diff --git a/drivers/pcie/host/pcie.c b/drivers/pcie/host/pcie.c index 49952803b85..8626e127bc0 100644 --- a/drivers/pcie/host/pcie.c +++ b/drivers/pcie/host/pcie.c @@ -216,87 +216,34 @@ bool pcie_probe_mbar(pcie_bdf_t bdf, return pcie_get_mbar(bdf, reg - PCIE_CONF_BAR0, mbar); } -/* The first bit is used to indicate whether the list of reserved interrupts - * have been initialized based on content stored in the irq_alloc linker - * section in ROM. - */ -#define IRQ_LIST_INITIALIZED 0 - -#ifndef CONFIG_MAX_IRQ_LINES -#warning TOFIX for non-x86 -#define CONFIG_MAX_IRQ_LINES 0 -#endif - -static ATOMIC_DEFINE(irq_reserved, CONFIG_MAX_IRQ_LINES); - -static unsigned int irq_alloc(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(irq_reserved); i++) { - unsigned int fz, irq; - - while ((fz = find_lsb_set(~atomic_get(&irq_reserved[i])))) { - irq = (fz - 1) + (i * sizeof(atomic_val_t) * 8); - if (irq >= CONFIG_MAX_IRQ_LINES) { - break; - } - - if (!atomic_test_and_set_bit(irq_reserved, irq)) { - return irq; - } - } - } - - return PCIE_CONF_INTR_IRQ_NONE; -} - -static bool irq_is_reserved(unsigned int irq) -{ - return atomic_test_bit(irq_reserved, irq); -} - -static void irq_init(void) -{ - extern uint8_t __irq_alloc_start[]; - extern uint8_t __irq_alloc_end[]; - const uint8_t *irq; - - for (irq = __irq_alloc_start; irq < __irq_alloc_end; irq++) { - __ASSERT_NO_MSG(*irq < CONFIG_MAX_IRQ_LINES); - atomic_set_bit(irq_reserved, *irq); - } -} +#ifndef CONFIG_PCIE_CONTROLLER unsigned int pcie_alloc_irq(pcie_bdf_t bdf) { unsigned int irq; uint32_t data; - if (!atomic_test_and_set_bit(irq_reserved, IRQ_LIST_INITIALIZED)) { - irq_init(); - } - data = pcie_conf_read(bdf, PCIE_CONF_INTR); irq = PCIE_CONF_INTR_IRQ(data); - if (irq == PCIE_CONF_INTR_IRQ_NONE || irq >= CONFIG_MAX_IRQ_LINES || - irq_is_reserved(irq)) { - - irq = irq_alloc(); - if (irq == PCIE_CONF_INTR_IRQ_NONE) { - return irq; + if (irq == PCIE_CONF_INTR_IRQ_NONE || + irq >= CONFIG_MAX_IRQ_LINES || + arch_irq_is_used(irq)) { + irq = arch_irq_allocate(); + if (irq == UINT_MAX) { + return PCIE_CONF_INTR_IRQ_NONE; } data &= ~0xffU; data |= irq; pcie_conf_write(bdf, PCIE_CONF_INTR, data); } else { - atomic_set_bit(irq_reserved, irq); + arch_irq_set_used(irq); } return irq; } +#endif /* CONFIG_PCIE_CONTROLLER */ unsigned int pcie_get_irq(pcie_bdf_t bdf) { diff --git a/include/drivers/pcie/pcie.h b/include/drivers/pcie/pcie.h index 7adba14ab72..785e31ab0b8 100644 --- a/include/drivers/pcie/pcie.h +++ b/include/drivers/pcie/pcie.h @@ -124,17 +124,22 @@ extern bool pcie_probe_mbar(pcie_bdf_t bdf, */ extern void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on); +#ifndef CONFIG_PCIE_CONTROLLER /** * @brief Allocate an IRQ for an endpoint. * * This function first checks the IRQ register and if it contains a valid * value this is returned. If the register does not contain a valid value * allocation of a new one is attempted. + * Such function is only exposed if CONFIG_PCIE_CONTROLLER is unset. + * It is thus available where architecture tied dynamic IRQ allocation for + * PCIe device makes sense. * * @param bdf the PCI(e) endpoint * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if allocation failed. */ extern unsigned int pcie_alloc_irq(pcie_bdf_t bdf); +#endif /* CONFIG_PCIE_CONTROLLER */ /** * @brief Return the IRQ assigned by the firmware/board to an endpoint.