diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-08-29 14:00:16 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-09-01 13:48:59 +0200 |
commit | 9ce7a25849e80cfb264f4995f832b932c1987e1a (patch) | |
tree | c7f7301049b93dda90c16b1e8b09e29cdb0bc189 /drivers/base | |
parent | b76f16748fa61801b1a1fd3ffb6f25ee228a35e0 (diff) | |
download | linux-9ce7a25849e80cfb264f4995f832b932c1987e1a.tar.gz linux-9ce7a25849e80cfb264f4995f832b932c1987e1a.tar.bz2 linux-9ce7a25849e80cfb264f4995f832b932c1987e1a.zip |
genirq: Simplify wakeup mechanism
Currently we suspend wakeup interrupts by lazy disabling them and
check later whether the interrupt has fired, but that's not sufficient
for suspend to idle as there is no way to check that once we
transitioned into the CPU idle state.
So we change the mechanism in the following way:
1) Leave the wakeup interrupts enabled across suspend
2) Add a check to irq_may_run() which is called at the beginning of
each flow handler whether the interrupt is an armed wakeup source.
This check is basically free as it just extends the existing check
for IRQD_IRQ_INPROGRESS. So no new conditional in the hot path.
If the IRQD_WAKEUP_ARMED flag is set, then the interrupt is
disabled, marked as pending/suspended and the pm core is notified
about the wakeup event.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: syscore.c and put irq_pm_check_wakeup() into pm.c ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/syscore.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c index dbb8350ea8dc..8d98a329f6ea 100644 --- a/drivers/base/syscore.c +++ b/drivers/base/syscore.c @@ -9,7 +9,7 @@ #include <linux/syscore_ops.h> #include <linux/mutex.h> #include <linux/module.h> -#include <linux/interrupt.h> +#include <linux/suspend.h> #include <trace/events/power.h> static LIST_HEAD(syscore_ops_list); @@ -54,9 +54,8 @@ int syscore_suspend(void) pr_debug("Checking wakeup interrupts\n"); /* Return error code if there are any wakeup interrupts pending. */ - ret = check_wakeup_irqs(); - if (ret) - return ret; + if (pm_wakeup_pending()) + return -EBUSY; WARN_ONCE(!irqs_disabled(), "Interrupts enabled before system core suspend.\n"); |