irqchip: omap-intc: Improve IRQ handler

As it turns out the current IRQ number will *always* be available from
SIR register which renders the reads of PENDING registers as plain
unnecessary overhead.

In order to catch any situation where SIR reads as zero, we're adding
a WARN() to turn it into a very verbose error and users actually
report it.

With this patch average running time of omap_intc_handle_irq() reduced
from about 28.5us to 19.8us as measured by the kernel function
profiler.

Tested with BeagleBoneBlack Rev A5C.

Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Cc: Linux ARM Kernel Mailing List <linux-arm-kernel@lists.infradead.org>
Link: http://lkml.kernel.org/r/20150720204910.GH5394@saruman.tx.rr.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Felipe Balbi 2015-01-02 16:18:54 -06:00 committed by Thomas Gleixner
parent e10fc03c4f
commit 6ed3464897
1 changed files with 5 additions and 30 deletions

View File

@ -330,37 +330,12 @@ static int __init omap_init_irq(u32 base, struct device_node *node)
static asmlinkage void __exception_irq_entry
omap_intc_handle_irq(struct pt_regs *regs)
{
u32 irqnr = 0;
int handled_irq = 0;
int i;
u32 irqnr;
do {
for (i = 0; i < omap_nr_pending; i++) {
irqnr = intc_readl(INTC_PENDING_IRQ0 + (0x20 * i));
if (irqnr)
goto out;
}
out:
if (!irqnr)
break;
irqnr = intc_readl(INTC_SIR);
irqnr &= ACTIVEIRQ_MASK;
if (irqnr) {
handle_domain_irq(domain, 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);
irqnr = intc_readl(INTC_SIR);
irqnr &= ACTIVEIRQ_MASK;
WARN_ONCE(!irqnr, "Spurious IRQ ?\n");
handle_domain_irq(domain, irqnr, regs);
}
void __init omap3_init_irq(void)