diff --git a/drivers/pcie/host/pcie.c b/drivers/pcie/host/pcie.c index 8626e127bc0..f6fb38142ef 100644 --- a/drivers/pcie/host/pcie.c +++ b/drivers/pcie/host/pcie.c @@ -252,6 +252,35 @@ unsigned int pcie_get_irq(pcie_bdf_t bdf) return PCIE_CONF_INTR_IRQ(data); } +bool pcie_connect_dynamic_irq(pcie_bdf_t bdf, + unsigned int irq, + unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, + uint32_t flags) +{ +#if defined(CONFIG_PCIE_MSI) && defined(CONFIG_PCIE_MSI_MULTI_VECTOR) + if (pcie_is_msi(bdf)) { + msi_vector_t vector; + + if ((pcie_msi_vectors_allocate(bdf, priority, + &vector, 1) == 0) || + !pcie_msi_vector_connect(bdf, &vector, + routine, parameter, flags)) { + return false; + } + } else +#endif /* CONFIG_PCIE_MSI && CONFIG_PCIE_MSI_MULTI_VECTOR */ + { + if (irq_connect_dynamic(irq, priority, routine, + parameter, flags) < 0) { + return false; + } + } + + return true; +} + void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq) { #if CONFIG_PCIE_MSI diff --git a/include/drivers/pcie/pcie.h b/include/drivers/pcie/pcie.h index 785e31ab0b8..76c1afc94ff 100644 --- a/include/drivers/pcie/pcie.h +++ b/include/drivers/pcie/pcie.h @@ -181,6 +181,24 @@ extern uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id); */ extern uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id); +/** + * @brief Dynamically connect a PCIe endpoint IRQ to an ISR handler + * + * @param bdf the PCI endpoint to examine + * @param irq the IRQ to connect (see pcie_alloc_irq()) + * @param priority priority of the IRQ + * @param routine the ISR handler to connect to the IRQ + * @param parameter the parameter to provide to the handler + * @param flags IRQ connection flags + * @return true if connected, false otherwise + */ +extern bool pcie_connect_dynamic_irq(pcie_bdf_t bdf, + unsigned int irq, + unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, + uint32_t flags); + /* * Configuration word 13 contains the head of the capabilities list. */