diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 8bb2628df34e..ac7e03ec952f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3493,7 +3493,12 @@ static struct omap_hwmod am35xx_emac_hwmod = { .name = "davinci_emac", .mpu_irqs = am35xx_emac_mpu_irqs, .class = &am35xx_emac_class, - .flags = HWMOD_NO_IDLEST, + /* + * According to Mark Greer, the MPU will not return from WFI + * when the EMAC signals an interrupt. + * http://www.spinics.net/lists/arm-kernel/msg174734.html + */ + .flags = (HWMOD_NO_IDLEST | HWMOD_BLOCK_WFI), }; /* l3_core -> davinci emac interface */ diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index b2a4df623545..b59d93908341 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -54,7 +54,6 @@ #include "powerdomain.h" #include "clockdomain.h" -static void (*omap2_sram_idle)(void); static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, void __iomem *sdrc_power); @@ -163,6 +162,8 @@ static int omap2_allow_mpu_retention(void) static void omap2_enter_mpu_retention(void) { + const int zero = 0; + /* The peripherals seem not to be able to wake up the MPU when * it is in retention mode. */ if (omap2_allow_mpu_retention()) { @@ -179,7 +180,8 @@ static void omap2_enter_mpu_retention(void) pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); } - omap2_sram_idle(); + /* WFI */ + asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc"); pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); } @@ -333,11 +335,9 @@ int __init omap2_pm_init(void) /* * We copy the assembler sleep/wakeup routines to SRAM. * These routines need to be in SRAM as that's the only - * memory the MPU can see when it wakes up. + * memory the MPU can see when it wakes up after the entire + * chip enters idle. */ - omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend, - omap24xx_idle_loop_suspend_sz); - omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, omap24xx_cpu_suspend_sz); diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S index ce0ccd26efbd..1d3cb25c9629 100644 --- a/arch/arm/mach-omap2/sleep24xx.S +++ b/arch/arm/mach-omap2/sleep24xx.S @@ -36,25 +36,6 @@ .text -/* - * Forces OMAP into idle state - * - * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI - * for normal idles. - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - * wakes up it continues execution at the point it went to sleep. - */ - .align 3 -ENTRY(omap24xx_idle_loop_suspend) - stmfd sp!, {r0, lr} @ save registers on stack - mov r0, #0 @ clear for mcr setup - mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt - ldmfd sp!, {r0, pc} @ restore regs and return - -ENTRY(omap24xx_idle_loop_suspend_sz) - .word . - omap24xx_idle_loop_suspend - /* * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore