]> git.sur5r.net Git - u-boot/blobdiff - arch/microblaze/cpu/interrupts.c
microblaze: Read information about timer/interrupts from DT
[u-boot] / arch / microblaze / cpu / interrupts.c
index 9364e2fa9c9b0fb1e810ad2d2f88a6cd7deafdd0..e5d8894f54471a783efc11b1728f5de73a56e196 100644 (file)
 
 #include <common.h>
 #include <command.h>
+#include <fdtdec.h>
 #include <malloc.h>
 #include <asm/microblaze_intc.h>
 #include <asm/asm.h>
 
-#undef DEBUG_INT
+DECLARE_GLOBAL_DATA_PTR;
 
 void enable_interrupts(void)
 {
+       debug("Enable interrupts for the whole CPU\n");
        MSRSET(0x2);
 }
 
@@ -50,12 +52,11 @@ static void enable_one_interrupt(int irq)
        offset <<= irq;
        mask = intc->ier;
        intc->ier = (mask | offset);
-#ifdef DEBUG_INT
-       printf("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask,
-               intc->ier);
-       printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
-               intc->iar, intc->mer);
-#endif
+
+       debug("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask,
+             intc->ier);
+       debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
+             intc->iar, intc->mer);
 }
 
 static void disable_one_interrupt(int irq)
@@ -66,12 +67,11 @@ static void disable_one_interrupt(int irq)
        offset <<= irq;
        mask = intc->ier;
        intc->ier = (mask & ~offset);
-#ifdef DEBUG_INT
-       printf("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask,
-               intc->ier);
-       printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
-               intc->iar, intc->mer);
-#endif
+
+       debug("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask,
+             intc->ier);
+       debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
+             intc->iar, intc->mer);
 }
 
 int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg)
@@ -88,12 +88,12 @@ int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg)
                act->handler = hdlr;
                act->arg = arg;
                act->count = 0;
-               enable_one_interrupt (irq);
+               enable_one_interrupt(irq);
                return 0;
        }
 
        /* Disable */
-       act->handler = (interrupt_handler_t *) def_hdlr;
+       act->handler = (interrupt_handler_t *)def_hdlr;
        act->arg = (void *)irq;
        disable_one_interrupt(irq);
        return 1;
@@ -107,19 +107,40 @@ static void intc_init(void)
        intc->iar = 0xFFFFFFFF;
        /* XIntc_Start - hw_interrupt enable and all interrupt enable */
        intc->mer = 0x3;
-#ifdef DEBUG_INT
-       printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
-               intc->iar, intc->mer);
-#endif
+
+       debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
+             intc->iar, intc->mer);
 }
 
-int interrupts_init(void)
+int interrupt_init(void)
 {
        int i;
 
+#ifdef CONFIG_OF_CONTROL
+       const void *blob = gd->fdt_blob;
+       int node = 0;
+
+       debug("INTC: Initialization\n");
+
+       node = fdt_node_offset_by_compatible(blob, node,
+                               "xlnx,xps-intc-1.00.a");
+       if (node != -1) {
+               fdt_addr_t base = fdtdec_get_addr(blob, node, "reg");
+               if (base == FDT_ADDR_T_NONE)
+                       return -1;
+
+               debug("INTC: Base addr %lx\n", base);
+               intc = (microblaze_intc_t *)base;
+               irq_no = fdtdec_get_int(blob, node, "xlnx,num-intr-inputs", 0);
+               debug("INTC: IRQ NO %x\n", irq_no);
+       } else {
+               return node;
+       }
+#else
 #if defined(CONFIG_SYS_INTC_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM)
-       intc = (microblaze_intc_t *) (CONFIG_SYS_INTC_0_ADDR);
+       intc = (microblaze_intc_t *)CONFIG_SYS_INTC_0_ADDR;
        irq_no = CONFIG_SYS_INTC_0_NUM;
+#endif
 #endif
        if (irq_no) {
                vecs = calloc(1, sizeof(struct irq_action) * irq_no);
@@ -130,7 +151,7 @@ int interrupts_init(void)
 
                /* initialize irq list */
                for (i = 0; i < irq_no; i++) {
-                       vecs[i].handler = (interrupt_handler_t *) def_hdlr;
+                       vecs[i].handler = (interrupt_handler_t *)def_hdlr;
                        vecs[i].arg = (void *)i;
                        vecs[i].count = 0;
                }
@@ -147,31 +168,29 @@ void interrupt_handler(void)
 {
        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,
-               intc->iar, intc->mer);
-       R14(value);
-       printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
-#endif
        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);
+       debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
+             intc->iar, intc->mer);
+#ifdef DEBUG
+       R14(value);
 #endif
-       act->handler (act->arg);
+       debug("Interrupt handler on %x line, r14 %x\n", irqs, value);
+
+       debug("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n",
+             (u32)act->handler, act->count, (u32)act->arg);
+       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,
-               intc->ier, intc->iar, intc->mer);
+       debug("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr,
+             intc->ier, intc->iar, intc->mer);
+#ifdef DEBUG
        R14(value);
-       printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
 #endif
+       debug("Interrupt handler on %x line, r14 %x\n", irqs, value);
 }
 
 #if defined(CONFIG_CMD_IRQ)
@@ -186,10 +205,10 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, const char *argv[])
                      "-----------------------------\n");
 
                for (i = 0; i < irq_no; i++) {
-                       if (act->handler != (interrupt_handler_t *) def_hdlr) {
+                       if (act->handler != (interrupt_handler_t *)def_hdlr) {
                                printf("%02d  %08x  %08x  %d\n", i,
-                                       (int)act->handler, (int)act->arg,
-                                                               act->count);
+                                      (int)act->handler, (int)act->arg,
+                                      act->count);
                        }
                        act++;
                }