diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 21ffa7836d..dd7959387e 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -18,6 +18,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_MCUX_LPUART uart_mcux_lpuart.c) zephyr_library_sources_ifdef(CONFIG_UART_MCUX_LPSCI uart_mcux_lpsci.c) zephyr_library_sources_ifdef(CONFIG_UART_MIV uart_miv.c) zephyr_library_sources_ifdef(CONFIG_UART_MSP432P4XX uart_msp432p4xx.c) +zephyr_library_sources_ifdef(CONFIG_UART_NS16550 uart_ns16550.c) zephyr_library_sources_ifdef(CONFIG_NRF_UART_PERIPHERAL uart_nrfx_uart.c) zephyr_library_sources_ifdef(CONFIG_NRF_UARTE_PERIPHERAL uart_nrfx_uarte.c) zephyr_library_sources_ifdef(CONFIG_UART_NUVOTON uart_nuvoton.c) @@ -40,19 +41,6 @@ zephyr_library_sources_ifdef(CONFIG_USB_CDC_ACM ${ZEPHYR_BASE}/misc/empty_file.c zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) -if(CONFIG_UART_NS16550) - zephyr_library_sources(uart_ns16550.c) - math(EXPR max_index "${CONFIG_UART_NS16550_MAX_INSTANCES} - 1") - foreach(NUM RANGE 0 ${max_index}) - math(EXPR NEXT_NUM "${NUM} + 1") - configure_file( - uart_ns16550_port_x.h - ${PROJECT_BINARY_DIR}/include/generated/uart_ns16550_port_${NUM}.h - @ONLY - ) - endforeach(NUM) -endif() - if(CONFIG_UART_NATIVE_POSIX) zephyr_library_compile_definitions(NO_POSIX_CHEATS) zephyr_library_sources(uart_native_posix.c) diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index 1f0e004cc8..f00356c60f 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -11,13 +11,6 @@ menuconfig UART_NS16550 if UART_NS16550 -config UART_NS16550_MAX_INSTANCES - int "Maximum number of supported driver instances" - range 1 32 - default 4 - help - The maximum number of supported driver instances in device tree. - config UART_NS16550_LINE_CTRL bool "Enable Serial Line Control for Apps" depends on UART_LINE_CTRL diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 11e859b693..61b5391d33 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -979,8 +979,119 @@ static const struct uart_driver_api uart_ns16550_driver_api = { #endif }; -/* The instance-specific header files are chained together (each instance - * includes the next one, unless it's the last instance) so we only need to - * include the first instance. - */ -#include +#define UART_NS16550_IRQ_FLAGS_SENSE0(n) 0 +#define UART_NS16550_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense) +#define UART_NS16550_IRQ_FLAGS(n) \ + _CONCAT(UART_NS16550_IRQ_FLAGS_SENSE, DT_INST_IRQ_HAS_CELL(n, sense))(n) + +/* not PCI(e) */ +#define UART_NS16550_IRQ_CONFIG_PCIE0(n) \ + static void irq_config_func##n(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + uart_ns16550_isr, DEVICE_DT_INST_GET(n), \ + UART_NS16550_IRQ_FLAGS(n)); \ + irq_enable(DT_INST_IRQN(n)); \ + } + +/* PCI(e) with auto IRQ detection */ +#define UART_NS16550_IRQ_CONFIG_PCIE1(n) \ + static void irq_config_func##n(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + BUILD_ASSERT(DT_INST_IRQN(n) == PCIE_IRQ_DETECT, \ + "Only runtime IRQ configuration is supported"); \ + BUILD_ASSERT(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), \ + "NS16550 PCIe requires dynamic interrupts"); \ + unsigned int irq = pcie_alloc_irq(DT_INST_REG_ADDR(n)); \ + if (irq == PCIE_CONF_INTR_IRQ_NONE) { \ + return; \ + } \ + irq_connect_dynamic(irq, DT_INST_IRQ(n, priority), \ + (void (*)(const void *))uart_ns16550_isr, \ + DEVICE_DT_INST_GET(n), \ + UART_NS16550_IRQ_FLAGS(n)); \ + pcie_irq_enable(DT_INST_REG_ADDR(n), irq); \ + } + +#ifdef UART_NS16550_ACCESS_IOPORT +#define DEV_CONFIG_REG_INIT(n) \ + .port = DT_INST_REG_ADDR(n), +#else +#define DEV_CONFIG_REG_INIT_PCIE0(n) DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), +#define DEV_CONFIG_REG_INIT_PCIE1(n) +#define DEV_CONFIG_REG_INIT(n) \ + _CONCAT(DEV_CONFIG_REG_INIT_PCIE, DT_INST_ON_BUS(n, pcie))(n) +#endif + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define DEV_CONFIG_IRQ_FUNC_INIT(n) \ + .irq_config_func = irq_config_func##n, +#define UART_NS16550_IRQ_FUNC_DECLARE(n) \ + static void irq_config_func##n(const struct device *dev); +#define UART_NS16550_IRQ_FUNC_DEFINE(n) \ + _CONCAT(UART_NS16550_IRQ_CONFIG_PCIE, DT_INST_ON_BUS(n, pcie))(n) +#else +/* !CONFIG_UART_INTERRUPT_DRIVEN */ +#define DEV_CONFIG_IRQ_FUNC_INIT(n) +#define UART_NS16550_IRQ_FUNC_DECLARE(n) +#define UART_NS16550_IRQ_FUNC_DEFINE(n) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#if UART_NS16550_PCP_ENABLED +#define DEV_CONFIG_PCP_INIT(n) .pcp = DT_INST_PROP_OR(n, pcp, 0), +#else +#define DEV_CONFIG_PCP_INIT(n) +#endif + +#define DEV_CONFIG_REG_INT0(n) +#define DEV_CONFIG_REG_INT1(n) \ + .reg_interval = (1 << DT_INST_PROP(n, reg_shift)), +#define DEV_CONFIG_REG_INT_INIT(n) \ + _CONCAT(DEV_CONFIG_REG_INT, DT_INST_NODE_HAS_PROP(n, reg_shift))(n) + +#define DEV_CONFIG_PCIE0(n) +#define DEV_CONFIG_PCIE1(n) \ + .pcie = true, \ + .pcie_bdf = DT_INST_REG_ADDR(n), \ + .pcie_id = DT_INST_REG_SIZE(n), +#define DEV_CONFIG_PCIE_INIT(n) \ + _CONCAT(DEV_CONFIG_PCIE, DT_INST_ON_BUS(n, pcie))(n) + +#define DEV_DATA_FLOW_CTRL0 UART_CFG_FLOW_CTRL_NONE +#define DEV_DATA_FLOW_CTRL1 UART_CFG_FLOW_CTRL_RTS_CTS +#define DEV_DATA_FLOW_CTRL(n) \ + _CONCAT(DEV_DATA_FLOW_CTRL, DT_INST_NODE_HAS_PROP(n, hw_flow_control)) + +#define DEV_DATA_DLF0(n) +#define DEV_DATA_DLF1(n) \ + .dlf = DT_INST_PROP(n, dlf), +#define DEV_DATA_DLF_INIT(n) \ + _CONCAT(DEV_DATA_DLF, DT_INST_NODE_HAS_PROP(n, dlf))(n) + +#define UART_NS16550_DEVICE_INIT(n) \ + UART_NS16550_IRQ_FUNC_DECLARE(n); \ + static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \ + DEV_CONFIG_REG_INIT(n) \ + .sys_clk_freq = DT_INST_PROP(n, clock_frequency), \ + DEV_CONFIG_IRQ_FUNC_INIT(n) \ + DEV_CONFIG_PCP_INIT(n) \ + DEV_CONFIG_REG_INT_INIT(n) \ + DEV_CONFIG_PCIE_INIT(n) \ + }; \ + static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_##n = { \ + .uart_config.baudrate = DT_INST_PROP_OR(n, current_speed, 0), \ + .uart_config.parity = UART_CFG_PARITY_NONE, \ + .uart_config.stop_bits = UART_CFG_STOP_BITS_1, \ + .uart_config.data_bits = UART_CFG_DATA_BITS_8, \ + .uart_config.flow_ctrl = DEV_DATA_FLOW_CTRL(n), \ + DEV_DATA_DLF_INIT(n) \ + }; \ + DEVICE_DT_INST_DEFINE(n, &uart_ns16550_init, device_pm_control_nop, \ + &uart_ns16550_dev_data_##n, &uart_ns16550_dev_cfg_##n, \ + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &uart_ns16550_driver_api); \ + UART_NS16550_IRQ_FUNC_DEFINE(n) + +DT_INST_FOREACH_STATUS_OKAY(UART_NS16550_DEVICE_INIT) diff --git a/drivers/serial/uart_ns16550_port_x.h b/drivers/serial/uart_ns16550_port_x.h deleted file mode 100644 index 5d59620b96..0000000000 --- a/drivers/serial/uart_ns16550_port_x.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2010, 2012-2015 Wind River Systems, Inc. - * Copyright (c) 2019-2020 Intel Corp. - * - * SPDX-License-Identifier: Apache-2.0 - * - * This file is a template for cmake and is not meant to be used directly! - */ - -#if DT_NODE_HAS_STATUS(DT_DRV_INST(@NUM@), okay) - -#ifdef CONFIG_UART_INTERRUPT_DRIVEN -static void irq_config_func_@NUM@(const struct device *port); -#endif - -static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_@NUM@ = { -#ifdef UART_NS16550_ACCESS_IOPORT - .port = DT_INST_REG_ADDR(@NUM@), -#elif !DT_INST_ON_BUS(@NUM@, pcie) - DEVICE_MMIO_ROM_INIT(DT_DRV_INST(@NUM@)), -#endif - .sys_clk_freq = DT_INST_PROP(@NUM@, clock_frequency), - -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - .irq_config_func = irq_config_func_@NUM@, -#endif - -#if DT_INST_NODE_HAS_PROP(@NUM@, pcp) - .pcp = DT_INST_PROP(@NUM@, pcp), -#endif - -#if DT_INST_NODE_HAS_PROP(@NUM@, reg_shift) - .reg_interval = (1 << DT_INST_PROP(@NUM@, reg_shift)) -#endif - -#if DT_INST_ON_BUS(@NUM@, pcie) - .pcie = true, - .pcie_bdf = DT_INST_REG_ADDR(@NUM@), - .pcie_id = DT_INST_REG_SIZE(@NUM@), -#endif -}; - -static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_@NUM@ = { -#if DT_INST_NODE_HAS_PROP(@NUM@, current_speed) - .uart_config.baudrate = DT_INST_PROP(@NUM@, current_speed), -#endif - .uart_config.parity = UART_CFG_PARITY_NONE, - .uart_config.stop_bits = UART_CFG_STOP_BITS_1, - .uart_config.data_bits = UART_CFG_DATA_BITS_8, -#if DT_INST_PROP(@NUM@, hw_flow_control) - .uart_config.flow_ctrl = UART_CFG_FLOW_CTRL_RTS_CTS, -#else - .uart_config.flow_ctrl = UART_CFG_FLOW_CTRL_NONE, -#endif -#if DT_INST_NODE_HAS_PROP(@NUM@, dlf) - .dlf = DT_INST_PROP(@NUM@, dlf), -#endif -}; - -DEVICE_DT_INST_DEFINE(@NUM@, - &uart_ns16550_init, - device_pm_control_nop, - &uart_ns16550_dev_data_@NUM@, &uart_ns16550_dev_cfg_@NUM@, - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, - &uart_ns16550_driver_api); - -#if DT_INST_IRQ_HAS_CELL(@NUM@, sense) -#define INST_@NUM@_IRQ_FLAGS DT_INST_IRQ(@NUM@, sense) -#else -#define INST_@NUM@_IRQ_FLAGS 0 -#endif - -#ifdef CONFIG_UART_INTERRUPT_DRIVEN -static void irq_config_func_@NUM@(const struct device *dev) -{ - ARG_UNUSED(dev); - -#if DT_INST_ON_BUS(@NUM@, pcie) - /* PCI(e) with auto IRQ detection */ - BUILD_ASSERT(DT_INST_IRQN(@NUM@) == PCIE_IRQ_DETECT, - "Only runtime IRQ configuration is supported"); - BUILD_ASSERT(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), - "NS16550 PCI auto-IRQ needs CONFIG_DYNAMIC_INTERRUPTS"); - - unsigned int irq; - - irq = pcie_alloc_irq(DT_INST_REG_ADDR(@NUM@)); - - if (irq == PCIE_CONF_INTR_IRQ_NONE) { - return; - } - - irq_connect_dynamic(irq, - DT_INST_IRQ(@NUM@, priority), - (void (*)(const void *))uart_ns16550_isr, - DEVICE_DT_INST_GET(@NUM@), - INST_@NUM@_IRQ_FLAGS); - - pcie_irq_enable(DT_INST_REG_ADDR(@NUM@), irq); -#else - - /* not PCI(e) */ - - IRQ_CONNECT(DT_INST_IRQN(@NUM@), - DT_INST_IRQ(@NUM@, priority), - uart_ns16550_isr, - DEVICE_DT_INST_GET(@NUM@), - INST_@NUM@_IRQ_FLAGS); - - irq_enable(DT_INST_IRQN(@NUM@)); - -#endif -} -#endif - -#endif - -/* Include subsequent instances */ -#if @NUM@ < (CONFIG_UART_NS16550_MAX_INSTANCES - 1) -#include -#endif diff --git a/soc/x86/elkhart_lake/Kconfig.defconfig b/soc/x86/elkhart_lake/Kconfig.defconfig index 11d3914630..fe4a08093d 100644 --- a/soc/x86/elkhart_lake/Kconfig.defconfig +++ b/soc/x86/elkhart_lake/Kconfig.defconfig @@ -49,8 +49,4 @@ config I2C_DW default y depends on I2C -config UART_NS16550_MAX_INSTANCES - default 11 - depends on UART_NS16550 - endif # SOC_ELKHART_LAKE