diff options
-rw-r--r-- | drivers/tty/serial/8250/8250_omap.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index d81bac98d190..833771bca0a5 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -786,8 +786,27 @@ unlock: static void __dma_rx_complete(void *param) { - __dma_rx_do_complete(param); - omap_8250_rx_dma(param); + struct uart_8250_port *p = param; + struct uart_8250_dma *dma = p->dma; + struct dma_tx_state state; + unsigned long flags; + + spin_lock_irqsave(&p->port.lock, flags); + + /* + * If the tx status is not DMA_COMPLETE, then this is a delayed + * completion callback. A previous RX timeout flush would have + * already pushed the data, so exit. + */ + if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) != + DMA_COMPLETE) { + spin_unlock_irqrestore(&p->port.lock, flags); + return; + } + __dma_rx_do_complete(p); + omap_8250_rx_dma(p); + + spin_unlock_irqrestore(&p->port.lock, flags); } static void omap_8250_rx_dma_flush(struct uart_8250_port *p) |