summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm34xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
-rw-r--r--arch/arm/mach-omap2/pm34xx.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 54fea79b1720..ebb88f3aae31 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -63,6 +63,8 @@ static LIST_HEAD(pwrst_list);
static void (*_omap_sram_idle)(u32 *addr, int save_state);
+static int (*_omap_save_secure_sram)(u32 *addr);
+
static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
static struct powerdomain *core_pwrdm, *per_pwrdm;
@@ -110,6 +112,33 @@ static void omap3_core_restore_context(void)
omap_dma_global_context_restore();
}
+static void omap3_save_secure_ram_context(u32 target_mpu_state)
+{
+ u32 ret;
+
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+ /* Disable dma irq before calling secure rom code API */
+ omap_dma_disable_irq(0);
+ omap_dma_disable_irq(1);
+ /*
+ * MPU next state must be set to POWER_ON temporarily,
+ * otherwise the WFI executed inside the ROM code
+ * will hang the system.
+ */
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+ ret = _omap_save_secure_sram((u32 *)
+ __pa(omap3_secure_ram_storage));
+ pwrdm_set_next_pwrst(mpu_pwrdm, target_mpu_state);
+ /* Following is for error tracking, it should not happen */
+ if (ret) {
+ printk(KERN_ERR "save_secure_sram() returns %08x\n",
+ ret);
+ while (1)
+ ;
+ }
+ }
+}
+
/*
* PRCM Interrupt Handler Helper Function
*
@@ -308,6 +337,7 @@ static void omap_sram_idle(void)
if (core_next_state == PWRDM_POWER_OFF) {
omap3_core_save_context();
omap3_prcm_save_context();
+ omap3_save_secure_ram_context(mpu_next_state);
}
/* Enable IO-PAD wakeup */
prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
@@ -901,6 +931,9 @@ void omap_push_sram_idle(void)
{
_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
omap34xx_cpu_suspend_sz);
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+ _omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
+ save_secure_ram_context_sz);
}
static int __init omap3_pm_init(void)
@@ -916,7 +949,6 @@ static int __init omap3_pm_init(void)
/* XXX prcm_setup_regs needs to be before enabling hw
* supervised mode for powerdomains */
prcm_setup_regs();
- omap3_save_scratchpad_contents();
ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
(irq_handler_t)prcm_interrupt_handler,
@@ -961,6 +993,15 @@ static int __init omap3_pm_init(void)
*/
pwrdm_add_wkdep(per_pwrdm, core_pwrdm);
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+ omap3_secure_ram_storage =
+ kmalloc(0x803F, GFP_KERNEL);
+ if (!omap3_secure_ram_storage)
+ printk(KERN_ERR "Memory allocation failed when"
+ "allocating for secure sram context\n");
+ }
+ omap3_save_scratchpad_contents();
+
err1:
return ret;
err2: