ARM: OMAP3: Fix external abort on 36xx waking from off mode idle
[pandora-kernel.git] / arch / arm / mach-omap2 / pm34xx.c
index f11825f..717c594 100644 (file)
@@ -335,7 +335,7 @@ void omap_sram_idle(void)
        int per_next_state = PWRDM_POWER_ON;
        int core_next_state = PWRDM_POWER_ON;
        int per_going_off;
-       int core_prev_state, per_prev_state;
+       int per_prev_state;
        u32 sdrc_pwr = 0;
 
        mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
@@ -435,23 +435,25 @@ void omap_sram_idle(void)
                sdrc_write_reg(sdrc_pwr, SDRC_POWER);
 
        /* CORE */
+       if (core_next_state < PWRDM_POWER_ON &&
+           pwrdm_read_prev_pwrst(core_pwrdm) == PWRDM_POWER_OFF) {
+               omap3_core_restore_context();
+               omap3_cm_restore_context();
+               omap3_sram_restore_context();
+               omap2_sms_restore_context();
+       } else {
+               /*
+                * In off-mode resume path above, omap3_core_restore_context
+                * also handles the INTC autoidle restore done here so limit
+                * this to non-off mode resume paths so we don't do it twice.
+                */
+               omap3_intc_resume_idle();
+       }
        if (core_next_state < PWRDM_POWER_ON) {
-               core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
-               if (core_prev_state == PWRDM_POWER_OFF) {
-                       omap3_core_restore_context();
-                       omap3_cm_restore_context();
-                       omap3_sram_restore_context();
-                       omap2_sms_restore_context();
-               }
                omap_uart_resume_idle(0);
                omap_uart_resume_idle(1);
-               if (core_next_state == PWRDM_POWER_OFF)
-                       omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
-                                              OMAP3430_GR_MOD,
-                                              OMAP3_PRM_VOLTCTRL_OFFSET);
                pwrdm_post_transition(core_pwrdm);
        }
-       omap3_intc_resume_idle();
 
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
@@ -485,7 +487,6 @@ console_still_active:
 static void omap3_pm_idle(void)
 {
        local_irq_disable();
-       local_fiq_disable();
 
        if (omap_irq_pending() || need_resched())
                goto out;
@@ -499,7 +500,6 @@ static void omap3_pm_idle(void)
        trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
 
 out:
-       local_fiq_enable();
        local_irq_enable();
 }
 
@@ -738,6 +738,11 @@ static void __init prcm_setup_regs(void)
 
        omap3_iva_idle();
        omap3_d2d_idle();
+
+       /* enable sys_clkreq signalling */
+       omap2_prm_rmw_mod_reg_bits((OMAP3430_AUTO_OFF_MASK | OMAP3430_AUTO_RET_MASK
+               | OMAP3430_AUTO_SLEEP_MASK), OMAP3430_AUTO_RET_MASK,
+               OMAP3430_GR_MOD, OMAP3_PRM_VOLTCTRL_OFFSET);
 }
 
 void omap3_pm_off_mode_enable(int enable)
@@ -924,14 +929,12 @@ static int __init omap3_pm_init(void)
                                        "allocating for secure sram context\n");
 
                local_irq_disable();
-               local_fiq_disable();
 
                omap_dma_global_context_save();
                omap3_save_secure_ram_context();
                omap_dma_global_context_restore();
 
                local_irq_enable();
-               local_fiq_enable();
        }
 
        omap3_save_scratchpad_contents();