14d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin 24d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin#include <linux/pci.h> 34d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin#include <linux/acpi.h> 44d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin#include <acpi/reboot.h> 54d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin 64d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbinvoid acpi_reboot(void) 74d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin{ 84d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin struct acpi_generic_address *rr; 94d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin struct pci_bus *bus0; 104d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin u8 reset_value; 114d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin unsigned int devfn; 124d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin 134d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin if (acpi_disabled) 144d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin return; 154d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin 164d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin rr = &acpi_gbl_FADT.reset_register; 174d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin 1895cf3e12e7f659e536215b37c67d46f3e2ce95ccMatthew Garrett /* ACPI reset register was only introduced with v2 of the FADT */ 1995cf3e12e7f659e536215b37c67d46f3e2ce95ccMatthew Garrett 2095cf3e12e7f659e536215b37c67d46f3e2ce95ccMatthew Garrett if (acpi_gbl_FADT.header.revision < 2) 2195cf3e12e7f659e536215b37c67d46f3e2ce95ccMatthew Garrett return; 2295cf3e12e7f659e536215b37c67d46f3e2ce95ccMatthew Garrett 236734fe57a07b2dd23ef1ef2ac1f790747e53eefcMatthew Garrett /* Is the reset register supported? The spec says we should be 246734fe57a07b2dd23ef1ef2ac1f790747e53eefcMatthew Garrett * checking the bit width and bit offset, but Windows ignores 256734fe57a07b2dd23ef1ef2ac1f790747e53eefcMatthew Garrett * these fields */ 266734fe57a07b2dd23ef1ef2ac1f790747e53eefcMatthew Garrett if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) 274d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin return; 284d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin 294d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin reset_value = acpi_gbl_FADT.reset_value; 304d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin 314d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin /* The reset register can only exist in I/O, Memory or PCI config space 324d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin * on a device on bus 0. */ 334d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin switch (rr->space_id) { 344d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin case ACPI_ADR_SPACE_PCI_CONFIG: 354d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin /* The reset register can only live on bus 0. */ 364d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin bus0 = pci_find_bus(0, 0); 374d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin if (!bus0) 384d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin return; 394d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin /* Form PCI device/function pair. */ 404d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, 414d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin (rr->address >> 16) & 0xffff); 424d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG."); 434d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin /* Write the value that resets us. */ 444d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin pci_bus_write_config_byte(bus0, devfn, 454d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin (rr->address & 0xffff), reset_value); 464d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin break; 474d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin 484d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin case ACPI_ADR_SPACE_SYSTEM_MEMORY: 494d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin case ACPI_ADR_SPACE_SYSTEM_IO: 504d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n"); 512ee62612485f888b731804ca1b3b18ed8e842b51Lin Ming acpi_reset(); 524d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin break; 534d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin } 544d3870431d17346c4fdd80e087b7d76f1b5941d5Aaron Durbin} 55