Index: sys/arm/mv/mv_ap806_gicp.c =================================================================== --- sys/arm/mv/mv_ap806_gicp.c +++ sys/arm/mv/mv_ap806_gicp.c @@ -395,8 +395,8 @@ for (i = 0; i < count; i++) { BIT_SET(sc->msi_bitmap_size, - mv_ap806_gicp_irq_to_msi(sc, srcs[i]->isrc_irq), - sc->msi_bitmap); + mv_ap806_gicp_irq_to_msi(sc, + rman_get_start(srcs[i]->isrc_irq)), sc->msi_bitmap); } return (0); @@ -411,7 +411,7 @@ sc = device_get_softc(dev); *addr = rman_get_start(sc->res); - *data = mv_ap806_gicp_irq_to_msi(sc, isrc->isrc_irq); + *data = mv_ap806_gicp_irq_to_msi(sc, rman_get_start(isrc->isrc_irq)); return (0); } Index: sys/arm/mv/mv_ap806_sei.c =================================================================== --- sys/arm/mv/mv_ap806_sei.c +++ sys/arm/mv/mv_ap806_sei.c @@ -453,7 +453,7 @@ for (i = 0; i < count; i++) { BIT_SET(MV_AP806_SEI_CP_SIZE, - srcs[i]->isrc_irq - MV_AP806_SEI_CP_FIRST, + rman_get_start(srcs[i]->isrc_irq) - MV_AP806_SEI_CP_FIRST, &sc->msi_bitmap); } @@ -469,7 +469,7 @@ sc = device_get_softc(dev); *addr = rman_get_start(sc->mem_res) + MV_AP806_SEI_SETSPI_OFFSET; - *data = isrc->isrc_irq; + *data = rman_get_start(isrc->isrc_irq); return (0); } Index: sys/kern/subr_intr.c =================================================================== --- sys/kern/subr_intr.c +++ sys/kern/subr_intr.c @@ -133,7 +133,7 @@ /* Interrupt source definition. */ static struct mtx isrc_table_lock; static struct intr_irqsrc **irq_sources; -u_int irq_next_free; +static struct rman intr_avail; #ifdef SMP #ifdef EARLY_AP_STARTUP @@ -190,6 +190,14 @@ sintrnames = intrcnt_count * INTRNAME_LEN; irq_sources = mallocarray(intr_nirq, sizeof(struct intr_irqsrc*), M_INTRNG, M_WAITOK | M_ZERO); + + intr_avail.rm_start = 0; + intr_avail.rm_end = intr_nirq - 1; + intr_avail.rm_type = RMAN_ARRAY; + intr_avail.rm_descr = "INTRNG available interrupts"; + if (rman_init(&intr_avail) || + rman_manage_region(&intr_avail, 0, intr_nirq - 1)) + panic("%s(): failure initializing free rman", __func__); } SYSINIT(intr_irq_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_irq_init, NULL); @@ -401,32 +409,20 @@ static inline int isrc_alloc_irq(struct intr_irqsrc *isrc) { - u_int irq; + struct resource *irq; mtx_assert(&isrc_table_lock, MA_OWNED); - if (irq_next_free >= intr_nirq) - return (ENOSPC); - - for (irq = irq_next_free; irq < intr_nirq; irq++) { - if (irq_sources[irq] == NULL) - goto found; - } - for (irq = 0; irq < irq_next_free; irq++) { - if (irq_sources[irq] == NULL) - goto found; - } + irq = rman_reserve_resource(&intr_avail, 0, ~0, 1, + RF_ACTIVE | RF_UNMAPPED, isrc->isrc_dev); - irq_next_free = intr_nirq; - return (ENOSPC); + if (irq == NULL) + return (ENOSPC); -found: isrc->isrc_irq = irq; - irq_sources[irq] = isrc; - irq_next_free = irq + 1; - if (irq_next_free >= intr_nirq) - irq_next_free = 0; + irq_sources[rman_get_start(irq)] = isrc; + return (0); } @@ -439,22 +435,21 @@ mtx_assert(&isrc_table_lock, MA_OWNED); - if (isrc->isrc_irq >= intr_nirq) + if (isrc->isrc_irq == NULL) + return (EINVAL); + KASSERT(rman_is_region_manager(isrc->isrc_irq, &intr_avail), + ("%s(): intr_irqsrc with invalid irq (not region manager)", + __func__)); + if (rman_get_start(isrc->isrc_irq) >= intr_nirq) return (EINVAL); - if (irq_sources[isrc->isrc_irq] != isrc) + if (irq_sources[rman_get_start(isrc->isrc_irq)] != isrc) return (EINVAL); - irq_sources[isrc->isrc_irq] = NULL; - isrc->isrc_irq = INTR_IRQ_INVALID; /* just to be safe */ + irq_sources[rman_get_start(isrc->isrc_irq)] = NULL; - /* - * If we are recovering from the state irq_sources table is full, - * then the following allocation should check the entire table. This - * will ensure maximum separation of allocation order from release - * order. - */ - if (irq_next_free >= intr_nirq) - irq_next_free = 0; + rman_release_resource(isrc->isrc_irq); + + isrc->isrc_irq = NULL; /* just to be safe */ return (0); } @@ -471,7 +466,7 @@ bzero(isrc, sizeof(struct intr_irqsrc)); isrc->isrc_dev = dev; - isrc->isrc_irq = INTR_IRQ_INVALID; /* just to be safe */ + isrc->isrc_irq = NULL; /* just to be safe */ isrc->isrc_flags = flags; va_start(ap, fmt); @@ -650,7 +645,7 @@ struct intr_event *ie; int error; - error = intr_event_create(&ie, isrc, 0, isrc->isrc_irq, + error = intr_event_create(&ie, isrc, 0, rman_get_start(isrc->isrc_irq), intr_isrc_pre_ithread, intr_isrc_post_ithread, intr_isrc_post_filter, intr_isrc_assign_cpu, "%s:", isrc->isrc_name); if (error) @@ -1078,14 +1073,15 @@ if (flags & INTR_SOLO) { error = iscr_setup_filter(isrc, name, (intr_irq_filter_t *)filt, arg, cookiep); - debugf("irq %u setup filter error %d on %s\n", isrc->isrc_irq, error, - name); + debugf("irq %u setup filter error %d on %s\n", + rman_get_start(isrc->isrc_irq), error, name); } else #endif { error = isrc_add_handler(isrc, name, filt, hand, arg, flags, cookiep); - debugf("irq %u add handler error %d on %s\n", isrc->isrc_irq, error, name); + debugf("irq %u add handler error %d on %s\n", + rman_get_start(isrc->isrc_irq), error, name); } if (error != 0) return (error); Index: sys/sys/intr.h =================================================================== --- sys/sys/intr.h +++ sys/sys/intr.h @@ -82,7 +82,7 @@ /* Interrupt source definition. */ struct intr_irqsrc { device_t isrc_dev; /* where isrc is mapped */ - u_int isrc_irq; /* unique identificator */ + struct resource *isrc_irq; /* unique identificator */ u_int isrc_flags; char isrc_name[INTR_ISRC_NAMELEN]; cpuset_t isrc_cpu; /* on which CPUs is enabled */