ns9xxx: fix handle_prio_irq to unmask irqs with lower priority
authorUwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Fri, 25 Apr 2008 13:03:18 +0000 (15:03 +0200)
committerUwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Fri, 25 Apr 2008 13:45:08 +0000 (15:45 +0200)
When an irq is reported all lower prio irqs are masked until the current
irq is acked.  So never leave handle_prio_irq without acking.

desc->status & IRQ_INPROGRESS should never become true because the current
irq is masked until it is acked, too.

Signed-off-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
arch/arm/mach-ns9xxx/irq.c

index 7ddc8fde7748dcb255e8d634278e4cd514422b94..ba7a9e4888f07aa0ef84d209c332728fe9632ac8 100644 (file)
@@ -64,15 +64,14 @@ void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 
        spin_lock(&desc->lock);
 
-       if (unlikely(desc->status & IRQ_INPROGRESS))
-               goto out_unlock;
+       BUG_ON(desc->status & IRQ_INPROGRESS);
 
        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
        kstat_cpu(cpu).irqs[irq]++;
 
        action = desc->action;
        if (unlikely(!action || (desc->status & IRQ_DISABLED)))
-               goto out_unlock;
+               goto out_mask;
 
        desc->status |= IRQ_INPROGRESS;
        spin_unlock(&desc->lock);
@@ -81,10 +80,14 @@ void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 
        spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
-       if (!(desc->status & IRQ_DISABLED) && desc->chip->ack)
-               desc->chip->ack(irq);
 
-out_unlock:
+       if (desc->status & IRQ_DISABLED)
+out_mask:
+               desc->chip->mask(irq);
+
+       /* ack unconditionally to unmask lower prio irqs */
+       desc->chip->ack(irq);
+
        spin_unlock(&desc->lock);
 }
 #define handle_irq handle_prio_irq