The CPR register can give the information whether the IP is DMA capable or not. Let's extract this information when the CPR register is valid and use it to discriminate when the DMA cannot be hooked up. We assume existing designs either provide a valid CPR register or do not provide any. Co-developed-by: Phil Edworthy <phil.edworthy@xxxxxxxxxxx> Signed-off-by: Phil Edworthy <phil.edworthy@xxxxxxxxxxx> Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx> --- drivers/tty/serial/8250/8250_dw.c | 4 ++-- drivers/tty/serial/8250/8250_dwlib.c | 7 +++++-- drivers/tty/serial/8250/8250_dwlib.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 88fa17882df5..2f4a818f787c 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -564,8 +564,8 @@ static int dw8250_probe(struct platform_device *pdev) if (!data->skip_autocfg) dw8250_setup_port(p); - /* If we have a valid fifosize, try hooking up DMA */ - if (p->fifosize) { + /* If we have a valid fifosize and DMA support, try hooking up DMA */ + if (p->fifosize && !data->no_dma) { data->data.dma.rxconf.src_maxburst = p->fifosize / 4; data->data.dma.txconf.dst_maxburst = p->fifosize / 4; up->dma = &data->data.dma; diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c index cef20ca3ad61..b3ff67401670 100644 --- a/drivers/tty/serial/8250/8250_dwlib.c +++ b/drivers/tty/serial/8250/8250_dwlib.c @@ -92,6 +92,8 @@ void dw8250_setup_port(struct uart_port *p) { struct uart_8250_port *up = up_to_u8250p(p); const struct dw8250_platform_data *pdata = device_get_match_data(up->port.dev); + struct dw8250_port_data *d = p->private_data; + struct dw8250_data *data = container_of(d, struct dw8250_data, data); u32 reg; /* @@ -110,8 +112,6 @@ void dw8250_setup_port(struct uart_port *p) dw8250_writel_ext(p, DW_UART_DLF, 0); if (reg) { - struct dw8250_port_data *d = p->private_data; - d->dlf_size = fls(reg); p->get_divisor = dw8250_get_divisor; p->set_divisor = dw8250_set_divisor; @@ -136,5 +136,8 @@ void dw8250_setup_port(struct uart_port *p) if (reg & DW_UART_CPR_SIR_MODE) up->capabilities |= UART_CAP_IRDA; + + if (!(reg & DW_UART_CPR_DMA_EXTRA)) + data->no_dma = 1; } EXPORT_SYMBOL_GPL(dw8250_setup_port); diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h index 704ba91ab09f..ff965345fc14 100644 --- a/drivers/tty/serial/8250/8250_dwlib.h +++ b/drivers/tty/serial/8250/8250_dwlib.h @@ -39,6 +39,7 @@ struct dw8250_data { unsigned int skip_autocfg:1; unsigned int uart_16550_compatible:1; + unsigned int no_dma:1; }; void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, struct ktermios *old); -- 2.27.0