fix: interrupt handler for multiple sources
authorMichal Simek <monstr@monstr.eu>
Mon, 7 May 2007 15:22:25 +0000 (17:22 +0200)
committerMichal Simek <monstr@monstr.eu>
Mon, 7 May 2007 15:22:25 +0000 (17:22 +0200)
cpu/microblaze/interrupts.c
cpu/microblaze/timer.c
include/asm-microblaze/microblaze_intc.h

index 2db847cd02c368d29f7084dadac9dbdd94b96c3d..115e58d7f08e36aaec041a5210d007024c375343 100644 (file)
@@ -27,6 +27,7 @@
 #include <common.h>
 #include <command.h>
 #include <asm/microblaze_intc.h>
+#include <asm/asm.h>
 
 #undef DEBUG_INT
 
@@ -106,7 +107,6 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg)
                act->count = 0;
                enable_one_interrupt (irq);
        } else {                /* disable */
-
                act->handler = (interrupt_handler_t *) def_hdlr;
                act->arg = (void *)irq;
                disable_one_interrupt (irq);
@@ -147,12 +147,13 @@ int interrupts_init (void)
 
 void interrupt_handler (void)
 {
-       int irqs;
-       irqs = (intc->isr & intc->ier); /* find active interrupt */
-
+       int irqs = (intc->isr & intc->ier);     /* find active interrupt */
+       int i = 1;
 #ifdef DEBUG_INT
+       int value;
        printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
                intc->iar, intc->mer);
+       R14(value);
        printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
 #endif
        struct irq_action *act = vecs;
@@ -165,15 +166,19 @@ void interrupt_handler (void)
 #endif
                        act->handler (act->arg);
                        act->count++;
+                       intc->iar = i;
+                       return;
                }
                irqs >>= 1;
                act++;
+               i <<= 1;
        }
-       intc->iar = 0xFFFFFFFF; /* erase all events */
-#ifdef DEBUG
+
+#ifdef DEBUG_INT
        printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr,
                intc->ier, intc->iar, intc->mer);
-       printf ("Interrupt handler on %x line, r14\n", irqs);
+       R14(value);
+       printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
 #endif
 }
 #endif
index be4fd57cc49dd3b76041071ba4d3332426af7021..ab1cb127492b0c18dff5eb7d3884ae0af117bf3f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <common.h>
 #include <asm/microblaze_timer.h>
+#include <asm/microblaze_intc.h>
 
 volatile int timestamp = 0;
 
@@ -44,9 +45,6 @@ void set_timer (ulong t)
 
 #ifdef CFG_INTC_0
 #ifdef CFG_TIMER_0
-extern void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,
-                                      void *arg);
-
 microblaze_timer_t *tmr = (microblaze_timer_t *) (CFG_TIMER_0_ADDR);
 
 void timer_isr (void *arg)
index 73f732c56678bc8ce79f422600a7fabab9044a0a..4c385aa24f012218f58e3e59abc3422586305de9 100644 (file)
@@ -39,3 +39,5 @@ struct irq_action {
        int count; /* number of interrupt */
 };
 
+void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,
+                                      void *arg);