From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/tty/serial/8250/8250_dma.c | 30 +++++++++++++++++++++++++++--- 1 files changed, 27 insertions(+), 3 deletions(-) diff --git a/kernel/drivers/tty/serial/8250/8250_dma.c b/kernel/drivers/tty/serial/8250/8250_dma.c index d8da062..8cde714 100644 --- a/kernel/drivers/tty/serial/8250/8250_dma.c +++ b/kernel/drivers/tty/serial/8250/8250_dma.c @@ -15,6 +15,7 @@ #define MAX_TX_BYTES 64 #define MAX_FIFO_SIZE 64 #define UART_RFL_16550A 0x21 +#define DW_UART_DMASA 0x2a #endif static void __dma_tx_complete(void *param) @@ -85,19 +86,38 @@ struct uart_8250_dma *dma = p->dma; struct tty_port *tty_port = &p->port.state->port; struct dma_tx_state state; + enum dma_status dma_status; int count; - dma->rx_running = 0; - dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); + /* + * New DMA Rx can be started during the completion handler before it + * could acquire port's lock and it might still be ongoing. Don't to + * anything in such case. + */ + dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); + if (dma_status == DMA_IN_PROGRESS) + return; count = dma->rx_size - state.residue; tty_insert_flip_string(tty_port, dma->rx_buf, count); p->port.icount.rx += count; + dma->rx_running = 0; tty_flip_buffer_push(tty_port); } +static void dma_rx_complete(void *param) +{ + struct uart_8250_port *p = param; + struct uart_8250_dma *dma = p->dma; + unsigned long flags; + + spin_lock_irqsave(&p->port.lock, flags); + if (dma->rx_running) + __dma_rx_complete(p); + spin_unlock_irqrestore(&p->port.lock, flags); +} #endif int serial8250_tx_dma(struct uart_8250_port *p) @@ -150,6 +170,10 @@ dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) + /* Clear uart dma request before start dma */ + serial_port_out(&p->port, DW_UART_DMASA, 0x1); +#endif dma_async_issue_pending(dma->txchan); if (dma->tx_err) { dma->tx_err = 0; @@ -234,7 +258,7 @@ return -EBUSY; dma->rx_running = 1; - desc->callback = __dma_rx_complete; + desc->callback = dma_rx_complete; desc->callback_param = p; dma->rx_cookie = dmaengine_submit(desc); -- Gitblit v1.6.2