-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the ability to reset the machine using the RESET_REG in ACPI's FA…
…DT table. Signed-off-by: Aaron Durbin <adurbin@google.com> Signed-off-by: Andi Kleen <ak@linux.intel.com> Cc: Len Brown <lenb@kernel.org> Cc: Andi Kleen <andi@firstfloor.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
- Loading branch information
Showing
3 changed files
with
59 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
|
||
#include <linux/pci.h> | ||
#include <linux/acpi.h> | ||
#include <acpi/reboot.h> | ||
|
||
void acpi_reboot(void) | ||
{ | ||
struct acpi_generic_address *rr; | ||
struct pci_bus *bus0; | ||
u8 reset_value; | ||
unsigned int devfn; | ||
|
||
if (acpi_disabled) | ||
return; | ||
|
||
rr = &acpi_gbl_FADT.reset_register; | ||
|
||
/* Is the reset register supported? */ | ||
if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || | ||
rr->bit_width != 8 || rr->bit_offset != 0) | ||
return; | ||
|
||
reset_value = acpi_gbl_FADT.reset_value; | ||
|
||
/* The reset register can only exist in I/O, Memory or PCI config space | ||
* on a device on bus 0. */ | ||
switch (rr->space_id) { | ||
case ACPI_ADR_SPACE_PCI_CONFIG: | ||
/* The reset register can only live on bus 0. */ | ||
bus0 = pci_find_bus(0, 0); | ||
if (!bus0) | ||
return; | ||
/* Form PCI device/function pair. */ | ||
devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, | ||
(rr->address >> 16) & 0xffff); | ||
printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG."); | ||
/* Write the value that resets us. */ | ||
pci_bus_write_config_byte(bus0, devfn, | ||
(rr->address & 0xffff), reset_value); | ||
break; | ||
|
||
case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
case ACPI_ADR_SPACE_SYSTEM_IO: | ||
printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n"); | ||
acpi_hw_low_level_write(8, reset_value, rr); | ||
break; | ||
} | ||
/* Wait ten seconds */ | ||
acpi_os_stall(10000000); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
#ifndef __ACPI_REBOOT_H | ||
#define __ACPI_REBOOT_H | ||
|
||
#ifdef CONFIG_ACPI | ||
extern void acpi_reboot(void); | ||
#else | ||
static inline void acpi_reboot(void) { } | ||
#endif | ||
|
||
/* | ||
* Dummy placeholder to make the EFI patches apply to the x86 tree. | ||
* Andrew/Len, please just kill this file if you encounter it. | ||
*/ | ||
#ifndef acpi_reboot | ||
# define acpi_reboot() do { } while (0) | ||
#endif | ||
|