diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index ae8f866a3e3..bef4e778d6e 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -72,6 +72,16 @@ config UART_NS16550_SIMULT_ACCESS When enabled, NS16550 supports IO, MMIO, PCIe UART devices simultaneously. For io-mapped instances, io-mapped DTS property need to be added in dtsi. +config UART_NS16550_PARENT_INIT_LEVEL + bool "Boot level based on parent node" + default y if ACPI + help + Boot level based on parent node (PCI or no PCI device). Some platforms the + PCI bus driver depends on ACPI sub system to retrieve platform information + such as interrupt routing information. But ACPI sub system currently support + only post kernel and hence such platforms the UART driver instance init + should be invoked only post kernel in case parent node is PCI. + menu "NS16550 Workarounds" config UART_NS16550_WA_ISR_REENABLE_INTERRUPT diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 08619561570..0456b354c4e 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -1248,6 +1248,15 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #define DEV_DATA_DLF_INIT(n) \ _CONCAT(DEV_DATA_DLF, DT_INST_NODE_HAS_PROP(n, dlf))(n) +#ifdef CONFIG_UART_NS16550_PARENT_INIT_LEVEL +#define NS16550_BOOT_LEVEL0 PRE_KERNEL_1 +#define NS16550_BOOT_LEVEL1 POST_KERNEL +#define BOOT_LEVEL(n) \ + _CONCAT(NS16550_BOOT_LEVEL, DT_INST_ON_BUS(n, pcie)) +#else +#define BOOT_LEVEL(n) PRE_KERNEL_1 +#endif + #define UART_NS16550_DEVICE_INIT(n) \ UART_NS16550_IRQ_FUNC_DECLARE(n); \ DEV_PCIE_DECLARE(n); \ @@ -1283,7 +1292,7 @@ static const struct uart_driver_api uart_ns16550_driver_api = { }; \ DEVICE_DT_INST_DEFINE(n, &uart_ns16550_init, NULL, \ &uart_ns16550_dev_data_##n, &uart_ns16550_dev_cfg_##n, \ - PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + BOOT_LEVEL(n), CONFIG_SERIAL_INIT_PRIORITY, \ &uart_ns16550_driver_api); \ UART_NS16550_IRQ_FUNC_DEFINE(n)