drivers/uart_ns16550: enable auto IRQ detection for PCI(e) endpoints
If a UART is configured with IRQ == PCIE_IRQ_DETECT, then use the pcie_wired_irq() to determine the IRQ at runtime, and install the handler using the dynamic interrupt mechanism. Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
parent
f2af5fe731
commit
869c5d2e54
2 changed files with 47 additions and 7 deletions
|
@ -50,20 +50,51 @@ static void irq_config_func_@NUM@(struct device *dev)
|
|||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
#if DT_UART_NS16550_PORT_@NUM@_PCIE
|
||||
#if DT_UART_NS16550_PORT_@NUM@_IRQ == PCIE_IRQ_DETECT
|
||||
|
||||
/* PCI(e) with auto IRQ detection */
|
||||
|
||||
BUILD_ASSERT_MSG(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS),
|
||||
"NS16550 PCI auto-IRQ needs CONFIG_DYNAMIC_INTERRUPTS");
|
||||
|
||||
unsigned int irq;
|
||||
|
||||
irq = pcie_wired_irq(DT_UART_NS16550_PORT_@NUM@_BASE_ADDR);
|
||||
if (irq == PCIE_CONF_INTR_IRQ_NONE) return;
|
||||
|
||||
irq_connect_dynamic(irq,
|
||||
DT_UART_NS16550_PORT_@NUM@_IRQ_PRI,
|
||||
uart_ns16550_isr,
|
||||
DEVICE_GET(uart_ns16550_@NUM@),
|
||||
DT_UART_NS16550_PORT_@NUM@_IRQ_FLAGS);
|
||||
|
||||
pcie_irq_enable(DT_UART_NS16550_PORT_@NUM@_BASE_ADDR, irq);
|
||||
|
||||
#else
|
||||
|
||||
/* PCI(e) with fixed or MSI IRQ */
|
||||
|
||||
IRQ_CONNECT(DT_UART_NS16550_PORT_@NUM@_IRQ,
|
||||
DT_UART_NS16550_PORT_@NUM@_IRQ_PRI,
|
||||
uart_ns16550_isr, DEVICE_GET(uart_ns16550_@NUM@),
|
||||
DT_UART_NS16550_PORT_@NUM@_IRQ_FLAGS);
|
||||
|
||||
#ifdef UART_NS16550_PCIE_ENABLED
|
||||
if (DEV_CFG(dev)->pcie) {
|
||||
pcie_irq_enable(DT_UART_NS16550_PORT_@NUM@_BASE_ADDR,
|
||||
DT_UART_NS16550_PORT_@NUM@_IRQ);
|
||||
} else {
|
||||
irq_enable(DT_UART_NS16550_PORT_@NUM@_IRQ);
|
||||
}
|
||||
pcie_irq_enable(DT_UART_NS16550_PORT_@NUM@_BASE_ADDR,
|
||||
DT_UART_NS16550_PORT_@NUM@_IRQ);
|
||||
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* not PCI(e) */
|
||||
|
||||
IRQ_CONNECT(DT_UART_NS16550_PORT_@NUM@_IRQ,
|
||||
DT_UART_NS16550_PORT_@NUM@_IRQ_PRI,
|
||||
uart_ns16550_isr, DEVICE_GET(uart_ns16550_@NUM@),
|
||||
DT_UART_NS16550_PORT_@NUM@_IRQ_FLAGS);
|
||||
|
||||
irq_enable(DT_UART_NS16550_PORT_@NUM@_IRQ);
|
||||
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,15 @@
|
|||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PCIE_PCIE_H_
|
||||
#define ZEPHYR_INCLUDE_DT_BINDINGS_PCIE_PCIE_H_
|
||||
|
||||
/*
|
||||
* Set the device's IRQ (in devicetree, or whatever) to PCIE_IRQ_DETECT
|
||||
* if the device doesn't support MSI and we don't/can't know the wired IRQ
|
||||
* allocated by the firmware ahead of time. Use of this functionality will
|
||||
* generally also require CONFIG_DYNAMIC_INTERRUPTS.
|
||||
*/
|
||||
|
||||
#define PCIE_IRQ_DETECT 0xFFFFFFFU
|
||||
|
||||
/*
|
||||
* We represent a PCI device ID as [31:16] device ID, [15:0] vendor ID. Not
|
||||
* coincidentally, this is same representation used in PCI configuration space.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue