[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>

authored by Alexey Starikovskiy and committed by Len Brown 729b4d4c 7116317d

+26 -35
+9 -6
drivers/acpi/sleep/poweroff.c
··· 33 ACPI_FLUSH_CPU_CACHE(); 34 acpi_enable_wakeup_device_prep(acpi_state); 35 #endif 36 - if (acpi_state == ACPI_STATE_S5) { 37 - acpi_wakeup_gpe_poweroff_prepare(); 38 - } 39 acpi_enter_sleep_state_prep(acpi_state); 40 return 0; 41 } ··· 51 52 static int acpi_shutdown(struct sys_device *x) 53 { 54 - if (system_state == SYSTEM_POWER_OFF) { 55 - /* Prepare if we are going to power off the system */ 56 return acpi_sleep_prepare(ACPI_STATE_S5); 57 } 58 - return 0; 59 } 60 61 static struct sysdev_class acpi_sysclass = {
··· 33 ACPI_FLUSH_CPU_CACHE(); 34 acpi_enable_wakeup_device_prep(acpi_state); 35 #endif 36 + acpi_gpe_sleep_prepare(acpi_state); 37 acpi_enter_sleep_state_prep(acpi_state); 38 return 0; 39 } ··· 53 54 static int acpi_shutdown(struct sys_device *x) 55 { 56 + switch (system_state) { 57 + case SYSTEM_POWER_OFF: 58 + /* Prepare to power off the system */ 59 return acpi_sleep_prepare(ACPI_STATE_S5); 60 + case SYSTEM_SUSPEND_DISK: 61 + /* Prepare to suspend the system to disk */ 62 + return acpi_sleep_prepare(ACPI_STATE_S4); 63 + default: 64 + return 0; 65 } 66 } 67 68 static struct sysdev_class acpi_sysclass = {
+1 -1
drivers/acpi/sleep/sleep.h
··· 5 extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 6 extern void acpi_enable_wakeup_device(u8 sleep_state); 7 extern void acpi_disable_wakeup_device(u8 sleep_state); 8 - extern void acpi_wakeup_gpe_poweroff_prepare(void);
··· 5 extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 6 extern void acpi_enable_wakeup_device(u8 sleep_state); 7 extern void acpi_disable_wakeup_device(u8 sleep_state); 8 + extern void acpi_gpe_sleep_prepare(u32 sleep_state);
+3 -3
drivers/acpi/sleep/wakeup.c
··· 192 * RUNTIME GPEs, we simply mark all GPES that 193 * are not enabled for wakeup from S5 as RUNTIME. 194 */ 195 - void acpi_wakeup_gpe_poweroff_prepare(void) 196 { 197 struct list_head *node, *next; 198 ··· 201 struct acpi_device, 202 wakeup_list); 203 204 - /* The GPE can wakeup system from S5, don't touch it */ 205 - if ((u32) dev->wakeup.sleep_state == ACPI_STATE_S5) 206 continue; 207 /* acpi_set_gpe_type will automatically disable GPE */ 208 acpi_set_gpe_type(dev->wakeup.gpe_device,
··· 192 * RUNTIME GPEs, we simply mark all GPES that 193 * are not enabled for wakeup from S5 as RUNTIME. 194 */ 195 + void acpi_gpe_sleep_prepare(u32 sleep_state) 196 { 197 struct list_head *node, *next; 198 ··· 201 struct acpi_device, 202 wakeup_list); 203 204 + /* The GPE can wakeup system from this state, don't touch it */ 205 + if ((u32) dev->wakeup.sleep_state >= sleep_state) 206 continue; 207 /* acpi_set_gpe_type will automatically disable GPE */ 208 acpi_set_gpe_type(dev->wakeup.gpe_device,
+1
include/linux/kernel.h
··· 181 SYSTEM_HALT, 182 SYSTEM_POWER_OFF, 183 SYSTEM_RESTART, 184 } system_state; 185 186 #define TAINT_PROPRIETARY_MODULE (1<<0)
··· 181 SYSTEM_HALT, 182 SYSTEM_POWER_OFF, 183 SYSTEM_RESTART, 184 + SYSTEM_SUSPEND_DISK, 185 } system_state; 186 187 #define TAINT_PROPRIETARY_MODULE (1<<0)
+1 -2
include/linux/reboot.h
··· 60 */ 61 62 extern void kernel_restart_prepare(char *cmd); 63 - extern void kernel_halt_prepare(void); 64 - extern void kernel_power_off_prepare(void); 65 66 extern void kernel_restart(char *cmd); 67 extern void kernel_halt(void);
··· 60 */ 61 62 extern void kernel_restart_prepare(char *cmd); 63 + extern void kernel_shutdown_prepare(enum system_states state); 64 65 extern void kernel_restart(char *cmd); 66 extern void kernel_halt(void);
+1 -8
kernel/power/disk.c
··· 52 53 switch(mode) { 54 case PM_DISK_PLATFORM: 55 - kernel_power_off_prepare(); 56 error = pm_ops->enter(PM_SUSPEND_DISK); 57 break; 58 case PM_DISK_SHUTDOWN: ··· 117 if (freeze_processes()) { 118 error = -EBUSY; 119 goto thaw; 120 - } 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. */
··· 52 53 switch(mode) { 54 case PM_DISK_PLATFORM: 55 + kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); 56 error = pm_ops->enter(PM_SUSPEND_DISK); 57 break; 58 case PM_DISK_SHUTDOWN: ··· 117 if (freeze_processes()) { 118 error = -EBUSY; 119 goto thaw; 120 } 121 122 /* Free memory before shutting down devices. */
+10 -15
kernel/sys.c
··· 427 } 428 EXPORT_SYMBOL_GPL(kernel_kexec); 429 430 /** 431 * kernel_halt - halt the system 432 * 433 * Shutdown everything and perform a clean system halt. 434 */ 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 { 443 - kernel_halt_prepare(); 444 printk(KERN_EMERG "System halted.\n"); 445 machine_halt(); 446 } 447 EXPORT_SYMBOL_GPL(kernel_halt); 448 449 /** ··· 453 * 454 * Shutdown everything and perform a clean system power_off. 455 */ 456 - void kernel_power_off_prepare(void) 457 - { 458 - notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); 459 - system_state = SYSTEM_POWER_OFF; 460 - device_shutdown(); 461 - } 462 void kernel_power_off(void) 463 { 464 - kernel_power_off_prepare(); 465 printk(KERN_EMERG "Power down.\n"); 466 machine_power_off(); 467 } 468 EXPORT_SYMBOL_GPL(kernel_power_off); 469 - 470 /* 471 * Reboot system call: for obvious reasons only root may call it, 472 * and even root needs to set up some magic numbers in the registers
··· 427 } 428 EXPORT_SYMBOL_GPL(kernel_kexec); 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 + } 437 /** 438 * kernel_halt - halt the system 439 * 440 * Shutdown everything and perform a clean system halt. 441 */ 442 void kernel_halt(void) 443 { 444 + kernel_shutdown_prepare(SYSTEM_HALT); 445 printk(KERN_EMERG "System halted.\n"); 446 machine_halt(); 447 } 448 + 449 EXPORT_SYMBOL_GPL(kernel_halt); 450 451 /** ··· 451 * 452 * Shutdown everything and perform a clean system power_off. 453 */ 454 void kernel_power_off(void) 455 { 456 + kernel_shutdown_prepare(SYSTEM_POWER_OFF); 457 printk(KERN_EMERG "Power down.\n"); 458 machine_power_off(); 459 } 460 EXPORT_SYMBOL_GPL(kernel_power_off); 461 /* 462 * Reboot system call: for obvious reasons only root may call it, 463 * and even root needs to set up some magic numbers in the registers