When an interrupt has become active on the INTC it will stay active
until it is acked, even if masked or de-asserted. The
INTC_PENDING_IRQn registers are however updated and since these are
used by omap_intc_handle_irq to determine which interrupt to handle,
it will never see the active interrupt. This will result in a storm of
useless interrupts that is only stopped when another higher priority
interrupt is asserted.

Fix by sending the INTC an acknowledge if we find no interrupts to
handle.

Signed-off-by: Stefan Sørensen <stefan.soren...@spectralink.com>
---
 arch/arm/mach-omap2/irq.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index e022a86..6037a9a 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -222,6 +222,7 @@ void __init ti81xx_init_irq(void)
 static inline void omap_intc_handle_irq(void __iomem *base_addr, struct 
pt_regs *regs)
 {
        u32 irqnr;
+       int handled_irq = 0;
 
        do {
                irqnr = readl_relaxed(base_addr + 0x98);
@@ -249,8 +250,15 @@ out:
                if (irqnr) {
                        irqnr = irq_find_mapping(domain, irqnr);
                        handle_IRQ(irqnr, regs);
+                       handled_irq = 1;
                }
        } while (irqnr);
+
+       /* If an irq is masked or deasserted while active, we will
+        * keep ending up here with no irq handled. So remove it from
+        * the INTC with an ack.*/
+       if (!handled_irq)
+               omap_ack_irq(NULL);
 }
 
 asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs 
*regs)
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to