/* * Deregister an interrupt handler. */ void sa11x0_intr_disestablish(sa11x0_chipset_tag_t ic, void *arg) { struct irqhandler *ih = arg; int irq = ih->ih_irq; int saved_cpsr; struct irqhandler **p, *q; #if DIAGNOSTIC if (irq < 0 || irq >= ICU_LEN) panic("intr_disestablish: bogus irq"); #endif /* * Remove the handler from the chain. * This is O(n^2), too. */ for (p = &irqhandlers[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next) ; if (q) *p = q->ih_next; else panic("intr_disestablish: handler not registered"); free(ih, M_DEVBUF); intr_calculatemasks(); saved_cpsr = SetCPSR(I32_bit, I32_bit); set_spl_masks(); irq_setmasks(); SetCPSR(I32_bit, saved_cpsr & I32_bit); }
void * sa11x0_intr_establish(sa11x0_chipset_tag_t ic, int irq, int type, int level, int (*ih_fun)(void *), void *ih_arg) { int saved_cpsr; struct irqhandler **p, *q, *ih; static struct irqhandler fakehand = {fakeintr}; /* no point in sleeping unless someone can free memory. */ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); if (ih == NULL) panic("sa11x0_intr_establish: can't malloc handler info"); if (irq < 0 || irq >= ICU_LEN || type == IST_NONE) panic("intr_establish: bogus irq or type"); /* All interrupts are level intrs. */ /* * Figure out where to put the handler. * This is O(N^2), but we want to preserve the order, and N is * generally small. */ for (p = &irqhandlers[irq]; (q = *p) != NULL; p = &q->ih_next) ; /* * Actually install a fake handler momentarily, since we might be doing * this with interrupts enabled and don't want the real routine called * until masking is set up. */ fakehand.ih_level = level; *p = &fakehand; intr_calculatemasks(); /* * Poke the real handler in now. */ ih->ih_func = ih_fun; ih->ih_arg = ih_arg; ih->ih_count = 0; ih->ih_next = NULL; ih->ih_level = level; ih->ih_irq = irq; ih->ih_name = NULL; /* XXX */ *p = ih; saved_cpsr = SetCPSR(I32_bit, I32_bit); set_spl_masks(); irq_setmasks(); SetCPSR(I32_bit, saved_cpsr & I32_bit); #ifdef DEBUG dumpirqhandlers(); #endif return (ih); }
static int sa1110_setup_intr(device_t dev, device_t child, struct resource *ires, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { int saved_cpsr; if (flags & INTR_TYPE_TTY) rman_set_start(ires, 15); else if (flags & INTR_TYPE_CLK) { if (rman_get_start(ires) == 0) rman_set_start(ires, 26); else rman_set_start(ires, 27); } saved_cpsr = SetCPSR(I32_bit, I32_bit); SetCPSR(I32_bit, saved_cpsr & I32_bit); BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt, intr, arg, cookiep); return (0); }
int sa11x0_attach(device_t dev) { struct sa11x0_softc *sc = device_get_softc(dev); int unit = device_get_unit(dev); sc->sc_iot = &sa11x0_bs_tag; sa11x0_softc = sc; /* Map the SAIP */ if (bus_space_map(sc->sc_iot, SAIPIC_BASE, SAIPIC_NPORTS, 0, &sc->sc_ioh)) panic("saip%d: Cannot map registers", unit); saipic_base = sc->sc_ioh; /* Map the GPIO registers */ if (bus_space_map(sc->sc_iot, SAGPIO_BASE, SAGPIO_NPORTS, 0, &sc->sc_gpioh)) panic("saip%d: unable to map GPIO registers", unit); bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_EDR, 0xffffffff); /* Map the PPC registers */ if (bus_space_map(sc->sc_iot, SAPPC_BASE, SAPPC_NPORTS, 0, &sc->sc_ppch)) panic("saip%d: unable to map PPC registers", unit); #if 0 /* Map the DMA controller registers */ if (bus_space_map(sc->sc_iot, SADMAC_BASE, SADMAC_NPORTS, 0, &sc->sc_dmach)) panic("saip%d: unable to map DMAC registers", unit); #endif /* Map the reset controller registers */ if (bus_space_map(sc->sc_iot, SARCR_BASE, PAGE_SIZE, 0, &sc->sc_reseth)) panic("saip%d: unable to map reset registers", unit); printf("\n"); /* * Mask all interrupts. * They are later unmasked at each device's attach routine. */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SAIPIC_MR, 0); /* Route all bits to IRQ */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SAIPIC_LR, 0); /* Exit idle mode only when unmasked intr is received */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SAIPIC_CR, 1); #if 0 /* disable all DMAC channels */ bus_space_write_4(sc->sc_iot, sc->sc_dmach, SADMAC_DCR0_CLR, 1); bus_space_write_4(sc->sc_iot, sc->sc_dmach, SADMAC_DCR1_CLR, 1); bus_space_write_4(sc->sc_iot, sc->sc_dmach, SADMAC_DCR2_CLR, 1); bus_space_write_4(sc->sc_iot, sc->sc_dmach, SADMAC_DCR3_CLR, 1); bus_space_write_4(sc->sc_iot, sc->sc_dmach, SADMAC_DCR4_CLR, 1); bus_space_write_4(sc->sc_iot, sc->sc_dmach, SADMAC_DCR5_CLR, 1); #endif /* * XXX this is probably a bad place, but intr bit shouldn't be * XXX enabled before intr mask is set. * XXX Having sane imask[] suffice?? */ #if 0 SetCPSR(I32_bit, 0); #endif /* * Attach each devices */ sc->sa11x0_rman.rm_type = RMAN_ARRAY; sc->sa11x0_rman.rm_descr = "SA11x0 IRQs"; if (rman_init(&sc->sa11x0_rman) != 0 || rman_manage_region(&sc->sa11x0_rman, 0, 32) != 0) panic("sa11x0_attach: failed to set up rman"); device_add_child(dev, "uart", 0); device_add_child(dev, "saost", 0); bus_generic_probe(dev); bus_generic_attach(dev); sa11x0_activateirqs(); return (0); }