microblaze: Fix level interrupt ACKing
authorsteve@digidescorp.com <steve@digidescorp.com>
Tue, 17 Nov 2009 14:43:39 +0000 (08:43 -0600)
committerMichal Simek <monstr@monstr.eu>
Mon, 14 Dec 2009 07:45:06 +0000 (08:45 +0100)
Level interrupts need to be ack'd in the unmask handler, as in powerpc.
Among other issues, this bug causes the system clock to appear to run at
double-speed.

Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
Signed-off-by: Michal Simek <monstr@monstr.eu>
arch/microblaze/kernel/intc.c

index 6eea6f9..03172c1 100644 (file)
@@ -42,8 +42,16 @@ unsigned int nr_irq;
 
 static void intc_enable_or_unmask(unsigned int irq)
 {
+       unsigned long mask = 1 << irq;
        pr_debug("enable_or_unmask: %d\n", irq);
-       out_be32(INTC_BASE + SIE, 1 << irq);
+       out_be32(INTC_BASE + SIE, mask);
+
+       /* ack level irqs because they can't be acked during
+        * ack function since the handle_level_irq function
+        * acks the irq before calling the interrupt handler
+        */
+       if (irq_desc[irq].status & IRQ_LEVEL)
+               out_be32(INTC_BASE + IAR, mask);
 }
 
 static void intc_disable_or_mask(unsigned int irq)