aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/sleep/poweroff.c15
-rw-r--r--drivers/acpi/sleep/sleep.h2
-rw-r--r--drivers/acpi/sleep/wakeup.c6
-rw-r--r--include/linux/kernel.h1
-rw-r--r--include/linux/reboot.h3
-rw-r--r--kernel/power/disk.c9
-rw-r--r--kernel/sys.c25
7 files changed, 26 insertions, 35 deletions
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
index af7935a95bcc..47fb4b394eec 100644
--- a/drivers/acpi/sleep/poweroff.c
+++ b/drivers/acpi/sleep/poweroff.c
@@ -33,9 +33,7 @@ int acpi_sleep_prepare(u32 acpi_state)
33 ACPI_FLUSH_CPU_CACHE(); 33 ACPI_FLUSH_CPU_CACHE();
34 acpi_enable_wakeup_device_prep(acpi_state); 34 acpi_enable_wakeup_device_prep(acpi_state);
35#endif 35#endif
36 if (acpi_state == ACPI_STATE_S5) { 36 acpi_gpe_sleep_prepare(acpi_state);
37 acpi_wakeup_gpe_poweroff_prepare();
38 }
39 acpi_enter_sleep_state_prep(acpi_state); 37 acpi_enter_sleep_state_prep(acpi_state);
40 return 0; 38 return 0;
41} 39}
@@ -53,11 +51,16 @@ void acpi_power_off(void)
53 51
54static int acpi_shutdown(struct sys_device *x) 52static int acpi_shutdown(struct sys_device *x)
55{ 53{
56 if (system_state == SYSTEM_POWER_OFF) { 54 switch (system_state) {
57 /* Prepare if we are going to power off the system */ 55 case SYSTEM_POWER_OFF:
56 /* Prepare to power off the system */
58 return acpi_sleep_prepare(ACPI_STATE_S5); 57 return acpi_sleep_prepare(ACPI_STATE_S5);
58 case SYSTEM_SUSPEND_DISK:
59 /* Prepare to suspend the system to disk */
60 return acpi_sleep_prepare(ACPI_STATE_S4);
61 default:
62 return 0;
59 } 63 }
60 return 0;
61} 64}
62 65
63static struct sysdev_class acpi_sysclass = { 66static struct sysdev_class acpi_sysclass = {
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index efd0001c6f05..f3e70397a7d6 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,4 +5,4 @@ extern int acpi_suspend (u32 state);
5extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 5extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
6extern void acpi_enable_wakeup_device(u8 sleep_state); 6extern void acpi_enable_wakeup_device(u8 sleep_state);
7extern void acpi_disable_wakeup_device(u8 sleep_state); 7extern void acpi_disable_wakeup_device(u8 sleep_state);
8extern void acpi_wakeup_gpe_poweroff_prepare(void); 8extern void acpi_gpe_sleep_prepare(u32 sleep_state);
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index 4134ed43d026..85df0ceda2a9 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -192,7 +192,7 @@ late_initcall(acpi_wakeup_device_init);
192 * RUNTIME GPEs, we simply mark all GPES that 192 * RUNTIME GPEs, we simply mark all GPES that
193 * are not enabled for wakeup from S5 as RUNTIME. 193 * are not enabled for wakeup from S5 as RUNTIME.
194 */ 194 */
195void acpi_wakeup_gpe_poweroff_prepare(void) 195void acpi_gpe_sleep_prepare(u32 sleep_state)
196{ 196{
197 struct list_head *node, *next; 197 struct list_head *node, *next;
198 198
@@ -201,8 +201,8 @@ void acpi_wakeup_gpe_poweroff_prepare(void)
201 struct acpi_device, 201 struct acpi_device,
202 wakeup_list); 202 wakeup_list);
203 203
204 /* The GPE can wakeup system from S5, don't touch it */ 204 /* The GPE can wakeup system from this state, don't touch it */
205 if ((u32) dev->wakeup.sleep_state == ACPI_STATE_S5) 205 if ((u32) dev->wakeup.sleep_state >= sleep_state)
206 continue; 206 continue;
207 /* acpi_set_gpe_type will automatically disable GPE */ 207 /* acpi_set_gpe_type will automatically disable GPE */
208 acpi_set_gpe_type(dev->wakeup.gpe_device, 208 acpi_set_gpe_type(dev->wakeup.gpe_device,
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b1e407a4fbda..73aa55a73334 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -181,6 +181,7 @@ extern enum system_states {
181 SYSTEM_HALT, 181 SYSTEM_HALT,
182 SYSTEM_POWER_OFF, 182 SYSTEM_POWER_OFF,
183 SYSTEM_RESTART, 183 SYSTEM_RESTART,
184 SYSTEM_SUSPEND_DISK,
184} system_state; 185} system_state;
185 186
186#define TAINT_PROPRIETARY_MODULE (1<<0) 187#define TAINT_PROPRIETARY_MODULE (1<<0)
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 7ab2cdb83ef0..015297ff73fa 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -60,8 +60,7 @@ extern void machine_crash_shutdown(struct pt_regs *);
60 */ 60 */
61 61
62extern void kernel_restart_prepare(char *cmd); 62extern void kernel_restart_prepare(char *cmd);
63extern void kernel_halt_prepare(void); 63extern void kernel_shutdown_prepare(enum system_states state);
64extern void kernel_power_off_prepare(void);
65 64
66extern void kernel_restart(char *cmd); 65extern void kernel_restart(char *cmd);
67extern void kernel_halt(void); 66extern void kernel_halt(void);
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 027322a564f4..f2cd279d07c7 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -52,7 +52,7 @@ static void power_down(suspend_disk_method_t mode)
52 52
53 switch(mode) { 53 switch(mode) {
54 case PM_DISK_PLATFORM: 54 case PM_DISK_PLATFORM:
55 kernel_power_off_prepare(); 55 kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
56 error = pm_ops->enter(PM_SUSPEND_DISK); 56 error = pm_ops->enter(PM_SUSPEND_DISK);
57 break; 57 break;
58 case PM_DISK_SHUTDOWN: 58 case PM_DISK_SHUTDOWN:
@@ -119,13 +119,6 @@ static int prepare_processes(void)
119 goto thaw; 119 goto thaw;
120 } 120 }
121 121
122 if (pm_disk_mode == PM_DISK_PLATFORM) {
123 if (pm_ops && pm_ops->prepare) {
124 if ((error = pm_ops->prepare(PM_SUSPEND_DISK)))
125 goto thaw;
126 }
127 }
128
129 /* Free memory before shutting down devices. */ 122 /* Free memory before shutting down devices. */
130 free_some_memory(); 123 free_some_memory();
131 return 0; 124 return 0;
diff --git a/kernel/sys.c b/kernel/sys.c
index eecf84526afe..c3b1874661fa 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -427,23 +427,25 @@ void kernel_kexec(void)
427} 427}
428EXPORT_SYMBOL_GPL(kernel_kexec); 428EXPORT_SYMBOL_GPL(kernel_kexec);
429 429
430void kernel_shutdown_prepare(enum system_states state)
431{
432 notifier_call_chain(&reboot_notifier_list,
433 (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL);
434 system_state = state;
435 device_shutdown();
436}
430/** 437/**
431 * kernel_halt - halt the system 438 * kernel_halt - halt the system
432 * 439 *
433 * Shutdown everything and perform a clean system halt. 440 * Shutdown everything and perform a clean system halt.
434 */ 441 */
435void kernel_halt_prepare(void)
436{
437 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
438 system_state = SYSTEM_HALT;
439 device_shutdown();
440}
441void kernel_halt(void) 442void kernel_halt(void)
442{ 443{
443 kernel_halt_prepare(); 444 kernel_shutdown_prepare(SYSTEM_HALT);
444 printk(KERN_EMERG "System halted.\n"); 445 printk(KERN_EMERG "System halted.\n");
445 machine_halt(); 446 machine_halt();
446} 447}
448
447EXPORT_SYMBOL_GPL(kernel_halt); 449EXPORT_SYMBOL_GPL(kernel_halt);
448 450
449/** 451/**
@@ -451,20 +453,13 @@ EXPORT_SYMBOL_GPL(kernel_halt);
451 * 453 *
452 * Shutdown everything and perform a clean system power_off. 454 * Shutdown everything and perform a clean system power_off.
453 */ 455 */
454void kernel_power_off_prepare(void)
455{
456 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
457 system_state = SYSTEM_POWER_OFF;
458 device_shutdown();
459}
460void kernel_power_off(void) 456void kernel_power_off(void)
461{ 457{
462 kernel_power_off_prepare(); 458 kernel_shutdown_prepare(SYSTEM_POWER_OFF);
463 printk(KERN_EMERG "Power down.\n"); 459 printk(KERN_EMERG "Power down.\n");
464 machine_power_off(); 460 machine_power_off();
465} 461}
466EXPORT_SYMBOL_GPL(kernel_power_off); 462EXPORT_SYMBOL_GPL(kernel_power_off);
467
468/* 463/*
469 * Reboot system call: for obvious reasons only root may call it, 464 * Reboot system call: for obvious reasons only root may call it,
470 * and even root needs to set up some magic numbers in the registers 465 * and even root needs to set up some magic numbers in the registers