diff options
author | Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 2005-12-01 04:29:00 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-12-15 13:28:14 -0500 |
commit | 729b4d4ce1982c52040bbf22d6711cdf8db07ad8 (patch) | |
tree | 1ae8b12dcbcd17c364f2df28db8ab3db9c8b89a2 | |
parent | 7116317dc9148d783846299fc80a7d377baa6dca (diff) |
[ACPI] fix reboot upon suspend-to-disk
http://bugzilla.kernel.org/show_bug.cgi?id=4320
Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/sleep/poweroff.c | 15 | ||||
-rw-r--r-- | drivers/acpi/sleep/sleep.h | 2 | ||||
-rw-r--r-- | drivers/acpi/sleep/wakeup.c | 6 | ||||
-rw-r--r-- | include/linux/kernel.h | 1 | ||||
-rw-r--r-- | include/linux/reboot.h | 3 | ||||
-rw-r--r-- | kernel/power/disk.c | 9 | ||||
-rw-r--r-- | kernel/sys.c | 25 |
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 | ||
54 | static int acpi_shutdown(struct sys_device *x) | 52 | static 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 | ||
63 | static struct sysdev_class acpi_sysclass = { | 66 | static 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); | |||
5 | extern void acpi_enable_wakeup_device_prep(u8 sleep_state); | 5 | extern void acpi_enable_wakeup_device_prep(u8 sleep_state); |
6 | extern void acpi_enable_wakeup_device(u8 sleep_state); | 6 | extern void acpi_enable_wakeup_device(u8 sleep_state); |
7 | extern void acpi_disable_wakeup_device(u8 sleep_state); | 7 | extern void acpi_disable_wakeup_device(u8 sleep_state); |
8 | extern void acpi_wakeup_gpe_poweroff_prepare(void); | 8 | extern 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 | */ |
195 | void acpi_wakeup_gpe_poweroff_prepare(void) | 195 | void 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 | ||
62 | extern void kernel_restart_prepare(char *cmd); | 62 | extern void kernel_restart_prepare(char *cmd); |
63 | extern void kernel_halt_prepare(void); | 63 | extern void kernel_shutdown_prepare(enum system_states state); |
64 | extern void kernel_power_off_prepare(void); | ||
65 | 64 | ||
66 | extern void kernel_restart(char *cmd); | 65 | extern void kernel_restart(char *cmd); |
67 | extern void kernel_halt(void); | 66 | extern 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 | } |
428 | EXPORT_SYMBOL_GPL(kernel_kexec); | 428 | EXPORT_SYMBOL_GPL(kernel_kexec); |
429 | 429 | ||
430 | void 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 | */ |
435 | void kernel_halt_prepare(void) | ||
436 | { | ||
437 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); | ||
438 | system_state = SYSTEM_HALT; | ||
439 | device_shutdown(); | ||
440 | } | ||
441 | void kernel_halt(void) | 442 | void 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 | |||
447 | EXPORT_SYMBOL_GPL(kernel_halt); | 449 | EXPORT_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 | */ |
454 | void 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 | } | ||
460 | void kernel_power_off(void) | 456 | void 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 | } |
466 | EXPORT_SYMBOL_GPL(kernel_power_off); | 462 | EXPORT_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 |