=================================================================== RCS file: /cvs/funnyos/arch/testarm/dev/tairqc.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- funnyos/arch/testarm/dev/tairqc.c 2007/11/02 13:27:42 1.5 +++ funnyos/arch/testarm/dev/tairqc.c 2007/11/04 23:15:57 1.6 @@ -1,11 +1,13 @@ /* - * $Id: tairqc.c,v 1.5 2007/11/02 13:27:42 init Exp $ + * $Id: tairqc.c,v 1.6 2007/11/04 23:15:57 init Exp $ */ #include #include #include #include +#include + #include #include #include @@ -42,6 +44,7 @@ tairqc_attach(struct device *self, uint32_t loc, uint8_t flags) { struct tairqc_dd *ddp = self->dv_devdata; + uint8_t intrno; /* leap to parent's bus_handle */ ddp->td_bushandlep = self->dv_parent->dv_aux; @@ -56,9 +59,15 @@ /* override trampoline so core irq jumps to us */ irq_trampoline_func = tairqc_irq; + /* mask all interrupts */ + for (intrno = 0; intrno < 32; intrno++) + tairqc_mask_intr(intrno); + /* XXX unmask rtc intr */ tairqc_unmask_intr(4); + __cpu_enable_irq(); + return(0); } @@ -91,12 +100,27 @@ { /* * Process an IRQ. + * Check interrupt status of the irqc and execute corresponding intr handlers + * for every asserted interrupt source (could be 0...31 on tairqc) */ - uint32_t irqstatus; + uint32_t irqstatus; + uint8_t intrno; /* read intr status; one bit per intr source */ irqstatus = tairqc_intrstatus(); - DPRINTF("tairqc_itq: got interrupt (status=0x%x)\n", irqstatus); + DPRINTF("tairqc_irq: got interrupt (status=0x%x)\n", irqstatus); + + /* exit if no interrupts; should not happen */ + if (irqstatus == 0) + return; + + /* let kern_irq throw us to the right place */ + for (intrno = 0; intrno < 32; intrno++) + if (irqstatus & (1 << intrno)) { + /* interrupt line is active */ + intr_execute(intrno); + } + }