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

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