diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 3f1f656348fc..a9f4034aa70a 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -130,9 +130,6 @@ 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 diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index db75167bc52d..b6abadccb1c6 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -68,7 +68,7 @@ save_secure_ram_debug: mov r0, #25 @ set service ID for PPA mov r12, r0 @ copy secure service ID in r12 mov r1, #0 @ set task id for ROM code in r1 - mov r2, #7 @ set some flags in r2, r6 + mov r2, #4 @ set some flags in r2, r6 mov r6, #0xff mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 3105aaa95d75..1b5216f1e78d 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -2358,26 +2358,20 @@ void omap_dma_global_context_save(void) void omap_dma_global_context_restore(void) { - dma_write(0x2, OCP_SYSCONFIG); - while (!__raw_readl(omap_dma_base + OMAP_DMA4_SYSSTATUS)) - ; dma_write(omap_dma_global_context.dma_gcr, GCR); dma_write(omap_dma_global_context.dma_ocp_sysconfig, OCP_SYSCONFIG); dma_write(omap_dma_global_context.dma_irqenable_l0, IRQENABLE_L0); -} -void omap_dma_disable_irq(int lch) -{ - u32 val; - - if (cpu_class_is_omap2()) { - /* Disable interrupts */ - val = dma_read(IRQENABLE_L0); - val &= ~(1 << lch); - dma_write(val, IRQENABLE_L0); - } + /* + * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared + * after secure sram context save and restore. Hence we need to + * manually clear those IRQs to avoid spurious interrupts. This + * affects only secure devices. + */ + if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) + dma_write(0x3 , IRQSTATUS_L0); } /*----------------------------------------------------------------------------*/ @@ -2515,8 +2509,8 @@ static int __init omap_init_dma(void) setup_irq(irq, &omap24xx_dma_irq); } - /* Enable smartidle idlemodes and autoidle */ if (cpu_is_omap34xx()) { + /* Enable smartidle idlemodes and autoidle */ u32 v = dma_read(OCP_SYSCONFIG); v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK | DMA_SYSCONFIG_SIDLEMODE_MASK | @@ -2525,6 +2519,13 @@ static int __init omap_init_dma(void) DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) | DMA_SYSCONFIG_AUTOIDLE); dma_write(v , OCP_SYSCONFIG); + /* reserve dma channels 0 and 1 in high security devices */ + if (omap_type() != OMAP2_DEVICE_TYPE_GP) { + printk(KERN_INFO "Reserving DMA channels 0 and 1 for " + "HS ROM code\n"); + dma_chan[0].dev_id = 0; + dma_chan[1].dev_id = 1; + } }