version 1.5, 2007/11/02 13:27:42 |
version 1.6, 2007/11/04 23:15:57 |
|
|
#include <sys/bus.h> |
#include <sys/bus.h> |
#include <sys/kern_irq.h> |
#include <sys/kern_irq.h> |
|
|
|
#include <dev/cpuvar.h> |
|
|
#include <arch/testarm/dev/tairqcvar.h> |
#include <arch/testarm/dev/tairqcvar.h> |
#include <arch/testarm/dev/tairqcreg.h> |
#include <arch/testarm/dev/tairqcreg.h> |
#include <libkern/printf.h> |
#include <libkern/printf.h> |
|
|
tairqc_attach(struct device *self, uint32_t loc, uint8_t flags) |
tairqc_attach(struct device *self, uint32_t loc, uint8_t flags) |
{ |
{ |
struct tairqc_dd *ddp = self->dv_devdata; |
struct tairqc_dd *ddp = self->dv_devdata; |
|
uint8_t intrno; |
|
|
/* leap to parent's bus_handle */ |
/* leap to parent's bus_handle */ |
ddp->td_bushandlep = self->dv_parent->dv_aux; |
ddp->td_bushandlep = self->dv_parent->dv_aux; |
|
|
/* override trampoline so core irq jumps to us */ |
/* override trampoline so core irq jumps to us */ |
irq_trampoline_func = tairqc_irq; |
irq_trampoline_func = tairqc_irq; |
|
|
|
/* mask all interrupts */ |
|
for (intrno = 0; intrno < 32; intrno++) |
|
tairqc_mask_intr(intrno); |
|
|
/* XXX unmask rtc intr */ |
/* XXX unmask rtc intr */ |
tairqc_unmask_intr(4); |
tairqc_unmask_intr(4); |
|
|
|
__cpu_enable_irq(); |
|
|
return(0); |
return(0); |
} |
} |
|
|
|
|
{ |
{ |
/* |
/* |
* Process an IRQ. |
* 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 */ |
/* read intr status; one bit per intr source */ |
irqstatus = tairqc_intrstatus(); |
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); |
|
} |
|
|
} |
} |
|
|