drivers/pcie: Add a function for dynamic PCIe IRQ connection
The is meant to fix a chicken & egg issue with MSI interrupt remapping. Currently, drivers first connect the irq (by-passing any possible MSI remapping), so the IRQ ends-up being remapped at the IOAPIC level which is not what we want. So adding a dedicated function to properly handle this case. This is valid only for runtime dynamic IRQ connection obviously. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
fbb2f1511c
commit
b5fecc5ff8
2 changed files with 47 additions and 0 deletions
|
@ -252,6 +252,35 @@ unsigned int pcie_get_irq(pcie_bdf_t bdf)
|
||||||
return PCIE_CONF_INTR_IRQ(data);
|
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)
|
void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq)
|
||||||
{
|
{
|
||||||
#if CONFIG_PCIE_MSI
|
#if CONFIG_PCIE_MSI
|
||||||
|
|
|
@ -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);
|
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.
|
* Configuration word 13 contains the head of the capabilities list.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue