Skip to content
Snippets Groups Projects
Commit 4d387043 authored by Aaron Durbin's avatar Aaron Durbin Committed by Andi Kleen
Browse files

Add the ability to reset the machine using the RESET_REG in ACPI's FADT table.


Signed-off-by: default avatarAaron Durbin <adurbin@google.com>
Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent c83642d5
No related branches found
No related tags found
No related merge requests found
...@@ -21,7 +21,7 @@ obj-$(CONFIG_X86) += blacklist.o ...@@ -21,7 +21,7 @@ obj-$(CONFIG_X86) += blacklist.o
# #
# ACPI Core Subsystem (Interpreter) # ACPI Core Subsystem (Interpreter)
# #
obj-y += osl.o utils.o \ obj-y += osl.o utils.o reboot.o\
dispatcher/ events/ executer/ hardware/ \ dispatcher/ events/ executer/ hardware/ \
namespace/ parser/ resources/ tables/ \ namespace/ parser/ resources/ tables/ \
utilities/ utilities/
......
#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);
}
#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 #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment