Index: sys/arm/allwinner/a10/a10_intc.c =================================================================== --- sys/arm/allwinner/a10/a10_intc.c +++ sys/arm/allwinner/a10/a10_intc.c @@ -255,6 +255,11 @@ const char *name; intptr_t xref; + xref = OF_xref_from_node(ofw_bus_get_node(sc->sc_dev)); + error = intr_pic_register(sc->sc_dev, xref, A10_INTR_MAX_NIRQS); + if (error != 0) + return (error); + name = device_get_nameunit(sc->sc_dev); for (irq = 0; irq < A10_INTR_MAX_NIRQS; irq++) { sc->isrcs[irq].irq = irq; @@ -265,11 +270,6 @@ return (error); } - xref = OF_xref_from_node(ofw_bus_get_node(sc->sc_dev)); - error = intr_pic_register(sc->sc_dev, xref); - if (error != 0) - return (error); - return (intr_pic_claim_root(sc->sc_dev, xref, a10_intr, sc, 0)); } Index: sys/arm/allwinner/aw_nmi.c =================================================================== --- sys/arm/allwinner/aw_nmi.c +++ sys/arm/allwinner/aw_nmi.c @@ -354,6 +354,12 @@ SC_NMI_WRITE(sc, NMI_IRQ_PENDING_REG, NMI_IRQ_ACK); xref = OF_xref_from_node(ofw_bus_get_node(dev)); + /* Register the PIC */ + if (intr_pic_register(dev, (intptr_t)xref, 1) != 0) { + device_printf(dev, "could not register pic\n"); + goto error; + } + /* Register our isrc */ sc->intr.irq = 0; sc->intr.pol = INTR_POLARITY_CONFORM; @@ -362,10 +368,6 @@ device_get_nameunit(sc->dev), sc->intr.irq) != 0) goto error; - if (intr_pic_register(dev, (intptr_t)xref) != 0) { - device_printf(dev, "could not register pic\n"); - goto error; - } return (0); error: Index: sys/arm/arm/gic.c =================================================================== --- sys/arm/arm/gic.c +++ sys/arm/arm/gic.c @@ -438,7 +438,7 @@ } static int -arm_gic_register_isrcs(struct arm_gic_softc *sc, uint32_t num) +arm_gic_register_isrcs(struct arm_gic_softc *sc) { int error; uint32_t irq; @@ -446,11 +446,11 @@ struct intr_irqsrc *isrc; const char *name; - irqs = malloc(num * sizeof(struct gic_irqsrc), M_DEVBUF, + irqs = malloc(sc->nirqs * sizeof(struct gic_irqsrc), M_DEVBUF, M_WAITOK | M_ZERO); name = device_get_nameunit(sc->gic_dev); - for (irq = 0; irq < num; irq++) { + for (irq = 0; irq < sc->nirqs; irq++) { irqs[irq].gi_irq = irq; irqs[irq].gi_pol = INTR_POLARITY_CONFORM; irqs[irq].gi_trig = INTR_TRIGGER_CONFORM; @@ -473,7 +473,6 @@ } } sc->gic_irqs = irqs; - sc->nirqs = num; return (0); } @@ -647,15 +646,9 @@ /* Get the number of interrupts */ sc->typer = gic_d_read_4(sc, GICD_TYPER); nirqs = 32 * ((sc->typer & 0x1f) + 1); - -#ifdef INTRNG - if (arm_gic_register_isrcs(sc, nirqs)) { - device_printf(dev, "could not register irqs\n"); - goto cleanup; - } -#else sc->nirqs = nirqs; +#ifndef INTRNG /* Set up function pointers */ arm_post_filter = gic_post_filter; arm_config_irq = gic_config_irq; @@ -711,12 +704,20 @@ * Now, when everything is initialized, it's right time to * register interrupt controller to interrupt framefork. */ - if (intr_pic_register(dev, xref) != 0) { + if (intr_pic_register(dev, xref, sc->nirqs) != 0) { device_printf(dev, "could not register PIC\n"); goto cleanup; } /* + * Register the isrcs for this PIC. + */ + if (arm_gic_register_isrcs(sc)) { + device_printf(dev, "could not register irqs\n"); + goto cleanup; + } + + /* * Controller is root if: * - doesn't have interrupt parent * - his interrupt parent is this controller Index: sys/arm/broadcom/bcm2835/bcm2835_gpio.c =================================================================== --- sys/arm/broadcom/bcm2835/bcm2835_gpio.c +++ sys/arm/broadcom/bcm2835/bcm2835_gpio.c @@ -1034,6 +1034,11 @@ uint32_t irq; const char *name; + error = intr_pic_register(sc->sc_dev, + OF_xref_from_node(ofw_bus_get_node(sc->sc_dev)), BCM_GPIO_PINS); + if (error != 0) + return (error); + name = device_get_nameunit(sc->sc_dev); for (irq = 0; irq < BCM_GPIO_PINS; irq++) { sc->sc_isrcs[irq].bgi_irq = irq; @@ -1045,8 +1050,8 @@ if (error != 0) return (error); /* XXX deregister ISRCs */ } - return (intr_pic_register(sc->sc_dev, - OF_xref_from_node(ofw_bus_get_node(sc->sc_dev)))); + + return (0); } static int Index: sys/arm/broadcom/bcm2835/bcm2835_intr.c =================================================================== --- sys/arm/broadcom/bcm2835/bcm2835_intr.c +++ sys/arm/broadcom/bcm2835/bcm2835_intr.c @@ -317,6 +317,10 @@ uint32_t irq; const char *name; + error = intr_pic_register(sc->sc_dev, xref, BCM_INTC_NIRQS); + if (error != 0) + return (error); + name = device_get_nameunit(sc->sc_dev); for (irq = 0; irq < BCM_INTC_NIRQS; irq++) { bii = &sc->intc_isrcs[irq]; @@ -341,7 +345,8 @@ if (error != 0) return (error); } - return (intr_pic_register(sc->sc_dev, xref)); + + return (0); } #endif Index: sys/arm/broadcom/bcm2835/bcm2836.c =================================================================== --- sys/arm/broadcom/bcm2835/bcm2836.c +++ sys/arm/broadcom/bcm2835/bcm2836.c @@ -604,6 +604,11 @@ const char *name; intptr_t xref; + xref = OF_xref_from_node(ofw_bus_get_node(sc->bls_dev)); + error = intr_pic_register(sc->bls_dev, xref, BCM_LINTC_NIRQS); + if (error != 0) + return (error); + bisrcs = sc->bls_isrcs; name = device_get_nameunit(sc->bls_dev); for (irq = 0; irq < BCM_LINTC_NIRQS; irq++) { @@ -652,11 +657,6 @@ return (error); } - xref = OF_xref_from_node(ofw_bus_get_node(sc->bls_dev)); - error = intr_pic_register(sc->bls_dev, xref); - if (error != 0) - return (error); - return (intr_pic_claim_root(sc->bls_dev, xref, bcm_lintc_intr, sc, 0)); } Index: sys/arm/freescale/imx/imx_gpio.c =================================================================== --- sys/arm/freescale/imx/imx_gpio.c +++ sys/arm/freescale/imx/imx_gpio.c @@ -680,8 +680,9 @@ } #ifdef INTRNG + intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)), + sc->gpio_npins); gpio_pic_register_isrcs(sc); - intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev))); #endif sc->sc_busdev = gpiobus_attach_bus(dev); Index: sys/arm/mv/mpic.c =================================================================== --- sys/arm/mv/mpic.c +++ sys/arm/mv/mpic.c @@ -269,13 +269,13 @@ sc->nirqs = MPIC_CTRL_NIRQS(val); #ifdef INTRNG - if (mv_mpic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register PIC ISRCs\n"); + if (intr_pic_register(dev, OF_xref_from_device(dev), sc->nirqs) != 0) { + device_printf(dev, "could not register PIC\n"); bus_release_resources(dev, mv_mpic_spec, sc->mpic_res); return (ENXIO); } - if (intr_pic_register(dev, OF_xref_from_device(dev)) != 0) { - device_printf(dev, "could not register PIC\n"); + if (mv_mpic_register_isrcs(sc) != 0) { + device_printf(dev, "could not register PIC ISRCs\n"); bus_release_resources(dev, mv_mpic_spec, sc->mpic_res); return (ENXIO); } Index: sys/arm/nvidia/tegra_gpio.c =================================================================== --- sys/arm/nvidia/tegra_gpio.c +++ sys/arm/nvidia/tegra_gpio.c @@ -440,6 +440,11 @@ uint32_t irq; const char *name; + error = intr_pic_register(sc->dev, + OF_xref_from_node(ofw_bus_get_node(sc->dev)), sc->gpio_npins); + if (error != 0) + return (error); + sc->isrcs = malloc(sizeof(*sc->isrcs) * sc->gpio_npins, M_DEVBUF, M_WAITOK | M_ZERO); @@ -452,8 +457,8 @@ if (error != 0) return (error); /* XXX deregister ISRCs */ } - return (intr_pic_register(sc->dev, - OF_xref_from_node(ofw_bus_get_node(sc->dev)))); + + return (error); } static int Index: sys/arm/nvidia/tegra_lic.c =================================================================== --- sys/arm/nvidia/tegra_lic.c +++ sys/arm/nvidia/tegra_lic.c @@ -233,7 +233,7 @@ } - if (intr_pic_register(dev, OF_xref_from_node(node)) != 0) { + if (intr_pic_register(dev, OF_xref_from_node(node), 0) != 0) { device_printf(dev, "Cannot register PIC\n"); goto fail; } Index: sys/arm/ti/aintc.c =================================================================== --- sys/arm/ti/aintc.c +++ sys/arm/ti/aintc.c @@ -225,6 +225,11 @@ const char *name; intptr_t xref; + xref = OF_xref_from_node(ofw_bus_get_node(sc->sc_dev)); + error = intr_pic_register(sc->sc_dev, xref, INTC_NIRQS); + if (error != 0) + return (error); + name = device_get_nameunit(sc->sc_dev); for (irq = 0; irq < INTC_NIRQS; irq++) { sc->aintc_isrcs[irq].tai_irq = irq; @@ -235,11 +240,6 @@ return (error); } - xref = OF_xref_from_node(ofw_bus_get_node(sc->sc_dev)); - error = intr_pic_register(sc->sc_dev, xref); - if (error != 0) - return (error); - return (intr_pic_claim_root(sc->sc_dev, xref, ti_aintc_intr, sc, 0)); } Index: sys/arm/ti/omap4/omap4_wugen.c =================================================================== --- sys/arm/ti/omap4/omap4_wugen.c +++ sys/arm/ti/omap4/omap4_wugen.c @@ -210,7 +210,7 @@ return (ENXIO); } - if (intr_pic_register(dev, OF_xref_from_node(node)) != 0) { + if (intr_pic_register(dev, OF_xref_from_node(node), 0) != 0) { device_printf(dev, "can't register PIC\n"); goto fail; } Index: sys/arm/ti/ti_gpio.c =================================================================== --- sys/arm/ti/ti_gpio.c +++ sys/arm/ti/ti_gpio.c @@ -890,6 +890,11 @@ uint32_t irq; const char *name; + error = intr_pic_register(sc->sc_dev, + OF_xref_from_node(ofw_bus_get_node(sc->sc_dev)), sc->sc_maxpin); + if (error != 0) + return (error); + sc->sc_isrcs = malloc(sizeof(*sc->sc_isrcs) * sc->sc_maxpin, M_DEVBUF, M_WAITOK | M_ZERO); @@ -904,8 +909,8 @@ if (error != 0) return (error); /* XXX deregister ISRCs */ } - return (intr_pic_register(sc->sc_dev, - OF_xref_from_node(ofw_bus_get_node(sc->sc_dev)))); + + return (0); } static int Index: sys/arm64/arm64/gic_v3.c =================================================================== --- sys/arm64/arm64/gic_v3.c +++ sys/arm64/arm64/gic_v3.c @@ -183,7 +183,7 @@ * Device interface. */ int -gic_v3_attach(device_t dev) +gic_v3_attach(device_t dev, intptr_t xref) { struct gic_v3_softc *sc; gic_v3_initseq_t *init_func; @@ -244,6 +244,12 @@ sc->gic_nirqs = GIC_I_NUM_MAX; #ifdef INTRNG + err = intr_pic_register(dev, xref, sc->gic_nirqs); + if (err != 0) { + device_printf(dev, "could not register PIC\n"); + return (err); + } + sc->gic_irqs = malloc(sizeof(*sc->gic_irqs) * sc->gic_nirqs, M_GIC_V3, M_WAITOK | M_ZERO); name = device_get_nameunit(dev); Index: sys/arm64/arm64/gic_v3_fdt.c =================================================================== --- sys/arm64/arm64/gic_v3_fdt.c +++ sys/arm64/arm64/gic_v3_fdt.c @@ -116,9 +116,7 @@ { struct gic_v3_softc *sc; pcell_t redist_regions; -#ifdef INTRNG intptr_t xref; -#endif int err; sc = device_get_softc(dev); @@ -133,17 +131,12 @@ else sc->gic_redists.nregions = redist_regions; - err = gic_v3_attach(dev); + xref = OF_xref_from_node(ofw_bus_get_node(dev)); + err = gic_v3_attach(dev, xref); if (err != 0) goto error; #ifdef INTRNG - xref = OF_xref_from_node(ofw_bus_get_node(dev)); - if (intr_pic_register(dev, xref) != 0) { - device_printf(dev, "could not register PIC\n"); - goto error; - } - if (intr_pic_claim_root(dev, xref, arm_gic_v3_intr, sc, GIC_LAST_SGI - GIC_FIRST_SGI + 1) != 0) { goto error; Index: sys/arm64/arm64/gic_v3_var.h =================================================================== --- sys/arm64/arm64/gic_v3_var.h +++ sys/arm64/arm64/gic_v3_var.h @@ -97,7 +97,7 @@ MALLOC_DECLARE(M_GIC_V3); /* Device methods */ -int gic_v3_attach(device_t dev); +int gic_v3_attach(device_t dev, intptr_t); int gic_v3_detach(device_t dev); int arm_gic_v3_intr(void *); Index: sys/kern/subr_intr.c =================================================================== --- sys/kern/subr_intr.c +++ sys/kern/subr_intr.c @@ -101,17 +101,20 @@ #define FLAG_PIC (1 << 0) #define FLAG_MSI (1 << 1) u_int pic_flags; + u_int pic_irq_base; + u_int pic_irq_next; + u_int pic_irq_count; + struct intr_irqsrc ** pic_sources; }; static struct mtx pic_list_lock; static SLIST_HEAD(, intr_pic) pic_list; +static u_int pic_next_irq_base; static struct intr_pic *pic_lookup(device_t dev, intptr_t xref); /* Interrupt source definition. */ static struct mtx isrc_table_lock; -static struct intr_irqsrc *irq_sources[NIRQ]; -u_int irq_next_free; /* * XXX - All stuff around struct intr_dev_data is considered as temporary @@ -140,7 +143,6 @@ static u_int intr_ddata_first_unused; #define IRQ_DDATA_BASE 10000 -CTASSERT(IRQ_DDATA_BASE > nitems(irq_sources)); #ifdef SMP static boolean_t irq_assign_cpu = FALSE; @@ -355,35 +357,35 @@ * constantly... */ static inline int -isrc_alloc_irq(struct intr_irqsrc *isrc) +isrc_alloc_irq(struct intr_pic *pic, struct intr_irqsrc *isrc) { u_int maxirqs, irq; mtx_assert(&isrc_table_lock, MA_OWNED); - maxirqs = nitems(irq_sources); - if (irq_next_free >= maxirqs) + maxirqs = pic->pic_irq_base + pic->pic_irq_count; + if (pic->pic_irq_next >= maxirqs) return (ENOSPC); - for (irq = irq_next_free; irq < maxirqs; irq++) { - if (irq_sources[irq] == NULL) + for (irq = pic->pic_irq_next; irq < maxirqs; irq++) { + if (pic->pic_sources[irq] == NULL) goto found; } - for (irq = 0; irq < irq_next_free; irq++) { - if (irq_sources[irq] == NULL) + for (irq = pic->pic_irq_base; irq < pic->pic_irq_next; irq++) { + if (pic->pic_sources[irq] == NULL) goto found; } - irq_next_free = maxirqs; + pic->pic_irq_next = maxirqs; return (ENOSPC); found: isrc->isrc_irq = irq; - irq_sources[irq] = isrc; + pic->pic_sources[irq - pic->pic_irq_base] = isrc; - irq_next_free = irq + 1; - if (irq_next_free >= maxirqs) - irq_next_free = 0; + pic->pic_irq_next = irq + 1; + if (pic->pic_irq_next >= maxirqs) + pic->pic_irq_next = pic->pic_irq_base; return (0); } @@ -391,17 +393,19 @@ * Free unique interrupt number (resource handle) from interrupt source. */ static inline int -isrc_free_irq(struct intr_irqsrc *isrc) +isrc_free_irq(struct intr_pic *pic, struct intr_irqsrc *isrc) { + u_int irq; mtx_assert(&isrc_table_lock, MA_OWNED); - if (isrc->isrc_irq >= nitems(irq_sources)) + irq = isrc->isrc_irq - pic->pic_irq_base; + if (irq > pic->pic_irq_count) return (EINVAL); - if (irq_sources[isrc->isrc_irq] != isrc) + if (pic->pic_sources[irq] != isrc) return (EINVAL); - irq_sources[isrc->isrc_irq] = NULL; + pic->pic_sources[irq] = NULL; isrc->isrc_irq = INTR_IRQ_INVALID; /* just to be safe */ return (0); } @@ -412,9 +416,13 @@ static inline struct intr_irqsrc * isrc_lookup(u_int irq) { + struct intr_pic *pic; + + SLIST_FOREACH(pic, &pic_list, pic_next) { + if (irq >= pic->pic_irq_base && irq < pic->pic_irq_count) + return (pic->pic_sources[irq - pic->pic_irq_base]); + } - if (irq < nitems(irq_sources)) - return (irq_sources[irq]); return (NULL); } @@ -425,9 +433,14 @@ intr_isrc_register(struct intr_irqsrc *isrc, device_t dev, u_int flags, const char *fmt, ...) { + struct intr_pic *pic; int error; va_list ap; + pic = pic_lookup(dev, 0); + /* This can only happen if the pic disappears somehow */ + KASSERT(pic != NULL, ("%s: Unable to find isrc pic", __func__)); + bzero(isrc, sizeof(struct intr_irqsrc)); isrc->isrc_dev = dev; isrc->isrc_irq = INTR_IRQ_INVALID; /* just to be safe */ @@ -438,7 +451,7 @@ va_end(ap); mtx_lock(&isrc_table_lock); - error = isrc_alloc_irq(isrc); + error = isrc_alloc_irq(pic, isrc); if (error != 0) { mtx_unlock(&isrc_table_lock); return (error); @@ -460,12 +473,17 @@ int intr_isrc_deregister(struct intr_irqsrc *isrc) { + struct intr_pic *pic; int error; + pic = pic_lookup(isrc->isrc_dev, 0); + /* This can only happen if the pic disappears somehow */ + KASSERT(pic != NULL, ("%s: Unable to find isrc pic", __func__)); + mtx_lock(&isrc_table_lock); if ((isrc->isrc_flags & INTR_ISRCF_IPI) == 0) isrc_release_counters(isrc); - error = isrc_free_irq(isrc); + error = isrc_free_irq(pic, isrc); mtx_unlock(&isrc_table_lock); return (error); } @@ -912,7 +930,7 @@ * Register interrupt controller. */ int -intr_pic_register(device_t dev, intptr_t xref) +intr_pic_register(device_t dev, intptr_t xref, u_int count) { struct intr_pic *pic; @@ -922,6 +940,19 @@ if (pic == NULL) return (ENOMEM); + if (count > 0) + pic->pic_sources = malloc(sizeof(*pic->pic_sources) * count, + M_INTRNG, M_WAITOK | M_ZERO); + pic->pic_irq_base = atomic_fetchadd_int(&pic_next_irq_base, count); + pic->pic_irq_next = pic->pic_irq_base; + pic->pic_irq_count = count; + + KASSERT((pic->pic_irq_base + count) < IRQ_DDATA_BASE, + ("%s: PIC %s is attempting to handle device data irqs, " + "base: %u count: %u", __func__, device_get_nameunit(dev), + pic->pic_irq_base, count)); + + pic->pic_flags |= FLAG_PIC; debugf("PIC %p registered for %s \n", pic, @@ -992,6 +1023,24 @@ } int +intr_pic_intr_count(device_t dev, u_int *count) +{ + struct intr_pic *pic; + + pic = pic_lookup(dev, 0); + if (pic == NULL) + return (ESRCH); + + KASSERT((pic->pic_flags & FLAG_PIC) != 0, + ("%s: Found a non-PIC controller: %s", __func__, + device_get_name(pic->pic_dev))); + + *count = pic->pic_irq_count; + + return (0); +} + +int intr_map_irq(device_t dev, intptr_t xref, struct intr_map_data *data, u_int *irqp) { @@ -1227,23 +1276,16 @@ return (last_cpu); } -/* - * Distribute all the interrupt sources among the available - * CPUs once the AP's have been launched. - */ static void -intr_irq_shuffle(void *arg __unused) +intr_irq_shuffle_pic(struct intr_pic *pic) { struct intr_irqsrc *isrc; u_int i; - if (mp_ncpus == 1) - return; + mtx_assert(&isrc_table_lock, MA_OWNED); - mtx_lock(&isrc_table_lock); - irq_assign_cpu = TRUE; - for (i = 0; i < NIRQ; i++) { - isrc = irq_sources[i]; + for (i = 0; i < pic->pic_irq_count; i++) { + isrc = pic->pic_sources[i]; if (isrc == NULL || isrc->isrc_handlers == 0 || isrc->isrc_flags & (INTR_ISRCF_PPI | INTR_ISRCF_IPI)) continue; @@ -1264,6 +1306,26 @@ if (PIC_BIND_INTR(isrc->isrc_dev, isrc) != 0) CPU_ZERO(&isrc->isrc_cpu); } +} + +/* + * Distribute all the interrupt sources among the available + * CPUs once the AP's have been launched. + */ +static void +intr_irq_shuffle(void *arg __unused) +{ + struct intr_pic *pic; + + if (mp_ncpus == 1) + return; + + mtx_lock(&isrc_table_lock); + irq_assign_cpu = TRUE; + + SLIST_FOREACH(pic, &pic_list, pic_next) { + intr_irq_shuffle_pic(pic); + } mtx_unlock(&isrc_table_lock); } SYSINIT(intr_irq_shuffle, SI_SUB_SMP, SI_ORDER_SECOND, intr_irq_shuffle, NULL); @@ -1459,20 +1521,27 @@ #ifdef DDB DB_SHOW_COMMAND(irqs, db_show_irqs) { + struct intr_pic *pic; u_int i, irqsum; u_long num; struct intr_irqsrc *isrc; - for (irqsum = 0, i = 0; i < NIRQ; i++) { - isrc = irq_sources[i]; - if (isrc == NULL) - continue; - - num = isrc->isrc_count != NULL ? isrc->isrc_count[0] : 0; - db_printf("irq%-3u <%s>: cpu %02lx%s cnt %lu\n", i, - isrc->isrc_name, isrc->isrc_cpu.__bits[0], - isrc->isrc_flags & INTR_ISRCF_BOUND ? " (bound)" : "", num); - irqsum += num; + irqsum = 0; + SLIST_FOREACH(pic, &pic_list, pic_next) { + for (i = 0; i < pic->pic_irq_count; i++) { + isrc = pic->pic_sources[i]; + if (isrc == NULL) + continue; + + num = + isrc->isrc_count != NULL ? isrc->isrc_count[0] : 0; + db_printf("irq%-3u <%s>: cpu %02lx%s cnt %lu\n", + isrc->isrc_irq, isrc->isrc_name, + isrc->isrc_cpu.__bits[0], + isrc->isrc_flags & INTR_ISRCF_BOUND ? + " (bound)" : "", num); + irqsum += num; + } } db_printf("irq total %u\n", irqsum); } Index: sys/mips/mediatek/mtk_gpio_v1.c =================================================================== --- sys/mips/mediatek/mtk_gpio_v1.c +++ sys/mips/mediatek/mtk_gpio_v1.c @@ -303,13 +303,13 @@ mtk_gpio_pin_probe(sc, i); } - if (mtk_pic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register PIC ISRCs\n"); + if (intr_pic_register(dev, OF_xref_from_node(node), sc->num_pins) != 0){ + device_printf(dev, "could not register PIC\n"); goto fail; } - if (intr_pic_register(dev, OF_xref_from_node(node)) != 0) { - device_printf(dev, "could not register PIC\n"); + if (mtk_pic_register_isrcs(sc) != 0) { + device_printf(dev, "could not register PIC ISRCs\n"); goto fail; } Index: sys/mips/mediatek/mtk_gpio_v2.c =================================================================== --- sys/mips/mediatek/mtk_gpio_v2.c +++ sys/mips/mediatek/mtk_gpio_v2.c @@ -294,13 +294,13 @@ mtk_gpio_pin_probe(sc, i); } - if (mtk_pic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register PIC ISRCs\n"); + if (intr_pic_register(dev, OF_xref_from_node(node), sc->num_pins) != 0){ + device_printf(dev, "could not register PIC\n"); goto fail; } - if (intr_pic_register(dev, OF_xref_from_node(node)) != 0) { - device_printf(dev, "could not register PIC\n"); + if (mtk_pic_register_isrcs(sc) != 0) { + device_printf(dev, "could not register PIC ISRCs\n"); goto fail; } Index: sys/mips/mediatek/mtk_intr_gic.c =================================================================== --- sys/mips/mediatek/mtk_intr_gic.c +++ sys/mips/mediatek/mtk_intr_gic.c @@ -203,21 +203,21 @@ WRITE4(sc, MTK_MAPVPE(i, 0), MTK_VPE_BITS(0)); } - /* Register the interrupts */ - if (mtk_gic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register GIC ISRCs\n"); - goto cleanup; - } - /* * Now, when everything is initialized, it's right time to * register interrupt controller to interrupt framefork. */ - if (intr_pic_register(dev, xref) != 0) { + if (intr_pic_register(dev, xref, sc->nirqs) != 0) { device_printf(dev, "could not register PIC\n"); goto cleanup; } + /* Register the interrupts */ + if (mtk_gic_register_isrcs(sc) != 0) { + device_printf(dev, "could not register GIC ISRCs\n"); + goto cleanup; + } + cpu_establish_hardintr("gic", mtk_gic_intr, NULL, sc, 0, INTR_TYPE_CLK, NULL); Index: sys/mips/mediatek/mtk_intr_v1.c =================================================================== --- sys/mips/mediatek/mtk_intr_v1.c +++ sys/mips/mediatek/mtk_intr_v1.c @@ -191,21 +191,21 @@ /* Set all interrupts to type 0 */ WRITE4(sc, MTK_INTTYPE, 0x00000000); - /* Register the interrupts */ - if (mtk_pic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register PIC ISRCs\n"); - goto cleanup; - } - /* * Now, when everything is initialized, it's right time to * register interrupt controller to interrupt framefork. */ - if (intr_pic_register(dev, xref) != 0) { + if (intr_pic_register(dev, xref, sc->nirqs, sc->nirqs) != 0) { device_printf(dev, "could not register PIC\n"); goto cleanup; } + /* Register the interrupts */ + if (mtk_pic_register_isrcs(sc) != 0) { + device_printf(dev, "could not register PIC ISRCs\n"); + goto cleanup; + } + if (bus_setup_intr(dev, sc->pic_res[1], INTR_TYPE_CLK, mtk_pic_intr, NULL, sc, &sc->pic_intrhand)) { device_printf(dev, "could not setup irq handler\n"); Index: sys/mips/mediatek/mtk_intr_v2.c =================================================================== --- sys/mips/mediatek/mtk_intr_v2.c +++ sys/mips/mediatek/mtk_intr_v2.c @@ -186,21 +186,21 @@ /* Set all interrupts to type 0 */ WRITE4(sc, MTK_INTTYPE, 0xFFFFFFFF); - /* Register the interrupts */ - if (mtk_pic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register PIC ISRCs\n"); - goto cleanup; - } - /* * Now, when everything is initialized, it's right time to * register interrupt controller to interrupt framefork. */ - if (intr_pic_register(dev, xref) != 0) { + if (intr_pic_register(dev, xref, sc->nirqs) != 0) { device_printf(dev, "could not register PIC\n"); goto cleanup; } + /* Register the interrupts */ + if (mtk_pic_register_isrcs(sc) != 0) { + device_printf(dev, "could not register PIC ISRCs\n"); + goto cleanup; + } + if (bus_setup_intr(dev, sc->pic_res[1], INTR_TYPE_CLK, mtk_pic_intr, NULL, sc, &sc->pic_intrhand)) { device_printf(dev, "could not setup irq handler\n"); Index: sys/mips/mediatek/mtk_pcie.c =================================================================== --- sys/mips/mediatek/mtk_pcie.c +++ sys/mips/mediatek/mtk_pcie.c @@ -319,7 +319,7 @@ } /* Register ourselves as an interrupt controller */ - if (intr_pic_register(dev, xref) != 0) { + if (intr_pic_register(dev, xref, sc->sc_num_irq) != 0) { device_printf(dev, "could not register PIC\n"); goto cleanup_rman; } Index: sys/mips/mips/mips_pic.c =================================================================== --- sys/mips/mips/mips_pic.c +++ sys/mips/mips/mips_pic.c @@ -213,21 +213,21 @@ goto cleanup; } - /* Register the interrupts */ - if (mips_pic_register_isrcs(sc) != 0) { - device_printf(dev, "could not register PIC ISRCs\n"); - goto cleanup; - } - /* * Now, when everything is initialized, it's right time to * register interrupt controller to interrupt framefork. */ - if (intr_pic_register(dev, xref) != 0) { + if (intr_pic_register(dev, xref, NREAL_IRQS) != 0) { device_printf(dev, "could not register PIC\n"); goto cleanup; } + /* Register the interrupts */ + if (mips_pic_register_isrcs(sc) != 0) { + device_printf(dev, "could not register PIC ISRCs\n"); + goto cleanup; + } + /* Claim our root controller role */ if (intr_pic_claim_root(dev, xref, mips_pic_intr, sc, 0) != 0) { device_printf(dev, "could not set PIC as a root\n"); Index: sys/sys/intr.h =================================================================== --- sys/sys/intr.h +++ sys/sys/intr.h @@ -110,9 +110,10 @@ int intr_isrc_dispatch(struct intr_irqsrc *, struct trapframe *); u_int intr_irq_next_cpu(u_int current_cpu, cpuset_t *cpumask); -int intr_pic_register(device_t, intptr_t); +int intr_pic_register(device_t, intptr_t, u_int); int intr_pic_deregister(device_t, intptr_t); int intr_pic_claim_root(device_t, intptr_t, intr_irq_filter_t *, void *, u_int); +int intr_pic_intr_count(device_t, u_int *); extern device_t intr_irq_root_dev;