From 048dcea54b6c1371813548240db918bca88c128b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 19 Dec 2020 18:36:43 +0200 Subject: [PATCH] drivers: serial: ns16550: Remove reg-shift instance count assumption The reg-shift support was quite broken in that the code only looked for this property on instance 0. Now we support the property on any node which might declare it. Signed-off-by: Johan Hedberg --- drivers/serial/uart_ns16550.c | 62 +++++++++++++++++----------- drivers/serial/uart_ns16550_port_x.h | 4 ++ 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index ce1b56ba04d..6b599192de5 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -40,11 +40,15 @@ #define INST_HAS_PCP_HELPER(inst) DT_INST_NODE_HAS_PROP(inst, pcp) || #define INST_HAS_DLF_HELPER(inst) DT_INST_NODE_HAS_PROP(inst, dlf) || +#define INST_HAS_REG_SHIFT_HELPER(inst) \ + DT_INST_NODE_HAS_PROP(inst, reg_shift) || #define UART_NS16550_PCP_ENABLED \ (DT_INST_FOREACH_STATUS_OKAY(INST_HAS_PCP_HELPER) 0) #define UART_NS16550_DLF_ENABLED \ (DT_INST_FOREACH_STATUS_OKAY(INST_HAS_DLF_HELPER) 0) +#define UART_NS16550_REG_INTERVAL_ENABLED \ + (DT_INST_FOREACH_STATUS_OKAY(INST_HAS_REG_SHIFT_HELPER) 0) #if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); @@ -192,44 +196,32 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); #define DEV_DATA(dev) \ ((struct uart_ns16550_dev_data_t *)(dev)->data) -#define THR(dev) (get_port(dev) + REG_THR * UART_REG_ADDR_INTERVAL) -#define RDR(dev) (get_port(dev) + REG_RDR * UART_REG_ADDR_INTERVAL) -#define BRDL(dev) \ - (get_port(dev) + REG_BRDL * UART_REG_ADDR_INTERVAL) -#define BRDH(dev) \ - (get_port(dev) + REG_BRDH * UART_REG_ADDR_INTERVAL) -#define IER(dev) (get_port(dev) + REG_IER * UART_REG_ADDR_INTERVAL) -#define IIR(dev) (get_port(dev) + REG_IIR * UART_REG_ADDR_INTERVAL) -#define FCR(dev) (get_port(dev) + REG_FCR * UART_REG_ADDR_INTERVAL) -#define LCR(dev) (get_port(dev) + REG_LCR * UART_REG_ADDR_INTERVAL) -#define MDC(dev) (get_port(dev) + REG_MDC * UART_REG_ADDR_INTERVAL) -#define LSR(dev) (get_port(dev) + REG_LSR * UART_REG_ADDR_INTERVAL) -#define MSR(dev) (get_port(dev) + REG_MSR * UART_REG_ADDR_INTERVAL) +#define THR(dev) (get_port(dev) + REG_THR * reg_interval(dev)) +#define RDR(dev) (get_port(dev) + REG_RDR * reg_interval(dev)) +#define BRDL(dev) (get_port(dev) + REG_BRDL * reg_interval(dev)) +#define BRDH(dev) (get_port(dev) + REG_BRDH * reg_interval(dev)) +#define IER(dev) (get_port(dev) + REG_IER * reg_interval(dev)) +#define IIR(dev) (get_port(dev) + REG_IIR * reg_interval(dev)) +#define FCR(dev) (get_port(dev) + REG_FCR * reg_interval(dev)) +#define LCR(dev) (get_port(dev) + REG_LCR * reg_interval(dev)) +#define MDC(dev) (get_port(dev) + REG_MDC * reg_interval(dev)) +#define LSR(dev) (get_port(dev) + REG_LSR * reg_interval(dev)) +#define MSR(dev) (get_port(dev) + REG_MSR * reg_interval(dev)) #define DLF(dev) (get_port(dev) + REG_DLF) #define PCP(dev) (get_port(dev) + REG_PCP) #define IIRC(dev) (DEV_DATA(dev)->iir_cache) -#if DT_INST_NODE_HAS_PROP(0, reg_shift) -#define UART_REG_ADDR_INTERVAL (1<reg_interval) { + return DEV_CFG(dev)->reg_interval; + } + + return DEFAULT_REG_INTERVAL; +} +#else +#define reg_interval(dev) DEFAULT_REG_INTERVAL +#endif + static const struct uart_driver_api uart_ns16550_driver_api; static inline uintptr_t get_port(const struct device *dev) diff --git a/drivers/serial/uart_ns16550_port_x.h b/drivers/serial/uart_ns16550_port_x.h index a9940f67644..dfc09dd168d 100644 --- a/drivers/serial/uart_ns16550_port_x.h +++ b/drivers/serial/uart_ns16550_port_x.h @@ -29,6 +29,10 @@ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_@NUM@ = { .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@),