Эх сурвалжийг харах

x86: add ACPI reboot option

Add the ability to reboot an x86_64 based machine using the RESET_REG in the
FADT ACPI table.

Signed-off-by: Aaron Durbin <adurbin@google.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Aaron Durbin 17 жил өмнө
parent
commit
fa20efd2fc

+ 4 - 1
Documentation/x86_64/boot-options.txt

@@ -110,12 +110,15 @@ Idle loop
 
 
 Rebooting
 Rebooting
 
 
-   reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
+   reboot=b[ios] | t[riple] | k[bd] | a[cpi] [, [w]arm | [c]old]
    bios	  Use the CPU reboot vector for warm reset
    bios	  Use the CPU reboot vector for warm reset
    warm   Don't set the cold reboot flag
    warm   Don't set the cold reboot flag
    cold   Set the cold reboot flag
    cold   Set the cold reboot flag
    triple Force a triple fault (init)
    triple Force a triple fault (init)
    kbd    Use the keyboard controller. cold reset (default)
    kbd    Use the keyboard controller. cold reset (default)
+   acpi   Use the ACPI RESET_REG in the FADT. If ACPI is not configured or the
+          ACPI reset does not work, the reboot path attempts the reset using
+          the keyboard controller.
 
 
    Using warm reset will be much faster especially on big memory
    Using warm reset will be much faster especially on big memory
    systems because the BIOS will not go through the memory check.
    systems because the BIOS will not go through the memory check.

+ 10 - 1
arch/x86/kernel/reboot_64.c

@@ -9,6 +9,7 @@
 #include <linux/pm.h>
 #include <linux/pm.h>
 #include <linux/kdebug.h>
 #include <linux/kdebug.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
+#include <acpi/reboot.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/delay.h>
 #include <asm/desc.h>
 #include <asm/desc.h>
@@ -29,7 +30,8 @@ EXPORT_SYMBOL(pm_power_off);
 static long no_idt[3];
 static long no_idt[3];
 static enum { 
 static enum { 
 	BOOT_TRIPLE = 't',
 	BOOT_TRIPLE = 't',
-	BOOT_KBD = 'k'
+	BOOT_KBD = 'k',
+	BOOT_ACPI = 'a'
 } reboot_type = BOOT_KBD;
 } reboot_type = BOOT_KBD;
 static int reboot_mode = 0;
 static int reboot_mode = 0;
 int reboot_force;
 int reboot_force;
@@ -39,6 +41,7 @@ int reboot_force;
    cold   Set the cold reboot flag
    cold   Set the cold reboot flag
    triple Force a triple fault (init)
    triple Force a triple fault (init)
    kbd    Use the keyboard controller. cold reset (default)
    kbd    Use the keyboard controller. cold reset (default)
+   acpi   Use the RESET_REG in the FADT
    force  Avoid anything that could hang.
    force  Avoid anything that could hang.
  */ 
  */ 
 static int __init reboot_setup(char *str)
 static int __init reboot_setup(char *str)
@@ -54,6 +57,7 @@ static int __init reboot_setup(char *str)
 			break;
 			break;
 
 
 		case 't':
 		case 't':
+		case 'a':
 		case 'b':
 		case 'b':
 		case 'k':
 		case 'k':
 			reboot_type = *str;
 			reboot_type = *str;
@@ -146,6 +150,11 @@ void machine_emergency_restart(void)
 
 
 			reboot_type = BOOT_KBD;
 			reboot_type = BOOT_KBD;
 			break;
 			break;
+
+		case BOOT_ACPI:
+			acpi_reboot();
+			reboot_type = BOOT_KBD;
+			break;
 		}      
 		}      
 	}      
 	}      
 }
 }