[PATCHv2 02/10] ARM: vic: MULTI_IRQ_HANDLER handler
Russell King - ARM Linux
linux at arm.linux.org.uk
Thu Nov 3 08:51:36 EDT 2011
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.)
More information about the linux-arm-kernel
mailing list