diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index 1bdc8d6432fe..7133fceed35e 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -34,7 +34,7 @@ static void __dma_tx_complete(void *param) uart_write_wakeup(&p->port); ret = serial8250_tx_dma(p); - if (ret) + if (ret || !dma->tx_running) serial8250_set_THRI(p); spin_unlock_irqrestore(&p->port.lock, flags); @@ -80,7 +80,6 @@ int serial8250_tx_dma(struct uart_8250_port *p) if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) { /* We have been called from __dma_tx_complete() */ - serial8250_rpm_put_tx(p); return 0; } diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 5bba852d30f7..40d4895fd208 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1948,9 +1948,12 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) status = serial8250_rx_chars(up, status); } serial8250_modem_status(up); - if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE) && - (up->ier & UART_IER_THRI)) - serial8250_tx_chars(up); + if ((status & UART_LSR_THRE) && (up->ier & UART_IER_THRI)) { + if (!up->dma || up->dma->tx_err) + serial8250_tx_chars(up); + else + __stop_tx(up); + } uart_unlock_and_check_sysrq_irqrestore(port, flags);