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.)
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

Reply via email to