Annotation of funnyos/arch/sam7s64/dev/saaic.c, Revision 1.1
1.1 ! nbrk 1: /*
! 2: * $Id$
! 3: */
! 4: #include <sys/types.h>
! 5: #include <sys/device.h>
! 6: #include <sys/bus.h>
! 7: #include <sys/kern_irq.h>
! 8:
! 9: #include <dev/cpuvar.h>
! 10:
! 11: #include <arch/sam7s64/dev/saaicvar.h>
! 12: #include <arch/sam7s64/dev/at91sam7.h>
! 13: #include <libkern/printf.h>
! 14:
! 15: #define SAAIC_DEBUG
! 16:
! 17: #ifdef SAAIC_DEBUG
! 18: #define DPRINTF(x...) do { printf(x); } while (0)
! 19: #else
! 20: #define DPRINTF(x...) { }
! 21: #endif
! 22:
! 23: /*
! 24: * Advanced Interrupt Controller.
! 25: */
! 26: extern void (*irq_trampoline_func)(void);
! 27: struct saaic_dd *irqcdd; /* current irqc device */
! 28:
! 29: struct driver saaic_dr = {
! 30: sizeof(struct saaic_dd),
! 31: saaic_attach,
! 32: NULL,
! 33: NULL
! 34: };
! 35:
! 36:
! 37: int
! 38: saaic_attach(struct device *self, uint32_t loc, uint8_t flags)
! 39: {
! 40: struct saaic_dd *ddp = self->dv_devdata;
! 41: uint8_t intrno;
! 42:
! 43: /* leap to parent's bus_handle */
! 44: ddp->sa_bhp = self->dv_parent->dv_aux;
! 45:
! 46: /* make this controller default */
! 47: irqcdd = ddp;
! 48:
! 49: printf("SAM7 Advanced Interrupt Controller (32 sources, 8 pri_levels)\n");
! 50:
! 51: /* override trampoline so core irq jumps to us */
! 52: irq_trampoline_func = saaic_irq;
! 53:
! 54: /* mask all interrupts */
! 55: for (intrno = 0; intrno < 32; intrno++)
! 56: saaic_unmask_intr(intrno);
! 57:
! 58: __cpu_enable_irq();
! 59:
! 60: return(0);
! 61: }
! 62:
! 63:
! 64: void
! 65: saaic_mask_intr(uint8_t intrno)
! 66: {
! 67: bus_write_4(irqcdd->sa_bhp, (uint32_t)AT91C_AIC_IDCR, 1 << intrno);
! 68: DPRINTF("saaic_mask_intr: masked interrupt no. %d (status=0x%x)\n", intrno, saaic_intrstatus());
! 69: }
! 70:
! 71:
! 72: void
! 73: saaic_unmask_intr(uint8_t intrno)
! 74: {
! 75: bus_write_1(irqcdd->sa_bhp, (uint32_t)AT91C_AIC_IECR, 1 << intrno);
! 76: DPRINTF("saaic_unmask_intr: unmasked interrupt no. %d (status=0x%x)\n", intrno, saaic_intrstatus());
! 77: }
! 78:
! 79:
! 80: uint32_t
! 81: saaic_intrstatus(void)
! 82: {
! 83: return( bus_read_4(irqcdd->sa_bhp, (uint32_t)AT91C_AIC_IMR));
! 84: }
! 85:
! 86:
! 87: void
! 88: saaic_irq(void)
! 89: {
! 90: /*
! 91: * Process an IRQ.
! 92: * Check interrupt status of the irqc and execute corresponding intr handlers.
! 93: */
! 94: uint32_t irqstatus;
! 95: uint8_t intrno;
! 96:
! 97: /* read intr status; one bit per intr source */
! 98: irqstatus = saaic_intrstatus();
! 99:
! 100: DPRINTF("saaic_irq: got interrupt (status=0x%x)\n", irqstatus);
! 101:
! 102: /* exit if no interrupts; should not happen */
! 103: if (irqstatus == 0)
! 104: return;
! 105:
! 106: /* let kern_irq throw us to the right place */
! 107: for (intrno = 0; intrno < 32; intrno++)
! 108: if (irqstatus & (1 << intrno)) {
! 109: /* interrupt line is active */
! 110: intr_execute(intrno);
! 111: }
! 112:
! 113: }
! 114:
CVSweb