Annotation of funnyos/arch/testarm/dev/tairqc.c, Revision 1.7
1.1 init 1: /*
1.7 ! init 2: * $Id: tairqc.c,v 1.6 2007/11/04 23:15:57 init Exp $
1.1 init 3: */
4: #include <sys/types.h>
5: #include <sys/device.h>
6: #include <sys/bus.h>
1.3 init 7: #include <sys/kern_irq.h>
1.1 init 8:
1.6 init 9: #include <dev/cpuvar.h>
10:
1.1 init 11: #include <arch/testarm/dev/tairqcvar.h>
12: #include <arch/testarm/dev/tairqcreg.h>
1.3 init 13: #include <libkern/printf.h>
1.1 init 14:
1.7 ! init 15: /* #define TAIRQC_DEBUG */
1.5 init 16:
17: #ifdef TAIRQC_DEBUG
18: #define DPRINTF(x...) do { printf(x); } while (0)
19: #else
20: #define DPRINTF(x...) { }
21: #endif
22:
1.1 init 23: /*
24: * testarm Interrupt Controller Unit support.
25: */
26: int tairqc_attach(struct device *self, uint32_t loc, uint8_t flags);
1.3 init 27: void tairqc_mask_intr(uint8_t intrno);
28: void tairqc_unmask_intr(uint8_t intrno);
29: uint32_t tairqc_intrstatus(void);
1.1 init 30: void tairqc_irq(void);
31:
1.3 init 32: extern void (*irq_trampoline_func)(void);
33: struct tairqc_dd *irqcdd; /* current irq device */
1.1 init 34:
35: struct driver tairqc_dr = {
36: sizeof(struct tairqc_dd),
37: tairqc_attach,
1.2 init 38: NULL,
1.1 init 39: NULL
40: };
41:
42:
43: int
44: tairqc_attach(struct device *self, uint32_t loc, uint8_t flags)
45: {
46: struct tairqc_dd *ddp = self->dv_devdata;
1.6 init 47: uint8_t intrno;
1.1 init 48:
49: /* leap to parent's bus_handle */
50: ddp->td_bushandlep = self->dv_parent->dv_aux;
51:
1.3 init 52: /* save locator */
53: ddp->td_ioaddr = loc ? loc : TAIRQC_REG_BASE;
1.1 init 54:
1.3 init 55: irqcdd = ddp;
56:
57: printf("testarm IRQ Controller (2=cons, 3=ether, 4=rtc, 6=mp)\n");
58:
59: /* override trampoline so core irq jumps to us */
60: irq_trampoline_func = tairqc_irq;
61:
1.6 init 62: /* mask all interrupts */
63: for (intrno = 0; intrno < 32; intrno++)
64: tairqc_mask_intr(intrno);
65:
1.3 init 66: /* XXX unmask rtc intr */
67: tairqc_unmask_intr(4);
1.4 init 68:
1.6 init 69: __cpu_enable_irq();
70:
1.4 init 71: return(0);
1.3 init 72: }
73:
74:
75: void
76: tairqc_mask_intr(uint8_t intrno)
77: {
78: bus_write_1(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQMASK, intrno);
1.5 init 79: DPRINTF("tairqc_mask_intr: masked interrupt no. %d (status=0x%x)\n", intrno, tairqc_intrstatus());
1.3 init 80: }
81:
82:
83: void
84: tairqc_unmask_intr(uint8_t intrno)
85: {
86: bus_write_1(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQUNMASK, intrno);
1.5 init 87: DPRINTF("tairqc_unmask_intr: unmasked interrupt no. %d (status=0x%x)\n", intrno, tairqc_intrstatus());
1.3 init 88: }
89:
90:
91: uint32_t
92: tairqc_intrstatus(void)
93: {
94: bus_read_4(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQSTATUS);
1.1 init 95: }
96:
97:
98: void
99: tairqc_irq(void)
100: {
101: /*
1.3 init 102: * Process an IRQ.
1.6 init 103: * Check interrupt status of the irqc and execute corresponding intr handlers
104: * for every asserted interrupt source (could be 0...31 on tairqc)
1.1 init 105: */
1.6 init 106: uint32_t irqstatus;
107: uint8_t intrno;
1.3 init 108:
109: /* read intr status; one bit per intr source */
110: irqstatus = tairqc_intrstatus();
1.1 init 111:
1.6 init 112: DPRINTF("tairqc_irq: got interrupt (status=0x%x)\n", irqstatus);
113:
114: /* exit if no interrupts; should not happen */
115: if (irqstatus == 0)
116: return;
117:
118: /* let kern_irq throw us to the right place */
119: for (intrno = 0; intrno < 32; intrno++)
120: if (irqstatus & (1 << intrno)) {
121: /* interrupt line is active */
122: intr_execute(intrno);
123: }
124:
1.1 init 125: }
126:
CVSweb