aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorStefan Sørensen <stefan.sorensen@spectralink.com>2014-03-06 10:27:15 -0500
committerTony Lindgren <tony@atomide.com>2014-03-13 16:34:48 -0400
commit698b48532539484b012fb7c4176b959d32a17d00 (patch)
tree4d91b13bddccc7fe209907fe25c72161b089d40b /arch
parentcfbf8d4857c26a8a307fb7cd258074c9dcd8c691 (diff)
ARM: OMAP2+: INTC: Acknowledge stuck active interrupts
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. Cc: stable@vger.kernel.org Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/irq.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index e022a869bff2..6037a9a01ed5 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)
222static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) 222static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
223{ 223{
224 u32 irqnr; 224 u32 irqnr;
225 int handled_irq = 0;
225 226
226 do { 227 do {
227 irqnr = readl_relaxed(base_addr + 0x98); 228 irqnr = readl_relaxed(base_addr + 0x98);
@@ -249,8 +250,15 @@ out:
249 if (irqnr) { 250 if (irqnr) {
250 irqnr = irq_find_mapping(domain, irqnr); 251 irqnr = irq_find_mapping(domain, irqnr);
251 handle_IRQ(irqnr, regs); 252 handle_IRQ(irqnr, regs);
253 handled_irq = 1;
252 } 254 }
253 } while (irqnr); 255 } while (irqnr);
256
257 /* If an irq is masked or deasserted while active, we will
258 * keep ending up here with no irq handled. So remove it from
259 * the INTC with an ack.*/
260 if (!handled_irq)
261 omap_ack_irq(NULL);
254} 262}
255 263
256asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs) 264asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs)