* Allocate required resources and initialize the given @p cpuirq state. * * @param sc BHND MIPS driver instance state. * @param cpuirq The CPU IRQ state to be initialized. * @param rid The resource ID to be assigned for the CPU IRQ resource, * or -1 if no resource should be assigned. * @param irq The MIPS HW IRQ# to be allocated. * @param filter The interrupt filter to be setup. * *
| 153 | * unix error code will be returned. |
| 154 | */ |
| 155 | static int |
| 156 | bcm_mips_init_cpuirq(struct bcm_mips_softc *sc, struct bcm_mips_cpuirq *cpuirq, |
| 157 | int rid, u_int irq, driver_filter_t filter) |
| 158 | { |
| 159 | struct resource *res; |
| 160 | void *cookie; |
| 161 | u_int irq_real; |
| 162 | int error; |
| 163 | |
| 164 | /* Must fall within MIPS HW IRQ range */ |
| 165 | if (irq >= NHARD_IRQS) |
| 166 | return (EINVAL); |
| 167 | |
| 168 | /* HW IRQs are numbered relative to SW IRQs */ |
| 169 | irq_real = irq + NSOFT_IRQS; |
| 170 | |
| 171 | /* Try to assign and allocate the resource */ |
| 172 | BCM_MIPS_LOCK(sc); |
| 173 | |
| 174 | KASSERT(cpuirq->sc == NULL, ("cpuirq already initialized")); |
| 175 | |
| 176 | error = bus_set_resource(sc->dev, SYS_RES_IRQ, rid, irq_real, 1); |
| 177 | if (error) { |
| 178 | BCM_MIPS_UNLOCK(sc); |
| 179 | device_printf(sc->dev, "failed to assign interrupt %u: " |
| 180 | "%d\n", irq, error); |
| 181 | return (error); |
| 182 | } |
| 183 | |
| 184 | res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &rid, RF_ACTIVE); |
| 185 | if (res == NULL) { |
| 186 | BCM_MIPS_UNLOCK(sc); |
| 187 | device_printf(sc->dev, "failed to allocate interrupt " |
| 188 | "%u resource\n", irq); |
| 189 | bus_delete_resource(sc->dev, SYS_RES_IRQ, rid); |
| 190 | return (ENXIO); |
| 191 | } |
| 192 | |
| 193 | error = bus_setup_intr(sc->dev, res, |
| 194 | INTR_TYPE_MISC | INTR_MPSAFE | INTR_EXCL, filter, NULL, cpuirq, |
| 195 | &cookie); |
| 196 | if (error) { |
| 197 | BCM_MIPS_UNLOCK(sc); |
| 198 | |
| 199 | printf("failed to setup internal interrupt handler: %d\n", |
| 200 | error); |
| 201 | |
| 202 | bus_release_resource(sc->dev, SYS_RES_IRQ, rid, res); |
| 203 | bus_delete_resource(sc->dev, SYS_RES_IRQ, rid); |
| 204 | |
| 205 | return (error); |
| 206 | } |
| 207 | |
| 208 | /* Initialize CPU IRQ state */ |
| 209 | cpuirq->sc = sc; |
| 210 | cpuirq->mips_irq = irq; |
| 211 | cpuirq->irq_rid = rid; |
| 212 | cpuirq->irq_res = res; |
no test coverage detected