]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/microblaze/cpu/interrupts.c
microblaze: avoid interrupt race conditions
[karo-tx-uboot.git] / arch / microblaze / cpu / interrupts.c
index a6021c99c3b2ab6a563fdfb1acc14b2ce6ed3d30..e7ca859bfe446be14489239250740f0c40fe2133 100644 (file)
@@ -41,18 +41,14 @@ void enable_interrupts (void)
 
 int disable_interrupts (void)
 {
+       unsigned int msr;
+
+       MFS(msr, rmsr);
        MSRCLR(0x2);
-       return 0;
+       return (msr & 0x2) != 0;
 }
 
 #ifdef CONFIG_SYS_INTC_0
-#ifdef CONFIG_SYS_TIMER_0
-extern void timer_init (void);
-#endif
-#ifdef CONFIG_SYS_FSL_2
-extern void fsl_init2 (void);
-#endif
-
 
 static struct irq_action vecs[CONFIG_SYS_INTC_0_NUM];
 
@@ -142,20 +138,14 @@ int interrupts_init (void)
        }
        /* initialize intc controller */
        intc_init ();
-#ifdef CONFIG_SYS_TIMER_0
-       timer_init ();
-#endif
-#ifdef CONFIG_SYS_FSL_2
-       fsl_init2 ();
-#endif
        enable_interrupts ();
        return 0;
 }
 
 void interrupt_handler (void)
 {
-       int irqs = (intc->isr & intc->ier);     /* find active interrupt */
-       int i = 1;
+       int irqs = intc->ivr;   /* find active interrupt */
+       int mask = 1;
 #ifdef DEBUG_INT
        int value;
        printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
@@ -163,23 +153,17 @@ void interrupt_handler (void)
        R14(value);
        printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
 #endif
-       struct irq_action *act = vecs;
-       while (irqs) {
-               if (irqs & 1) {
+       struct irq_action *act = vecs + irqs;
+
 #ifdef DEBUG_INT
-                       printf
-                           ("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n",
-                            act->handler, act->count, act->arg);
+       printf
+           ("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n",
+            act->handler, act->count, act->arg);
 #endif
-                       act->handler (act->arg);
-                       act->count++;
-                       intc->iar = i;
-                       return;
-               }
-               irqs >>= 1;
-               act++;
-               i <<= 1;
-       }
+       act->handler (act->arg);
+       act->count++;
+
+       intc->iar = mask << irqs;
 
 #ifdef DEBUG_INT
        printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr,
@@ -192,7 +176,7 @@ void interrupt_handler (void)
 
 #if defined(CONFIG_CMD_IRQ)
 #ifdef CONFIG_SYS_INTC_0
-int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        int i;
        struct irq_action *act = vecs;
@@ -212,7 +196,7 @@ int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        return (0);
 }
 #else
-int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        puts ("Undefined interrupt controller\n");
 }