aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTero Kristo <tero.kristo@nokia.com>2009-10-23 12:03:50 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2010-01-20 21:16:00 -0500
commitf18cc2ff5e18e8eb6df5284866331ef4a2db58d6 (patch)
tree5d20f9ba3a46c44ba11c3ed1deeed8e60e8115cc
parentb296c8118b26a359b027b8c9bb9f5f41dc7693fa (diff)
OMAP3: PM: Disable interrupt controller AUTOIDLE before WFI
OMAP interrupt controller goes to unknown state when there is right combination of l3,l4 sleep/wake-up transitions, l4 autoidle in interrupt controller and some interrupt. When this happens, interrupts are not delivered to ARM anymore and ARM will remain in WFI (wait for interrupt) until interrupt controller is forced to wake-up (i.e. lauterbach). Signed-off-by: Tero Kristo <tero.kristo@nokia.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r--arch/arm/mach-omap2/irq.c12
-rw-r--r--arch/arm/mach-omap2/pm34xx.c2
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h2
3 files changed, 16 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 54c5f0dcd663..27054025da2b 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -280,4 +280,16 @@ void omap3_intc_suspend(void)
280 /* A pending interrupt would prevent OMAP from entering suspend */ 280 /* A pending interrupt would prevent OMAP from entering suspend */
281 omap_ack_irq(0); 281 omap_ack_irq(0);
282} 282}
283
284void omap3_intc_prepare_idle(void)
285{
286 /* Disable autoidle as it can stall interrupt controller */
287 intc_bank_write_reg(0, &irq_banks[0], INTC_SYSCONFIG);
288}
289
290void omap3_intc_resume_idle(void)
291{
292 /* Re-enable autoidle */
293 intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG);
294}
283#endif /* CONFIG_ARCH_OMAP3 */ 295#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 8a148fbbab43..af83555795ff 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -392,6 +392,7 @@ void omap_sram_idle(void)
392 prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); 392 prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
393 omap3_enable_io_chain(); 393 omap3_enable_io_chain();
394 } 394 }
395 omap3_intc_prepare_idle();
395 396
396 /* 397 /*
397 * On EMU/HS devices ROM code restores a SRDC value 398 * On EMU/HS devices ROM code restores a SRDC value
@@ -438,6 +439,7 @@ void omap_sram_idle(void)
438 OMAP3430_GR_MOD, 439 OMAP3430_GR_MOD,
439 OMAP3_PRM_VOLTCTRL_OFFSET); 440 OMAP3_PRM_VOLTCTRL_OFFSET);
440 } 441 }
442 omap3_intc_resume_idle();
441 443
442 /* PER */ 444 /* PER */
443 if (per_next_state < PWRDM_POWER_ON) { 445 if (per_next_state < PWRDM_POWER_ON) {
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 0082036f6a48..c0ab7c80f72e 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -500,6 +500,8 @@ extern int omap_irq_pending(void);
500void omap_intc_save_context(void); 500void omap_intc_save_context(void);
501void omap_intc_restore_context(void); 501void omap_intc_restore_context(void);
502void omap3_intc_suspend(void); 502void omap3_intc_suspend(void);
503void omap3_intc_prepare_idle(void);
504void omap3_intc_resume_idle(void);
503#endif 505#endif
504 506
505#include <mach/hardware.h> 507#include <mach/hardware.h>