aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTero Kristo <tero.kristo@nokia.com>2009-10-23 19:03:50 +0300
committerKevin Hilman <khilman@deeprootsystems.com>2010-01-20 18:16:00 -0800
commitf18cc2ff5e18e8eb6df5284866331ef4a2db58d6 (patch)
tree5d20f9ba3a46c44ba11c3ed1deeed8e60e8115cc
parentb296c8118b26a359b027b8c9bb9f5f41dc7693fa (diff)
downloadhistory-f18cc2ff5e18e8eb6df5284866331ef4a2db58d6.tar.gz
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 54c5f0dcd6637d..27054025da2b50 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -280,4 +280,16 @@ void omap3_intc_suspend(void)
/* A pending interrupt would prevent OMAP from entering suspend */
omap_ack_irq(0);
}
+
+void omap3_intc_prepare_idle(void)
+{
+ /* Disable autoidle as it can stall interrupt controller */
+ intc_bank_write_reg(0, &irq_banks[0], INTC_SYSCONFIG);
+}
+
+void omap3_intc_resume_idle(void)
+{
+ /* Re-enable autoidle */
+ intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG);
+}
#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 8a148fbbab4390..af83555795ff98 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -392,6 +392,7 @@ void omap_sram_idle(void)
prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
omap3_enable_io_chain();
}
+ omap3_intc_prepare_idle();
/*
* On EMU/HS devices ROM code restores a SRDC value
@@ -438,6 +439,7 @@ void omap_sram_idle(void)
OMAP3430_GR_MOD,
OMAP3_PRM_VOLTCTRL_OFFSET);
}
+ omap3_intc_resume_idle();
/* PER */
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 0082036f6a48f5..c0ab7c80f72e75 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);
void omap_intc_save_context(void);
void omap_intc_restore_context(void);
void omap3_intc_suspend(void);
+void omap3_intc_prepare_idle(void);
+void omap3_intc_resume_idle(void);
#endif
#include <mach/hardware.h>