From e13d8f383985b7ab8c859c1fa327e9b3d201894e Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Sat, 9 Jul 2011 14:37:21 -0700 Subject: OMAP3+: SR: ensure pm-runtime callbacks can be invoked with IRQs disabled SmartReflex should be disabled while entering low power mode due to a) SmartReflex values are not defined for retention voltage, further b) with SmartReflex enabled, if CPU enters lower c-states, FSM will try to bump the voltage to current OPP's voltage for which it has entered c-state; hence SmartReflex needs to be disabled for MPU, CORE and IVA voltage domains in idle path before enabling auto retention voltage achievement on the device. However, since the current pm_runtime setup for SmartReflex devices are setup to allow callbacks to be invoked with interrupts enabled, calling SmartReflex enable/disable from other contexts such as idle paths where preemption is disabled causes warnings such as the following indicating of a potential race. [ 82.023895] [] (__irq_svc+0x3c/0x120) from [] (_raw_spin_unlock_irq+0x28/0x2c) [ 82.023895] [] (_raw_spin_unlock_irq+0x28/0x2c) from [] (rpm_callback+0x4c/0x68) [ 82.023956] [] (rpm_callback+0x4c/0x68) from [] (rpm_resume+0x338/0x53c) [ 82.023956] [] (rpm_resume+0x338/0x53c) from [] (__pm_runtime_resume+0x48/0x60) [ 82.023986] [] (__pm_runtime_resume+0x48/0x60) from [] (sr_enable+0xa8/0x19c) [ 82.023986] [] (sr_enable+0xa8/0x19c) from [] (omap_sr_enable+0x50/0x90) [ 82.024017] [] (omap_sr_enable+0x50/0x90) from [] (omap4_enter_sleep+0x138/0x168) Instead, we use pm_runtime_irq_safe to tell the PM core that callbacks can be invoked in interrupt disabled contexts. Acked-by: Rajendra Nayak Signed-off-by: Nishanth Menon [khilman@ti.com: minor changelog edits] Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-omap2/smartreflex.c') diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 2ce2fb7664bc..dc8e86a54ac5 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -860,6 +860,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); pm_runtime_enable(&pdev->dev); + pm_runtime_irq_safe(&pdev->dev); sr_info->pdev = pdev; sr_info->srid = pdev->id; -- cgit v1.2.3 From 98333b3dda1e490b02304a6a6643c294d4e520c3 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 22 Jul 2011 00:55:52 -0500 Subject: OMAP2+: PM: SmartReflex: use put_sync_suspend for IRQ-safe disabling 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 Signed-off-by: Colin Cross [khilman@ti.com: minor Subject edits] Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2/smartreflex.c') diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index dc8e86a54ac5..34c01a7de810 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -621,7 +621,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); } /** -- cgit v1.2.3