[PATCHv2 02/10] ARM: vic: MULTI_IRQ_HANDLER handler
From: Russell King - ARM Linux <hidden>
Date: 2011-11-03 12:51:36
Also in:
linux-devicetree
On Thu, Nov 03, 2011 at 01:29:08PM +0100, Linus Walleij wrote:
No, if we receive another IRQ *after* the read of the register was the question, right? Just replace stat &= ~(1 << irq); with a second stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); It'll work just fine, the IRQ line should be low when you read it the second time, else it is probably fully proper to call the IRQ handler again anyway.
It depends on what kind of behaviour you want. There are two solutions:
stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
while (stat) {
irq = ffs(stat) - 1;
handle_irq(irq);
stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
}
This gives priority to the lowest numbered interrupts; if these get stuck
then they can exclude higher numbered interrupts. This is what we
implement in the assembly code versions, and as far as I know, no one has
ever complained about that behaviour.
stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
while (stat) {
while (stat) {
irq = ffs(stat) - 1;
stat &= ~(1 << irq);
handle_irq(irq);
}
stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
}
This ensures that we process all interrupts found pending before we
re-check for any new interrupts pending. Arguably this is a much
fairer implementation (and may mean if things get irrevokably stuck,
things like sysrq via the console uart may still work.)