static int ti_aintc_attach(device_t dev) { struct ti_aintc_softc *sc = device_get_softc(dev); uint32_t x; sc->sc_dev = dev; if (ti_aintc_sc) return (ENXIO); if (bus_alloc_resources(dev, ti_aintc_spec, sc->aintc_res)) { device_printf(dev, "could not allocate resources\n"); return (ENXIO); } sc->aintc_bst = rman_get_bustag(sc->aintc_res[0]); sc->aintc_bsh = rman_get_bushandle(sc->aintc_res[0]); ti_aintc_sc = sc; x = aintc_read_4(INTC_REVISION); device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF); /* SoftReset */ aintc_write_4(INTC_SYSCONFIG, 2); /* Wait for reset to complete */ while(!(aintc_read_4(INTC_SYSSTATUS) & 1)); /*Set Priority Threshold */ aintc_write_4(INTC_THRESHOLD, 0xFF); return (0); }
void arm_mask_irq(uintptr_t nb) { uint32_t bit, block, value; bit = (nb % 32); block = (nb / 32); value = aintc_read_4(SW_INT_ENABLE_REG(block)); value &= ~(1 << bit); aintc_write_4(SW_INT_ENABLE_REG(block), value); value = aintc_read_4(SW_INT_MASK_REG(block)); value |= (1 << bit); aintc_write_4(SW_INT_MASK_REG(block), value); }
static void a10_intr_mask(struct a10_aintc_softc *sc, u_int irq) { uint32_t bit, block, value; bit = (irq % 32); block = (irq / 32); mtx_lock_spin(&sc->mtx); value = aintc_read_4(sc, SW_INT_ENABLE_REG(block)); value &= ~(1 << bit); aintc_write_4(sc, SW_INT_ENABLE_REG(block), value); value = aintc_read_4(sc, SW_INT_MASK_REG(block)); value |= (1 << bit); aintc_write_4(sc, SW_INT_MASK_REG(block), value); mtx_unlock_spin(&sc->mtx); }
void arm_unmask_irq(uintptr_t nb) { uint32_t bit, block, value; bit = (nb % 32); block = (nb / 32); value = aintc_read_4(SW_INT_ENABLE_REG(block)); value |= (1 << bit); aintc_write_4(SW_INT_ENABLE_REG(block), value); value = aintc_read_4(SW_INT_MASK_REG(block)); value &= ~(1 << bit); aintc_write_4(SW_INT_MASK_REG(block), value); if(nb == SW_INT_IRQNO_ENMI) /* must clear pending bit when enabled */ aintc_write_4(SW_INT_IRQ_PENDING_REG(0), (1 << SW_INT_IRQNO_ENMI)); }
int arm_get_next_irq(int last_irq) { uint32_t value; int i, b; for (i = 0; i < 3; i++) { value = aintc_read_4(SW_INT_IRQ_PENDING_REG(i)); for (b = 0; b < 32; b++) if (value & (1 << b)) { return (i * 32 + b); } } return (-1); }
static int a10_pending_irq(struct a10_aintc_softc *sc) { uint32_t value; int i, b; for (i = 0; i < 3; i++) { value = aintc_read_4(sc, SW_INT_IRQ_PENDING_REG(i)); if (value == 0) continue; for (b = 0; b < 32; b++) if (value & (1 << b)) { return (i * 32 + b); } } return (-1); }
DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass, 0, 0); int arm_get_next_irq(int last_irq) { uint32_t active_irq; if (last_irq != -1) { aintc_write_4(INTC_ISR_CLEAR(last_irq >> 5), 1UL << (last_irq & 0x1F)); aintc_write_4(INTC_CONTROL,1); } /* Get the next active interrupt */ active_irq = aintc_read_4(INTC_SIR_IRQ); /* Check for spurious interrupt */ if ((active_irq & 0xffffff80)) { device_printf(ti_aintc_sc->sc_dev, "Spurious interrupt detected (0x%08x)\n", active_irq); aintc_write_4(INTC_SIR_IRQ, 0); return -1; } if (active_irq != last_irq) return active_irq; else return -1; }