Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #define pr_fmt(fmt) "ACPI: " fmt
0004 
0005 #include <linux/pci.h>
0006 #include <linux/acpi.h>
0007 #include <acpi/reboot.h>
0008 #include <linux/delay.h>
0009 
0010 #ifdef CONFIG_PCI
0011 static void acpi_pci_reboot(struct acpi_generic_address *rr, u8 reset_value)
0012 {
0013     unsigned int devfn;
0014     struct pci_bus *bus0;
0015 
0016     /* The reset register can only live on bus 0. */
0017     bus0 = pci_find_bus(0, 0);
0018     if (!bus0)
0019         return;
0020     /* Form PCI device/function pair. */
0021     devfn = PCI_DEVFN((rr->address >> 32) & 0xffff,
0022               (rr->address >> 16) & 0xffff);
0023     pr_debug("Resetting with ACPI PCI RESET_REG.\n");
0024     /* Write the value that resets us. */
0025     pci_bus_write_config_byte(bus0, devfn,
0026             (rr->address & 0xffff), reset_value);
0027 }
0028 #else
0029 static inline void acpi_pci_reboot(struct acpi_generic_address *rr,
0030                    u8 reset_value)
0031 {
0032     pr_warn_once("PCI configuration space access is not supported\n");
0033 }
0034 #endif
0035 
0036 void acpi_reboot(void)
0037 {
0038     struct acpi_generic_address *rr;
0039     u8 reset_value;
0040 
0041     if (acpi_disabled)
0042         return;
0043 
0044     rr = &acpi_gbl_FADT.reset_register;
0045 
0046     /* ACPI reset register was only introduced with v2 of the FADT */
0047 
0048     if (acpi_gbl_FADT.header.revision < 2)
0049         return;
0050 
0051     /* Is the reset register supported? The spec says we should be
0052      * checking the bit width and bit offset, but Windows ignores
0053      * these fields */
0054     if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
0055         return;
0056 
0057     reset_value = acpi_gbl_FADT.reset_value;
0058 
0059     /* The reset register can only exist in I/O, Memory or PCI config space
0060      * on a device on bus 0. */
0061     switch (rr->space_id) {
0062     case ACPI_ADR_SPACE_PCI_CONFIG:
0063         acpi_pci_reboot(rr, reset_value);
0064         break;
0065 
0066     case ACPI_ADR_SPACE_SYSTEM_MEMORY:
0067     case ACPI_ADR_SPACE_SYSTEM_IO:
0068         pr_debug("ACPI MEMORY or I/O RESET_REG.\n");
0069         acpi_reset();
0070         break;
0071     }
0072 
0073     /*
0074      * Some platforms do not shut down immediately after writing to the
0075      * ACPI reset register, and this results in racing with the
0076      * subsequent reboot mechanism.
0077      *
0078      * The 15ms delay has been found to be long enough for the system
0079      * to reboot on the affected platforms.
0080      */
0081     mdelay(15);
0082 }