]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
serial: 8250: 8250_omap: Terminate DMA before pushing data on RX timeout
authorVignesh Raghavendra <vigneshr@ti.com>
Thu, 19 Mar 2020 11:03:39 +0000 (16:33 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Oct 2020 11:14:39 +0000 (13:14 +0200)
[ Upstream commit 7cf4df30a98175033e9849f7f16c46e96ba47f41 ]

Terminate and flush DMA internal buffers, before pushing RX data to
higher layer. Otherwise, this will lead to data corruption, as driver
would end up pushing stale buffer data to higher layer while actual data
is still stuck inside DMA hardware and has yet not arrived at the
memory.
While at that, replace deprecated dmaengine_terminate_all() with
dmaengine_terminate_async().

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Link: https://lore.kernel.org/r/20200319110344.21348-2-vigneshr@ti.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/tty/serial/8250/8250_omap.c

index a7e555e413a693b686bebcaef3a0c6d4e8be3ef8..cbd006fb7fbb986bde3407be6e2e02b8bb500e4f 100644 (file)
@@ -781,7 +781,10 @@ static void __dma_rx_do_complete(struct uart_8250_port *p)
        dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
 
        count = dma->rx_size - state.residue;
-
+       if (count < dma->rx_size)
+               dmaengine_terminate_async(dma->rxchan);
+       if (!count)
+               goto unlock;
        ret = tty_insert_flip_string(tty_port, dma->rx_buf, count);
 
        p->port.icount.rx += ret;
@@ -843,7 +846,6 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
        spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
 
        __dma_rx_do_complete(p);
-       dmaengine_terminate_all(dma->rxchan);
 }
 
 static int omap_8250_rx_dma(struct uart_8250_port *p)