summaryrefslogtreecommitdiffstats
path: root/drivers/base/power/main.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2015-05-18 15:40:29 -0700
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-05-20 01:56:31 +0200
commit4990d4fe327b9d9a7a3be7103a82699406fdde69 (patch)
tree00fbe86ede4fb244f56675d16dbb5581b016f2f0 /drivers/base/power/main.c
parent56f487c78015936097474fd89b2ccb229d500d0f (diff)
downloadop-kernel-dev-4990d4fe327b9d9a7a3be7103a82699406fdde69.zip
op-kernel-dev-4990d4fe327b9d9a7a3be7103a82699406fdde69.tar.gz
PM / Wakeirq: Add automated device wake IRQ handling
Turns out we can automate the handling for the device_may_wakeup() quite a bit by using the kernel wakeup source list as suggested by Rafael J. Wysocki <rjw@rjwysocki.net>. And as some hardware has separate dedicated wake-up interrupt in addition to the IO interrupt, we can automate the handling by adding a generic threaded interrupt handler that just calls the device PM runtime to wake up the device. This allows dropping code from device drivers as we currently are doing it in multiple ways, and often wrong. For most drivers, we should be able to drop the following boilerplate code from runtime_suspend and runtime_resume functions: ... device_init_wakeup(dev, true); ... if (device_may_wakeup(dev)) enable_irq_wake(irq); ... if (device_may_wakeup(dev)) disable_irq_wake(irq); ... device_init_wakeup(dev, false); ... We can replace it with just the following init and exit time code: ... device_init_wakeup(dev, true); dev_pm_set_wake_irq(dev, irq); ... dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); ... And for hardware with dedicated wake-up interrupts: ... device_init_wakeup(dev, true); dev_pm_set_dedicated_wake_irq(dev, irq); ... dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); ... Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r--drivers/base/power/main.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 3d874ec..6f2515c 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -24,6 +24,7 @@
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/pm-trace.h>
+#include <linux/pm_wakeirq.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/async.h>
@@ -587,6 +588,7 @@ void dpm_resume_noirq(pm_message_t state)
async_synchronize_full();
dpm_show_time(starttime, state, "noirq");
resume_device_irqs();
+ device_wakeup_disarm_wake_irqs();
cpuidle_resume();
trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, false);
}
@@ -1104,6 +1106,7 @@ int dpm_suspend_noirq(pm_message_t state)
trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, true);
cpuidle_pause();
+ device_wakeup_arm_wake_irqs();
suspend_device_irqs();
mutex_lock(&dpm_list_mtx);
pm_transition = state;
OpenPOWER on IntegriCloud