Commit b681286917eecf9320ca71310aee093c11afd910
Committed by
Tero Kristo
1 parent
fd6b279841
Exists in
ti-linux-3.14.y
and in
2 other branches
ARM: OMAP2: pm33xx: Fix race condition between cpuidle and suspend
CPUIdle does not get disabled until noirq suspend, but am33xx_pm_enter is called early in the suspend sequence, which configures the wkup_m3 for deep sleep before waiting for the m3_irq2 interrupt. On AM43xx, this interrupt is triggerred by a WFI instruction with MPU clockdomain set to HW_AUTO and SCU set to low power state, which is the same condition present in cpuidle state. If system attempts to enter cpuidle c-state during suspend path (happens very rarely) the system will hang because it will gate the MPU clock and pass control to wkup_m3 which attempts to put system in DeepSleep when it is not actually prepared. By using cpu_idle_poll_ctrl we can prevent cpuidle from entering c-states during the suspend path and prevent this hang. Also useful on AM33xx to prevent suspend from failing without a hang due to cpuidle reconfiguring the wkup_m3 during suspend for mpu pll bypass only rather than deep sleep. Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Showing 1 changed file with 3 additions and 0 deletions Side-by-side Diff
arch/arm/mach-omap2/pm33xx.c
... | ... | @@ -333,6 +333,7 @@ |
333 | 333 | { |
334 | 334 | int i; |
335 | 335 | |
336 | + cpu_idle_poll_ctrl(true); | |
336 | 337 | |
337 | 338 | switch (state) { |
338 | 339 | case PM_SUSPEND_MEM: |
... | ... | @@ -372,6 +373,8 @@ |
372 | 373 | if (retrigger_irq) |
373 | 374 | writel_relaxed(1 << (retrigger_irq & 31), |
374 | 375 | gic_dist_base + 0x200 + retrigger_irq / 32 * 4); |
376 | + | |
377 | + cpu_idle_poll_ctrl(false); | |
375 | 378 | } |
376 | 379 | |
377 | 380 | static int am33xx_pm_valid(suspend_state_t state) |