OMAP2+: disable idle early in the suspend sequence
authorJean Pihet <j-pihet@ti.com>
Thu, 9 Dec 2010 17:39:58 +0000 (18:39 +0100)
committerKevin Hilman <khilman@deeprootsystems.com>
Tue, 21 Dec 2010 22:29:34 +0000 (14:29 -0800)
Some bad interaction between the idle and the suspend paths has been
identified: the idle code is called during the suspend enter and exit
sequences. This could cause corruption or lock-up of resources.

The solution is to move the calls to disable_hlt at the very beginning
of the suspend sequence (ex. in omap3_pm_begin instead of
omap3_pm_prepare), and the call to enable_hlt at the very end of
the suspend sequence (ex. in omap3_pm_end instead of omap3_pm_finish).

Tested with RET and OFF on Beagle and OMAP3EVM.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/pm44xx.c

index aaeea49..aea7ced 100644 (file)
@@ -301,14 +301,8 @@ out:
 
 static int omap2_pm_begin(suspend_state_t state)
 {
-       suspend_state = state;
-       return 0;
-}
-
-static int omap2_pm_prepare(void)
-{
-       /* We cannot sleep in idle until we have resumed */
        disable_hlt();
+       suspend_state = state;
        return 0;
 }
 
@@ -349,21 +343,15 @@ static int omap2_pm_enter(suspend_state_t state)
        return ret;
 }
 
-static void omap2_pm_finish(void)
-{
-       enable_hlt();
-}
-
 static void omap2_pm_end(void)
 {
        suspend_state = PM_SUSPEND_ON;
+       enable_hlt();
 }
 
 static struct platform_suspend_ops omap_pm_ops = {
        .begin          = omap2_pm_begin,
-       .prepare        = omap2_pm_prepare,
        .enter          = omap2_pm_enter,
-       .finish         = omap2_pm_finish,
        .end            = omap2_pm_end,
        .valid          = suspend_valid_only_mem,
 };
index 648b8c5..5bf344a 100644 (file)
@@ -529,12 +529,6 @@ out:
 }
 
 #ifdef CONFIG_SUSPEND
-static int omap3_pm_prepare(void)
-{
-       disable_hlt();
-       return 0;
-}
-
 static int omap3_pm_suspend(void)
 {
        struct power_state *pwrst;
@@ -597,14 +591,10 @@ static int omap3_pm_enter(suspend_state_t unused)
        return ret;
 }
 
-static void omap3_pm_finish(void)
-{
-       enable_hlt();
-}
-
 /* Hooks to enable / disable UART interrupts during suspend */
 static int omap3_pm_begin(suspend_state_t state)
 {
+       disable_hlt();
        suspend_state = state;
        omap_uart_enable_irqs(0);
        return 0;
@@ -614,15 +604,14 @@ static void omap3_pm_end(void)
 {
        suspend_state = PM_SUSPEND_ON;
        omap_uart_enable_irqs(1);
+       enable_hlt();
        return;
 }
 
 static struct platform_suspend_ops omap_pm_ops = {
        .begin          = omap3_pm_begin,
        .end            = omap3_pm_end,
-       .prepare        = omap3_pm_prepare,
        .enter          = omap3_pm_enter,
-       .finish         = omap3_pm_finish,
        .valid          = suspend_valid_only_mem,
 };
 #endif /* CONFIG_SUSPEND */
index 54544b4..6aff996 100644 (file)
@@ -31,12 +31,6 @@ struct power_state {
 static LIST_HEAD(pwrst_list);
 
 #ifdef CONFIG_SUSPEND
-static int omap4_pm_prepare(void)
-{
-       disable_hlt();
-       return 0;
-}
-
 static int omap4_pm_suspend(void)
 {
        do_wfi();
@@ -59,28 +53,22 @@ static int omap4_pm_enter(suspend_state_t suspend_state)
        return ret;
 }
 
-static void omap4_pm_finish(void)
-{
-       enable_hlt();
-       return;
-}
-
 static int omap4_pm_begin(suspend_state_t state)
 {
+       disable_hlt();
        return 0;
 }
 
 static void omap4_pm_end(void)
 {
+       enable_hlt();
        return;
 }
 
 static struct platform_suspend_ops omap_pm_ops = {
        .begin          = omap4_pm_begin,
        .end            = omap4_pm_end,
-       .prepare        = omap4_pm_prepare,
        .enter          = omap4_pm_enter,
-       .finish         = omap4_pm_finish,
        .valid          = suspend_valid_only_mem,
 };
 #endif /* CONFIG_SUSPEND */