| From 698b48532539484b012fb7c4176b959d32a17d00 Mon Sep 17 00:00:00 2001 |
| From: Stefan Sørensen <stefan.sorensen@spectralink.com> |
| Date: Thu, 6 Mar 2014 16:27:15 +0100 |
| Subject: ARM: OMAP2+: INTC: Acknowledge stuck active interrupts |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Stefan Sørensen <stefan.sorensen@spectralink.com> |
| |
| commit 698b48532539484b012fb7c4176b959d32a17d00 upstream. |
| |
| 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.sorensen@spectralink.com> |
| Signed-off-by: Tony Lindgren <tony@atomide.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/arm/mach-omap2/irq.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/arch/arm/mach-omap2/irq.c |
| +++ b/arch/arm/mach-omap2/irq.c |
| @@ -220,6 +220,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); |
| @@ -247,8 +248,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) |