drivers: serial: ns16550: use MMIO device depending on Kconfig option

Add a new selectable Kconfig option to decide wether the device driver
is a MMIO device or not. Previous to this patch, the decision was maded
based on the existence of a definition in <soc.h>. The design was
fragile, as code compiled anyway if the definition was not present.

All platforms/boards that had the definition in <soc.h> select the
Kconfig option in their respective defconfig files.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2022-06-01 15:51:56 +02:00 committed by Carles Cufí
parent 920028e03b
commit 92f488497f
5 changed files with 23 additions and 8 deletions

View file

@ -67,6 +67,9 @@ config QEMU_ICOUNT
config QEMU_ICOUNT_SHIFT
default 5
config UART_NS16550_ACCESS_IOPORT
default y if UART_NS16550
endif # BOARD_QEMU_X86_LAKEMONT
if BOARD_QEMU_X86_TINY

View file

@ -58,6 +58,12 @@ config UART_NS16550_ACCESS_WORD_ONLY
16550 (DesignWare UART) only allows word access, byte access will raise
exception.
config UART_NS16550_ACCESS_IOPORT
bool
help
When enabled, NS16550 will not be a memory mapped device. This option
must be selected at SoC/board level if needed.
menu "NS16550 Workarounds"
config UART_NS16550_WA_ISR_REENABLE_INTERRUPT

View file

@ -207,7 +207,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
#define IIRC(dev) (((struct uart_ns16550_dev_data *)(dev)->data)->iir_cache)
#ifdef UART_NS16550_ACCESS_IOPORT
#ifdef CONFIG_UART_NS16550_ACCESS_IOPORT
#define INBYTE(x) sys_in8(x)
#define INWORD(x) sys_in32(x)
#define OUTBYTE(x, d) sys_out8(d, x)
@ -217,7 +217,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
#define INWORD(x) sys_read32(x)
#define OUTBYTE(x, d) sys_write8(d, x)
#define OUTWORD(x, d) sys_write32(d, x)
#endif /* UART_NS16550_ACCESS_IOPORT */
#endif /* CONFIG_UART_NS16550_ACCESS_IOPORT */
#ifdef CONFIG_UART_NS16550_ACCESS_WORD_ONLY
#undef INBYTE
@ -228,7 +228,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
/* device config */
struct uart_ns16550_device_config {
#ifndef UART_NS16550_ACCESS_IOPORT
#ifndef CONFIG_UART_NS16550_ACCESS_IOPORT
DEVICE_MMIO_ROM;
#else
uint32_t port;
@ -252,7 +252,7 @@ struct uart_ns16550_device_config {
/** Device data structure */
struct uart_ns16550_dev_data {
#ifndef UART_NS16550_ACCESS_IOPORT
#ifndef CONFIG_UART_NS16550_ACCESS_IOPORT
DEVICE_MMIO_RAM;
#endif
struct uart_config uart_config;
@ -276,7 +276,7 @@ struct uart_ns16550_dev_data {
#if defined(UART_REG_ADDR_INTERVAL)
#define DEFAULT_REG_INTERVAL UART_REG_ADDR_INTERVAL
#elif defined(UART_NS16550_ACCESS_IOPORT)
#elif defined(CONFIG_UART_NS16550_ACCESS_IOPORT)
#define DEFAULT_REG_INTERVAL 1
#else
#define DEFAULT_REG_INTERVAL 4
@ -301,7 +301,7 @@ static const struct uart_driver_api uart_ns16550_driver_api;
static inline uintptr_t get_port(const struct device *dev)
{
#ifndef UART_NS16550_ACCESS_IOPORT
#ifndef CONFIG_UART_NS16550_ACCESS_IOPORT
return DEVICE_MMIO_GET(dev);
#else
const struct uart_ns16550_device_config *config = dev->config;
@ -353,7 +353,7 @@ static int uart_ns16550_configure(const struct device *dev,
ARG_UNUSED(dev_data);
ARG_UNUSED(dev_cfg);
#ifndef UART_NS16550_ACCESS_IOPORT
#ifndef CONFIG_UART_NS16550_ACCESS_IOPORT
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
if (dev_cfg->pcie) {
struct pcie_mbar mbar;
@ -1085,7 +1085,7 @@ static const struct uart_driver_api uart_ns16550_driver_api = {
pcie_irq_enable(DT_INST_REG_ADDR(n), irq); \
}
#ifdef UART_NS16550_ACCESS_IOPORT
#ifdef CONFIG_UART_NS16550_ACCESS_IOPORT
#define DEV_CONFIG_REG_INIT(n) \
.port = DT_INST_REG_ADDR(n),
#else

View file

@ -19,4 +19,7 @@ config UART_PIPE_ON_DEV_NAME
endif
config UART_NS16550_ACCESS_IOPORT
default y if UART_NS16550
endif

View file

@ -11,4 +11,7 @@ config SOC
config SYS_CLOCK_HW_CYCLES_PER_SEC
default 25000000 if HPET_TIMER
config UART_NS16550_ACCESS_IOPORT
default y if UART_NS16550
endif