[BACK]Return to saaic.c CVS log [TXT][DIR] Up to [local] / funnyos / arch / sam7s64 / dev

Annotation of funnyos/arch/sam7s64/dev/saaic.c, Revision 1.2

1.1       nbrk        1: /*
1.2     ! nbrk        2:  * $Id: saaic.c,v 1.1 2007/11/24 20:49:44 nbrk Exp $
1.1       nbrk        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:
1.2     ! nbrk       15: #define SAAIC_DEBUG
1.1       nbrk       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);
1.2     ! nbrk       27: extern struct intr_vector *irqtable;
1.1       nbrk       28: struct saaic_dd *irqcdd;                       /* current irqc device */
                     29:
                     30: struct driver saaic_dr = {
                     31:        sizeof(struct saaic_dd),
                     32:        saaic_attach,
                     33:        NULL,
                     34:        NULL
                     35: };
                     36:
                     37:
                     38: int
                     39: saaic_attach(struct device *self, uint32_t loc, uint8_t flags)
                     40: {
                     41:        struct saaic_dd *ddp = self->dv_devdata;
1.2     ! nbrk       42:        uint8_t intrno;
        !            43:        struct intr_vector *ivp = irqtable;
1.1       nbrk       44:
                     45:        /* leap to parent's bus_handle */
                     46:        ddp->sa_bhp = self->dv_parent->dv_aux;
                     47:
                     48:        /* make this controller default */
                     49:        irqcdd = ddp;
                     50:
                     51:        printf("SAM7 Advanced Interrupt Controller (32 sources, 8 pri_levels)\n");
                     52:
                     53:        /* override trampoline so core irq jumps to us */
                     54:        irq_trampoline_func = saaic_irq;
                     55:
                     56:        /* mask all interrupts */
                     57:        for (intrno = 0; intrno < 32; intrno++)
                     58:                saaic_unmask_intr(intrno);
                     59:
1.2     ! nbrk       60:        /* clear all interrupts */
        !            61:        for (intrno = 0; intrno < 32; intrno++)
        !            62:                saaic_clear_intr(intrno);
        !            63:
        !            64:        /* look in system irqtable for claimed interrupts and unmask them */
        !            65:        while(ivp != NULL) {
        !            66:                saaic_unmask_intr(ivp->iv_intrno);
        !            67:
        !            68:                ivp = ivp->iv_next;
        !            69:        }
        !            70:
1.1       nbrk       71:        __cpu_enable_irq();
                     72:
                     73:        return(0);
                     74: }
                     75:
                     76:
                     77: void
                     78: saaic_mask_intr(uint8_t intrno)
                     79: {
                     80:        bus_write_4(irqcdd->sa_bhp, (uint32_t)AT91C_AIC_IDCR, 1 << intrno);
                     81:        DPRINTF("saaic_mask_intr: masked interrupt no. %d (status=0x%x)\n", intrno, saaic_intrstatus());
                     82: }
                     83:
                     84:
                     85: void
                     86: saaic_unmask_intr(uint8_t intrno)
                     87: {
                     88:        bus_write_1(irqcdd->sa_bhp, (uint32_t)AT91C_AIC_IECR, 1 << intrno);
                     89:        DPRINTF("saaic_unmask_intr: unmasked interrupt no. %d (status=0x%x)\n", intrno, saaic_intrstatus());
                     90: }
                     91:
                     92:
1.2     ! nbrk       93: void
        !            94: saaic_clear_intr(uint8_t intrno)
        !            95: {
        !            96:        bus_write_1(irqcdd->sa_bhp, (uint32_t)AT91C_AIC_ICCR, 1 << intrno);
        !            97:        DPRINTF("saaic_clear_intr: cleared interrupt no. %d (status=0x%x)\n", intrno, saaic_intrstatus());
        !            98: }
        !            99:
        !           100:
        !           101: void
        !           102: saaic_ack_intr(void)
        !           103: {
        !           104:        bus_write_1(irqcdd->sa_bhp, (uint32_t)AT91C_AIC_EOICR, 1);
        !           105:        DPRINTF("saaic_ack_intr: acknowledged current interrupt (status=0x%x)\n", saaic_intrstatus());
        !           106: }
        !           107:
        !           108:
        !           109:
1.1       nbrk      110: uint32_t
                    111: saaic_intrstatus(void)
                    112: {
1.2     ! nbrk      113:        return( bus_read_4(irqcdd->sa_bhp, (uint32_t)AT91C_AIC_IPR));
1.1       nbrk      114: }
                    115:
                    116:
                    117: void
                    118: saaic_irq(void)
                    119: {
                    120:        /*
                    121:         * Process an IRQ.
                    122:         * Check interrupt status of the irqc and execute corresponding intr handlers.
                    123:         */
                    124:        uint32_t irqstatus;
                    125:        uint8_t intrno;
                    126:
                    127:        /* read intr status; one bit per intr source */
                    128:        irqstatus = saaic_intrstatus();
                    129:
1.2     ! nbrk      130:        DPRINTF("saaic_irq: got interrupt (pending mask=0x%x)\n", irqstatus);
1.1       nbrk      131:
                    132:        /* exit if no interrupts; should not happen */
1.2     ! nbrk      133: //     if (irqstatus == 0)
        !           134: //             return;
1.1       nbrk      135:
                    136:        /* let kern_irq throw us to the right place */
                    137:        for (intrno = 0; intrno < 32; intrno++)
                    138:                if (irqstatus & (1 << intrno)) {
                    139:                        /* interrupt line is active */
                    140:                        intr_execute(intrno);
1.2     ! nbrk      141:
        !           142:                        /* XXX */
        !           143:                        saaic_clear_intr(intrno);
        !           144:
        !           145:                        /* XXX acknowledge this interrupt */
        !           146:                        saaic_ack_intr();
1.1       nbrk      147:                }
                    148:
                    149: }
                    150:

CVSweb