diff options
-rw-r--r-- | drivers/acpi/battery.c | 2 | ||||
-rw-r--r-- | drivers/acpi/button.c | 5 | ||||
-rw-r--r-- | drivers/acpi/device_pm.c | 3 | ||||
-rw-r--r-- | drivers/acpi/sleep.c | 28 | ||||
-rw-r--r-- | drivers/base/power/main.c | 5 | ||||
-rw-r--r-- | drivers/base/power/wakeup.c | 18 | ||||
-rw-r--r-- | include/linux/suspend.h | 7 | ||||
-rw-r--r-- | kernel/power/process.c | 2 | ||||
-rw-r--r-- | kernel/power/suspend.c | 29 |
9 files changed, 22 insertions, 77 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 83ab17e4a795..4ef1e4624b2b 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -776,7 +776,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) | |||
776 | if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || | 776 | if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || |
777 | (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && | 777 | (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && |
778 | (battery->capacity_now <= battery->alarm))) | 778 | (battery->capacity_now <= battery->alarm))) |
779 | pm_wakeup_hard_event(&battery->device->dev); | 779 | pm_wakeup_event(&battery->device->dev, 0); |
780 | 780 | ||
781 | return result; | 781 | return result; |
782 | } | 782 | } |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index b7c2a06963d6..668137e4a069 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -216,7 +216,7 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | if (state) | 218 | if (state) |
219 | pm_wakeup_hard_event(&device->dev); | 219 | pm_wakeup_event(&device->dev, 0); |
220 | 220 | ||
221 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); | 221 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); |
222 | if (ret == NOTIFY_DONE) | 222 | if (ret == NOTIFY_DONE) |
@@ -398,7 +398,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
398 | } else { | 398 | } else { |
399 | int keycode; | 399 | int keycode; |
400 | 400 | ||
401 | pm_wakeup_hard_event(&device->dev); | 401 | pm_wakeup_event(&device->dev, 0); |
402 | if (button->suspended) | 402 | if (button->suspended) |
403 | break; | 403 | break; |
404 | 404 | ||
@@ -530,7 +530,6 @@ static int acpi_button_add(struct acpi_device *device) | |||
530 | lid_device = device; | 530 | lid_device = device; |
531 | } | 531 | } |
532 | 532 | ||
533 | device_init_wakeup(&device->dev, true); | ||
534 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); | 533 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); |
535 | return 0; | 534 | return 0; |
536 | 535 | ||
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 798d5003a039..993fd31394c8 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/pm_qos.h> | 24 | #include <linux/pm_qos.h> |
25 | #include <linux/pm_domain.h> | 25 | #include <linux/pm_domain.h> |
26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
27 | #include <linux/suspend.h> | ||
28 | 27 | ||
29 | #include "internal.h" | 28 | #include "internal.h" |
30 | 29 | ||
@@ -400,7 +399,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) | |||
400 | mutex_lock(&acpi_pm_notifier_lock); | 399 | mutex_lock(&acpi_pm_notifier_lock); |
401 | 400 | ||
402 | if (adev->wakeup.flags.notifier_present) { | 401 | if (adev->wakeup.flags.notifier_present) { |
403 | pm_wakeup_ws_event(adev->wakeup.ws, 0, true); | 402 | __pm_wakeup_event(adev->wakeup.ws, 0); |
404 | if (adev->wakeup.context.work.func) | 403 | if (adev->wakeup.context.work.func) |
405 | queue_pm_work(&adev->wakeup.context.work); | 404 | queue_pm_work(&adev->wakeup.context.work); |
406 | } | 405 | } |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index e84005d642e6..a4327af676fe 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -662,40 +662,14 @@ static int acpi_freeze_prepare(void) | |||
662 | acpi_os_wait_events_complete(); | 662 | acpi_os_wait_events_complete(); |
663 | if (acpi_sci_irq_valid()) | 663 | if (acpi_sci_irq_valid()) |
664 | enable_irq_wake(acpi_sci_irq); | 664 | enable_irq_wake(acpi_sci_irq); |
665 | |||
666 | return 0; | 665 | return 0; |
667 | } | 666 | } |
668 | 667 | ||
669 | static void acpi_freeze_wake(void) | ||
670 | { | ||
671 | /* | ||
672 | * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means | ||
673 | * that the SCI has triggered while suspended, so cancel the wakeup in | ||
674 | * case it has not been a wakeup event (the GPEs will be checked later). | ||
675 | */ | ||
676 | if (acpi_sci_irq_valid() && | ||
677 | !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) | ||
678 | pm_system_cancel_wakeup(); | ||
679 | } | ||
680 | |||
681 | static void acpi_freeze_sync(void) | ||
682 | { | ||
683 | /* | ||
684 | * Process all pending events in case there are any wakeup ones. | ||
685 | * | ||
686 | * The EC driver uses the system workqueue, so that one needs to be | ||
687 | * flushed too. | ||
688 | */ | ||
689 | acpi_os_wait_events_complete(); | ||
690 | flush_scheduled_work(); | ||
691 | } | ||
692 | |||
693 | static void acpi_freeze_restore(void) | 668 | static void acpi_freeze_restore(void) |
694 | { | 669 | { |
695 | acpi_disable_wakeup_devices(ACPI_STATE_S0); | 670 | acpi_disable_wakeup_devices(ACPI_STATE_S0); |
696 | if (acpi_sci_irq_valid()) | 671 | if (acpi_sci_irq_valid()) |
697 | disable_irq_wake(acpi_sci_irq); | 672 | disable_irq_wake(acpi_sci_irq); |
698 | |||
699 | acpi_enable_all_runtime_gpes(); | 673 | acpi_enable_all_runtime_gpes(); |
700 | } | 674 | } |
701 | 675 | ||
@@ -707,8 +681,6 @@ static void acpi_freeze_end(void) | |||
707 | static const struct platform_freeze_ops acpi_freeze_ops = { | 681 | static const struct platform_freeze_ops acpi_freeze_ops = { |
708 | .begin = acpi_freeze_begin, | 682 | .begin = acpi_freeze_begin, |
709 | .prepare = acpi_freeze_prepare, | 683 | .prepare = acpi_freeze_prepare, |
710 | .wake = acpi_freeze_wake, | ||
711 | .sync = acpi_freeze_sync, | ||
712 | .restore = acpi_freeze_restore, | 684 | .restore = acpi_freeze_restore, |
713 | .end = acpi_freeze_end, | 685 | .end = acpi_freeze_end, |
714 | }; | 686 | }; |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e987a6f55d36..9faee1c893e5 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -1091,6 +1091,11 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a | |||
1091 | if (async_error) | 1091 | if (async_error) |
1092 | goto Complete; | 1092 | goto Complete; |
1093 | 1093 | ||
1094 | if (pm_wakeup_pending()) { | ||
1095 | async_error = -EBUSY; | ||
1096 | goto Complete; | ||
1097 | } | ||
1098 | |||
1094 | if (dev->power.syscore || dev->power.direct_complete) | 1099 | if (dev->power.syscore || dev->power.direct_complete) |
1095 | goto Complete; | 1100 | goto Complete; |
1096 | 1101 | ||
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 9c36b27996fc..c313b600d356 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -28,8 +28,8 @@ bool events_check_enabled __read_mostly; | |||
28 | /* First wakeup IRQ seen by the kernel in the last cycle. */ | 28 | /* First wakeup IRQ seen by the kernel in the last cycle. */ |
29 | unsigned int pm_wakeup_irq __read_mostly; | 29 | unsigned int pm_wakeup_irq __read_mostly; |
30 | 30 | ||
31 | /* If greater than 0 and the system is suspending, terminate the suspend. */ | 31 | /* If set and the system is suspending, terminate the suspend. */ |
32 | static atomic_t pm_abort_suspend __read_mostly; | 32 | static bool pm_abort_suspend __read_mostly; |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Combined counters of registered wakeup events and wakeup events in progress. | 35 | * Combined counters of registered wakeup events and wakeup events in progress. |
@@ -855,26 +855,20 @@ bool pm_wakeup_pending(void) | |||
855 | pm_print_active_wakeup_sources(); | 855 | pm_print_active_wakeup_sources(); |
856 | } | 856 | } |
857 | 857 | ||
858 | return ret || atomic_read(&pm_abort_suspend) > 0; | 858 | return ret || pm_abort_suspend; |
859 | } | 859 | } |
860 | 860 | ||
861 | void pm_system_wakeup(void) | 861 | void pm_system_wakeup(void) |
862 | { | 862 | { |
863 | atomic_inc(&pm_abort_suspend); | 863 | pm_abort_suspend = true; |
864 | freeze_wake(); | 864 | freeze_wake(); |
865 | } | 865 | } |
866 | EXPORT_SYMBOL_GPL(pm_system_wakeup); | 866 | EXPORT_SYMBOL_GPL(pm_system_wakeup); |
867 | 867 | ||
868 | void pm_system_cancel_wakeup(void) | 868 | void pm_wakeup_clear(void) |
869 | { | ||
870 | atomic_dec(&pm_abort_suspend); | ||
871 | } | ||
872 | |||
873 | void pm_wakeup_clear(bool reset) | ||
874 | { | 869 | { |
870 | pm_abort_suspend = false; | ||
875 | pm_wakeup_irq = 0; | 871 | pm_wakeup_irq = 0; |
876 | if (reset) | ||
877 | atomic_set(&pm_abort_suspend, 0); | ||
878 | } | 872 | } |
879 | 873 | ||
880 | void pm_system_irq_wakeup(unsigned int irq_number) | 874 | void pm_system_irq_wakeup(unsigned int irq_number) |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 0b1cf32edfd7..d9718378a8be 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
@@ -189,8 +189,6 @@ struct platform_suspend_ops { | |||
189 | struct platform_freeze_ops { | 189 | struct platform_freeze_ops { |
190 | int (*begin)(void); | 190 | int (*begin)(void); |
191 | int (*prepare)(void); | 191 | int (*prepare)(void); |
192 | void (*wake)(void); | ||
193 | void (*sync)(void); | ||
194 | void (*restore)(void); | 192 | void (*restore)(void); |
195 | void (*end)(void); | 193 | void (*end)(void); |
196 | }; | 194 | }; |
@@ -430,8 +428,7 @@ extern unsigned int pm_wakeup_irq; | |||
430 | 428 | ||
431 | extern bool pm_wakeup_pending(void); | 429 | extern bool pm_wakeup_pending(void); |
432 | extern void pm_system_wakeup(void); | 430 | extern void pm_system_wakeup(void); |
433 | extern void pm_system_cancel_wakeup(void); | 431 | extern void pm_wakeup_clear(void); |
434 | extern void pm_wakeup_clear(bool reset); | ||
435 | extern void pm_system_irq_wakeup(unsigned int irq_number); | 432 | extern void pm_system_irq_wakeup(unsigned int irq_number); |
436 | extern bool pm_get_wakeup_count(unsigned int *count, bool block); | 433 | extern bool pm_get_wakeup_count(unsigned int *count, bool block); |
437 | extern bool pm_save_wakeup_count(unsigned int count); | 434 | extern bool pm_save_wakeup_count(unsigned int count); |
@@ -481,7 +478,7 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) | |||
481 | 478 | ||
482 | static inline bool pm_wakeup_pending(void) { return false; } | 479 | static inline bool pm_wakeup_pending(void) { return false; } |
483 | static inline void pm_system_wakeup(void) {} | 480 | static inline void pm_system_wakeup(void) {} |
484 | static inline void pm_wakeup_clear(bool reset) {} | 481 | static inline void pm_wakeup_clear(void) {} |
485 | static inline void pm_system_irq_wakeup(unsigned int irq_number) {} | 482 | static inline void pm_system_irq_wakeup(unsigned int irq_number) {} |
486 | 483 | ||
487 | static inline void lock_system_sleep(void) {} | 484 | static inline void lock_system_sleep(void) {} |
diff --git a/kernel/power/process.c b/kernel/power/process.c index 78672d324a6e..c7209f060eeb 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -132,7 +132,7 @@ int freeze_processes(void) | |||
132 | if (!pm_freezing) | 132 | if (!pm_freezing) |
133 | atomic_inc(&system_freezing_cnt); | 133 | atomic_inc(&system_freezing_cnt); |
134 | 134 | ||
135 | pm_wakeup_clear(true); | 135 | pm_wakeup_clear(); |
136 | pr_info("Freezing user space processes ... "); | 136 | pr_info("Freezing user space processes ... "); |
137 | pm_freezing = true; | 137 | pm_freezing = true; |
138 | error = try_to_freeze_tasks(true); | 138 | error = try_to_freeze_tasks(true); |
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index c0248c74d6d4..15e6baef5c73 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c | |||
@@ -72,8 +72,6 @@ static void freeze_begin(void) | |||
72 | 72 | ||
73 | static void freeze_enter(void) | 73 | static void freeze_enter(void) |
74 | { | 74 | { |
75 | trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, true); | ||
76 | |||
77 | spin_lock_irq(&suspend_freeze_lock); | 75 | spin_lock_irq(&suspend_freeze_lock); |
78 | if (pm_wakeup_pending()) | 76 | if (pm_wakeup_pending()) |
79 | goto out; | 77 | goto out; |
@@ -100,27 +98,6 @@ static void freeze_enter(void) | |||
100 | out: | 98 | out: |
101 | suspend_freeze_state = FREEZE_STATE_NONE; | 99 | suspend_freeze_state = FREEZE_STATE_NONE; |
102 | spin_unlock_irq(&suspend_freeze_lock); | 100 | spin_unlock_irq(&suspend_freeze_lock); |
103 | |||
104 | trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, false); | ||
105 | } | ||
106 | |||
107 | static void s2idle_loop(void) | ||
108 | { | ||
109 | do { | ||
110 | freeze_enter(); | ||
111 | |||
112 | if (freeze_ops && freeze_ops->wake) | ||
113 | freeze_ops->wake(); | ||
114 | |||
115 | dpm_resume_noirq(PMSG_RESUME); | ||
116 | if (freeze_ops && freeze_ops->sync) | ||
117 | freeze_ops->sync(); | ||
118 | |||
119 | if (pm_wakeup_pending()) | ||
120 | break; | ||
121 | |||
122 | pm_wakeup_clear(false); | ||
123 | } while (!dpm_suspend_noirq(PMSG_SUSPEND)); | ||
124 | } | 101 | } |
125 | 102 | ||
126 | void freeze_wake(void) | 103 | void freeze_wake(void) |
@@ -394,8 +371,10 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) | |||
394 | * all the devices are suspended. | 371 | * all the devices are suspended. |
395 | */ | 372 | */ |
396 | if (state == PM_SUSPEND_FREEZE) { | 373 | if (state == PM_SUSPEND_FREEZE) { |
397 | s2idle_loop(); | 374 | trace_suspend_resume(TPS("machine_suspend"), state, true); |
398 | goto Platform_early_resume; | 375 | freeze_enter(); |
376 | trace_suspend_resume(TPS("machine_suspend"), state, false); | ||
377 | goto Platform_wake; | ||
399 | } | 378 | } |
400 | 379 | ||
401 | error = disable_nonboot_cpus(); | 380 | error = disable_nonboot_cpus(); |