Message ID | 1311314153-23531-2-git-send-email-nm@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Nishanth Menon <nm@ti.com> writes: > From: Colin Cross <ccross@google.com> > > omap_sr_disable_reset_volt is called with irqs off in omapx_enter_sleep, > as part of idle sequence, this eventually calls sr_disable and > pm_runtime_put_sync. pm_runtime_put_sync calls rpm_idle, which will > enable interrupts in order to call the callback. In this short interval > when interrupts are enabled, scenarios such as the following can occur: > while interrupts are enabled, the timer interrupt that is supposed to > wake the device out of idle occurs and is acked, so when the CPU finally > goes to off, the timer is already gone, missing a wakeup event. > > Further, as the documentation for runtime states:" > However, subsystems can use the pm_runtime_irq_safe() helper function > to tell the PM core that a device's ->runtime_suspend() and ->runtime_resume() > callbacks should be invoked in atomic context with interrupts disabled > (->runtime_idle() is still invoked the default way)." > > Hence, replace pm_runtime_put_sync with pm_runtime_put_sync_suspend > to invoke the suspend handler and shut off the fclk for SmartReflex > module instead of using the idle handler in interrupt disabled context. > > Signed-off-by: Nishanth Menon <nm@ti.com> > Signed-off-by: Colin Cross <ccross@google.com> Great catch! Looking through Documentation/power/runtime_pm.txt, I see (now) that it is well documented that _put_sync_suspend() is safe to use from interrupts-disabled context, but _put_sync() is not on that list. Queuing this as a fix for v3.1. Kevin -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index fb7dc52..33a027f 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -622,7 +622,7 @@ void sr_disable(struct voltagedomain *voltdm) sr_v2_disable(sr); } - pm_runtime_put_sync(&sr->pdev->dev); + pm_runtime_put_sync_suspend(&sr->pdev->dev); } /**