static int mtk_pic_intr(void *arg) { struct mtk_pic_softc *sc = arg; struct thread *td; uint32_t i, intr; td = curthread; /* Workaround: do not inflate intr nesting level */ td->td_intr_nesting_level--; #ifdef _notyet_ intr = READ4(sc, MTK_IRQ1STAT); while ((i = fls(intr)) != 0) { i--; intr &= ~(1u << i); if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i), curthread->td_intr_frame) != 0) { device_printf(sc->pic_dev, "Stray interrupt %u detected\n", i); pic_irq_mask(sc, i); continue; } } KASSERT(i == 0, ("all interrupts handled")); #endif intr = READ4(sc, MTK_IRQ0STAT); while ((i = fls(intr)) != 0) { i--; intr &= ~(1u << i); if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i), curthread->td_intr_frame) != 0) { device_printf(sc->pic_dev, "Stray interrupt %u detected\n", i); pic_irq_mask(sc, i); continue; } } KASSERT(i == 0, ("all interrupts handled")); td->td_intr_nesting_level++; return (FILTER_HANDLED); }
static int mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, struct intr_irqsrc **isrcp) { int error; u_int irq; struct mtk_gpio_softc *sc; sc = device_get_softc(dev); switch (data->type) { case INTR_MAP_DATA_FDT: error = (mtk_gpio_pic_map_fdt(sc, (struct intr_map_data_fdt *)data, &irq, NULL)); break; case INTR_MAP_DATA_GPIO: error = (mtk_gpio_pic_map_gpio(sc, (struct intr_map_data_gpio *)data, &irq, NULL)); break; default: error = EINVAL; break; } if (error != 0) { device_printf(dev, "Invalid map type\n"); return (error); } *isrcp = PIC_INTR_ISRC(sc, irq); return (0); }
static int mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, struct intr_irqsrc **isrcp) { struct mtk_gpio_softc *sc; sc = device_get_softc(dev); if (data == NULL || data->type != INTR_MAP_DATA_FDT || data->fdt.ncells != 1 || data->fdt.cells[0] >= sc->num_pins) return (EINVAL); *isrcp = PIC_INTR_ISRC(sc, data->fdt.cells[0]); return (0); }
static int apb_filter(void *arg) { struct apb_softc *sc = arg; struct thread *td; uint32_t i, intr; td = curthread; /* Workaround: do not inflate intr nesting level */ td->td_intr_nesting_level--; if(ar531x_soc >= AR531X_SOC_AR5315) intr = ATH_READ_REG(AR5315_SYSREG_BASE + AR5315_SYSREG_MISC_INTSTAT); else intr = ATH_READ_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_MISC_INTSTAT); while ((i = fls(intr)) != 0) { i--; intr &= ~(1u << i); if(i == 1 && ar531x_soc < AR531X_SOC_AR5315) { ATH_READ_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_AHBPERR); ATH_READ_REG(AR5312_SYSREG_BASE + AR5312_SYSREG_AHBDMAE); } if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i), curthread->td_intr_frame) != 0) { device_printf(sc->apb_dev, "Stray interrupt %u detected\n", i); apb_mask_irq((void*)i); continue; } } KASSERT(i == 0, ("all interrupts handled")); td->td_intr_nesting_level++; return (FILTER_HANDLED); }
static int mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, struct intr_irqsrc **isrcp) { struct intr_map_data_fdt *daf; struct mtk_gpio_softc *sc; if (data->type != INTR_MAP_DATA_FDT) return (ENOTSUP); sc = device_get_softc(dev); daf = (struct intr_map_data_fdt *)data; if (daf->ncells != 1 || daf->cells[0] >= sc->num_pins) return (EINVAL); *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]); return (0); }
static int mtk_gpio_intr(void *arg) { struct mtk_gpio_softc *sc; uint32_t i, interrupts; sc = arg; interrupts = MTK_READ_4(sc, GPIO_PIOINT); for (i = 0; interrupts != 0; i++, interrupts >>= 1) { if ((interrupts & 0x1) == 0) continue; if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i), curthread->td_intr_frame) != 0) { device_printf(sc->dev, "spurious interrupt %d\n", i); } } return (FILTER_HANDLED); }
static int mtk_pic_register_isrcs(struct mtk_gpio_softc *sc) { int error; uint32_t irq; struct intr_irqsrc *isrc; const char *name; name = device_get_nameunit(sc->dev); for (irq = 0; irq < sc->num_pins; irq++) { sc->pins[irq].pin_irqsrc.irq = irq; isrc = PIC_INTR_ISRC(sc, irq); error = intr_isrc_register(isrc, sc->dev, 0, "%s", name); if (error != 0) { /* XXX call intr_isrc_deregister */ device_printf(sc->dev, "%s failed", __func__); return (error); } } return (0); }
static int apb_setup_intr(device_t bus, device_t child, struct resource *ires, int flags, driver_filter_t *filt, driver_intr_t *handler, void *arg, void **cookiep) { struct apb_softc *sc = device_get_softc(bus); int error; int irq; #ifndef INTRNG struct intr_event *event; #endif #ifdef INTRNG struct intr_irqsrc *isrc; const char *name; if ((rman_get_flags(ires) & RF_SHAREABLE) == 0) flags |= INTR_EXCL; irq = rman_get_start(ires); isrc = PIC_INTR_ISRC(sc, irq); if(isrc->isrc_event == 0) { error = intr_event_create(&isrc->isrc_event, (void *)irq, 0, irq, apb_mask_irq, apb_unmask_irq, NULL, NULL, "apb intr%d:", irq); if(error != 0) return(error); } name = device_get_nameunit(child); error = intr_event_add_handler(isrc->isrc_event, name, filt, handler, arg, intr_priority(flags), flags, cookiep); return(error); #else irq = rman_get_start(ires); if (irq > APB_IRQ_END) panic("%s: bad irq %d", __func__, irq); event = sc->sc_eventstab[irq]; if (event == NULL) { error = intr_event_create(&event, (void *)irq, 0, irq, apb_mask_irq, apb_unmask_irq, NULL, NULL, "apb intr%d:", irq); if (error == 0) { sc->sc_eventstab[irq] = event; sc->sc_intr_counter[irq] = mips_intrcnt_create(event->ie_name); } else return (error); } intr_event_add_handler(event, device_get_nameunit(child), filt, handler, arg, intr_priority(flags), flags, cookiep); mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname); apb_unmask_irq((void*)irq); return (0); #endif }