summaryrefslogtreecommitdiffstats
path: root/include/linux/suspend.h
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-04-26 17:23:03 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-05-05 16:54:28 -0400
commiteed4d47efe9508b855b09754cf6de4325d8a2f0d (patch)
treea5116bd74fa697a1601dff6db711022e82a55fde /include/linux/suspend.h
parent8a537ece3d946227e4afa81eae0e43fa47439c7d (diff)
ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle
The ACPI SCI (System Control Interrupt) is set up as a wakeup IRQ during suspend-to-idle transitions and, consequently, any events signaled through it wake up the system from that state. However, on some systems some of the events signaled via the ACPI SCI while suspended to idle should not cause the system to wake up. In fact, quite often they should just be discarded. Arguably, systems should not resume entirely on such events, but in order to decide which events really should cause the system to resume and which are spurious, it is necessary to resume up to the point when ACPI SCIs are actually handled and processed, which is after executing dpm_resume_noirq() in the system resume path. For this reasons, add a loop around freeze_enter() in which the platforms can process events signaled via multiplexed IRQ lines like the ACPI SCI and add suspend-to-idle hooks that can be used for this purpose to struct platform_freeze_ops. In the ACPI case, the ->wake hook is used for checking if the SCI has triggered while suspended and deferring the interrupt-induced system wakeup until the events signaled through it are actually processed sufficiently to decide whether or not the system should resume. In turn, the ->sync hook allows all of the relevant event queues to be flushed so as to prevent events from being missed due to race conditions. In addition to that, some ACPI code processing wakeup events needs to be modified to use the "hard" version of wakeup triggers, so that it will cause a system resume to happen on device-induced wakeup events even if the "soft" mechanism to prevent the system from suspending is not enabled (that also helps to catch device-induced wakeup events occurring during suspend transitions in progress). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'include/linux/suspend.h')
-rw-r--r--include/linux/suspend.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index d9718378a8be..0b1cf32edfd7 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -189,6 +189,8 @@ struct platform_suspend_ops {
189struct platform_freeze_ops { 189struct 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);
192 void (*restore)(void); 194 void (*restore)(void);
193 void (*end)(void); 195 void (*end)(void);
194}; 196};
@@ -428,7 +430,8 @@ extern unsigned int pm_wakeup_irq;
428 430
429extern bool pm_wakeup_pending(void); 431extern bool pm_wakeup_pending(void);
430extern void pm_system_wakeup(void); 432extern void pm_system_wakeup(void);
431extern void pm_wakeup_clear(void); 433extern void pm_system_cancel_wakeup(void);
434extern void pm_wakeup_clear(bool reset);
432extern void pm_system_irq_wakeup(unsigned int irq_number); 435extern void pm_system_irq_wakeup(unsigned int irq_number);
433extern bool pm_get_wakeup_count(unsigned int *count, bool block); 436extern bool pm_get_wakeup_count(unsigned int *count, bool block);
434extern bool pm_save_wakeup_count(unsigned int count); 437extern bool pm_save_wakeup_count(unsigned int count);
@@ -478,7 +481,7 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
478 481
479static inline bool pm_wakeup_pending(void) { return false; } 482static inline bool pm_wakeup_pending(void) { return false; }
480static inline void pm_system_wakeup(void) {} 483static inline void pm_system_wakeup(void) {}
481static inline void pm_wakeup_clear(void) {} 484static inline void pm_wakeup_clear(bool reset) {}
482static inline void pm_system_irq_wakeup(unsigned int irq_number) {} 485static inline void pm_system_irq_wakeup(unsigned int irq_number) {}
483 486
484static inline void lock_system_sleep(void) {} 487static inline void lock_system_sleep(void) {}