0001
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
0017 bus0 = pci_find_bus(0, 0);
0018 if (!bus0)
0019 return;
0020
0021 devfn = PCI_DEVFN((rr->address >> 32) & 0xffff,
0022 (rr->address >> 16) & 0xffff);
0023 pr_debug("Resetting with ACPI PCI RESET_REG.\n");
0024
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
0047
0048 if (acpi_gbl_FADT.header.revision < 2)
0049 return;
0050
0051
0052
0053
0054 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
0055 return;
0056
0057 reset_value = acpi_gbl_FADT.reset_value;
0058
0059
0060
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
0075
0076
0077
0078
0079
0080
0081 mdelay(15);
0082 }