* Allocate a fixed IRQ mapping for the given MIPS @p irq, or return the * existing mapping if @p irq was previously mapped. * * @param irq The MIPS IRQ to be mapped. * @param[out] mapping On success, will be populated with the interrupt * mapping. * * @retval 0 success * @retval EINVAL if @p irq is not a valid MIPS IRQ#. * @retval non-zero If allocating the MIPS IRQ mapping otherwise
| 453 | * regular unix error code will be returned. |
| 454 | */ |
| 455 | static int |
| 456 | mips_pic_map_fixed_intr(u_int irq, struct mips_pic_intr **mapping) |
| 457 | { |
| 458 | struct mips_pic_intr *intr; |
| 459 | struct intr_map_data_mips_pic *data; |
| 460 | device_t pic_dev; |
| 461 | uintptr_t xref; |
| 462 | |
| 463 | if (irq < 0 || irq >= nitems(mips_pic_intrs)) |
| 464 | return (EINVAL); |
| 465 | |
| 466 | mtx_lock(&mips_pic_mtx); |
| 467 | |
| 468 | /* Fetch corresponding interrupt entry */ |
| 469 | intr = &mips_pic_intrs[irq]; |
| 470 | KASSERT(intr->mips_irq == irq, |
| 471 | ("intr %u found at index %u", intr->mips_irq, irq)); |
| 472 | |
| 473 | /* Already mapped? */ |
| 474 | if (intr->intr_irq != INTR_IRQ_INVALID) { |
| 475 | mtx_unlock(&mips_pic_mtx); |
| 476 | *mapping = intr; |
| 477 | return (0); |
| 478 | } |
| 479 | |
| 480 | /* Map the interrupt */ |
| 481 | data = (struct intr_map_data_mips_pic *)intr_alloc_map_data( |
| 482 | INTR_MAP_DATA_MIPS, sizeof(*data), M_WAITOK | M_ZERO); |
| 483 | data->irq = intr->mips_irq; |
| 484 | |
| 485 | #ifdef FDT |
| 486 | /* PIC must be attached on FDT devices */ |
| 487 | KASSERT(pic_sc != NULL, ("%s: no pic", __func__)); |
| 488 | |
| 489 | pic_dev = pic_sc->pic_dev; |
| 490 | xref = pic_xref(pic_dev); |
| 491 | #else /* !FDT */ |
| 492 | /* PIC has a fixed xref, and may not have been attached yet */ |
| 493 | pic_dev = NULL; |
| 494 | if (pic_sc != NULL) |
| 495 | pic_dev = pic_sc->pic_dev; |
| 496 | |
| 497 | xref = MIPS_PIC_XREF; |
| 498 | #endif /* FDT */ |
| 499 | |
| 500 | KASSERT(intr->intr_irq == INTR_IRQ_INVALID, ("duplicate map")); |
| 501 | intr->intr_irq = intr_map_irq(pic_dev, xref, &data->hdr); |
| 502 | *mapping = intr; |
| 503 | |
| 504 | mtx_unlock(&mips_pic_mtx); |
| 505 | return (0); |
| 506 | } |
| 507 | |
| 508 | /** |
| 509 | * |
no test coverage detected