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 <johan.hedberg@intel.com>
This commit is contained in:
parent
0cb118968d
commit
048dcea54b
2 changed files with 43 additions and 23 deletions
|
@ -40,11 +40,15 @@
|
||||||
|
|
||||||
#define INST_HAS_PCP_HELPER(inst) DT_INST_NODE_HAS_PROP(inst, pcp) ||
|
#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_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 \
|
#define UART_NS16550_PCP_ENABLED \
|
||||||
(DT_INST_FOREACH_STATUS_OKAY(INST_HAS_PCP_HELPER) 0)
|
(DT_INST_FOREACH_STATUS_OKAY(INST_HAS_PCP_HELPER) 0)
|
||||||
#define UART_NS16550_DLF_ENABLED \
|
#define UART_NS16550_DLF_ENABLED \
|
||||||
(DT_INST_FOREACH_STATUS_OKAY(INST_HAS_DLF_HELPER) 0)
|
(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)
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
|
||||||
BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_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) \
|
#define DEV_DATA(dev) \
|
||||||
((struct uart_ns16550_dev_data_t *)(dev)->data)
|
((struct uart_ns16550_dev_data_t *)(dev)->data)
|
||||||
|
|
||||||
#define THR(dev) (get_port(dev) + REG_THR * UART_REG_ADDR_INTERVAL)
|
#define THR(dev) (get_port(dev) + REG_THR * reg_interval(dev))
|
||||||
#define RDR(dev) (get_port(dev) + REG_RDR * UART_REG_ADDR_INTERVAL)
|
#define RDR(dev) (get_port(dev) + REG_RDR * reg_interval(dev))
|
||||||
#define BRDL(dev) \
|
#define BRDL(dev) (get_port(dev) + REG_BRDL * reg_interval(dev))
|
||||||
(get_port(dev) + REG_BRDL * UART_REG_ADDR_INTERVAL)
|
#define BRDH(dev) (get_port(dev) + REG_BRDH * reg_interval(dev))
|
||||||
#define BRDH(dev) \
|
#define IER(dev) (get_port(dev) + REG_IER * reg_interval(dev))
|
||||||
(get_port(dev) + REG_BRDH * UART_REG_ADDR_INTERVAL)
|
#define IIR(dev) (get_port(dev) + REG_IIR * reg_interval(dev))
|
||||||
#define IER(dev) (get_port(dev) + REG_IER * UART_REG_ADDR_INTERVAL)
|
#define FCR(dev) (get_port(dev) + REG_FCR * reg_interval(dev))
|
||||||
#define IIR(dev) (get_port(dev) + REG_IIR * UART_REG_ADDR_INTERVAL)
|
#define LCR(dev) (get_port(dev) + REG_LCR * reg_interval(dev))
|
||||||
#define FCR(dev) (get_port(dev) + REG_FCR * UART_REG_ADDR_INTERVAL)
|
#define MDC(dev) (get_port(dev) + REG_MDC * reg_interval(dev))
|
||||||
#define LCR(dev) (get_port(dev) + REG_LCR * UART_REG_ADDR_INTERVAL)
|
#define LSR(dev) (get_port(dev) + REG_LSR * reg_interval(dev))
|
||||||
#define MDC(dev) (get_port(dev) + REG_MDC * UART_REG_ADDR_INTERVAL)
|
#define MSR(dev) (get_port(dev) + REG_MSR * reg_interval(dev))
|
||||||
#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 DLF(dev) (get_port(dev) + REG_DLF)
|
#define DLF(dev) (get_port(dev) + REG_DLF)
|
||||||
#define PCP(dev) (get_port(dev) + REG_PCP)
|
#define PCP(dev) (get_port(dev) + REG_PCP)
|
||||||
|
|
||||||
#define IIRC(dev) (DEV_DATA(dev)->iir_cache)
|
#define IIRC(dev) (DEV_DATA(dev)->iir_cache)
|
||||||
|
|
||||||
#if DT_INST_NODE_HAS_PROP(0, reg_shift)
|
|
||||||
#define UART_REG_ADDR_INTERVAL (1<<DT_INST_PROP(0, reg_shift))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UART_NS16550_ACCESS_IOPORT
|
#ifdef UART_NS16550_ACCESS_IOPORT
|
||||||
#define INBYTE(x) sys_in8(x)
|
#define INBYTE(x) sys_in8(x)
|
||||||
#define INWORD(x) sys_in32(x)
|
#define INWORD(x) sys_in32(x)
|
||||||
#define OUTBYTE(x, d) sys_out8(d, x)
|
#define OUTBYTE(x, d) sys_out8(d, x)
|
||||||
#define OUTWORD(x, d) sys_out32(d, x)
|
#define OUTWORD(x, d) sys_out32(d, x)
|
||||||
#ifndef UART_REG_ADDR_INTERVAL
|
|
||||||
#define UART_REG_ADDR_INTERVAL 1 /* address diff of adjacent regs. */
|
|
||||||
#endif /* UART_REG_ADDR_INTERVAL */
|
|
||||||
#else
|
#else
|
||||||
#define INBYTE(x) sys_read8(x)
|
#define INBYTE(x) sys_read8(x)
|
||||||
#define INWORD(x) sys_read32(x)
|
#define INWORD(x) sys_read32(x)
|
||||||
#define OUTBYTE(x, d) sys_write8(d, x)
|
#define OUTBYTE(x, d) sys_write8(d, x)
|
||||||
#define OUTWORD(x, d) sys_write32(d, x)
|
#define OUTWORD(x, d) sys_write32(d, x)
|
||||||
#ifndef UART_REG_ADDR_INTERVAL
|
|
||||||
#define UART_REG_ADDR_INTERVAL 4 /* address diff of adjacent regs. */
|
|
||||||
#endif
|
|
||||||
#endif /* UART_NS16550_ACCESS_IOPORT */
|
#endif /* UART_NS16550_ACCESS_IOPORT */
|
||||||
|
|
||||||
#ifdef CONFIG_UART_NS16550_ACCESS_WORD_ONLY
|
#ifdef CONFIG_UART_NS16550_ACCESS_WORD_ONLY
|
||||||
|
@ -253,6 +245,9 @@ struct uart_ns16550_device_config {
|
||||||
#if UART_NS16550_PCP_ENABLED
|
#if UART_NS16550_PCP_ENABLED
|
||||||
uint32_t pcp;
|
uint32_t pcp;
|
||||||
#endif
|
#endif
|
||||||
|
#if UART_NS16550_REG_INTERVAL_ENABLED
|
||||||
|
uint8_t reg_interval;
|
||||||
|
#endif
|
||||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
|
||||||
bool pcie;
|
bool pcie;
|
||||||
pcie_bdf_t pcie_bdf;
|
pcie_bdf_t pcie_bdf;
|
||||||
|
@ -279,6 +274,27 @@ struct uart_ns16550_dev_data_t {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(UART_REG_ADDR_INTERVAL)
|
||||||
|
#define DEFAULT_REG_INTERVAL UART_REG_ADDR_INTERVAL
|
||||||
|
#elif defined(UART_NS16550_ACCESS_IOPORT)
|
||||||
|
#define DEFAULT_REG_INTERVAL 1
|
||||||
|
#else
|
||||||
|
#define DEFAULT_REG_INTERVAL 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UART_NS16550_REG_INTERVAL_ENABLED
|
||||||
|
static inline uint8_t reg_interval(const struct device *dev)
|
||||||
|
{
|
||||||
|
if (DEV_CFG(dev)->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 const struct uart_driver_api uart_ns16550_driver_api;
|
||||||
|
|
||||||
static inline uintptr_t get_port(const struct device *dev)
|
static inline uintptr_t get_port(const struct device *dev)
|
||||||
|
|
|
@ -29,6 +29,10 @@ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_@NUM@ = {
|
||||||
.pcp = DT_INST_PROP(@NUM@, pcp),
|
.pcp = DT_INST_PROP(@NUM@, pcp),
|
||||||
#endif
|
#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)
|
#if DT_INST_ON_BUS(@NUM@, pcie)
|
||||||
.pcie = true,
|
.pcie = true,
|
||||||
.pcie_bdf = DT_INST_REG_ADDR(@NUM@),
|
.pcie_bdf = DT_INST_REG_ADDR(@NUM@),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue