aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Genoud <richard.genoud@gmail.com>2016-12-13 11:27:56 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-11 02:18:45 -0500
commit89d8232411a85b9a6b12fd5da4d07d8a138a8e0c (patch)
treea72050791b333650ecec60742926be90dabb535e
parenta121103c922847ba5010819a3f250f1f7fc84ab8 (diff)
tty/serial: atmel_serial: BUG: stop DMA from transmitting in stop_tx
If we don't disable the transmitter in atmel_stop_tx, the DMA buffer continues to send data until it is emptied. This cause problems with the flow control (CTS is asserted and data are still sent). So, disabling the transmitter in atmel_stop_tx is a sane thing to do. Tested on at91sam9g35-cm(DMA) Tested for regressions on sama5d2-xplained(Fifo) and at91sam9g20ek(PDC) Cc: <stable@vger.kernel.org> (beware, this won't apply before 4.3) Signed-off-by: Richard Genoud <richard.genoud@gmail.com> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/atmel_serial.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 168b10cad47b..f9d42de5ab2d 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -481,6 +481,14 @@ static void atmel_stop_tx(struct uart_port *port)
481 /* disable PDC transmit */ 481 /* disable PDC transmit */
482 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS); 482 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
483 } 483 }
484
485 /*
486 * Disable the transmitter.
487 * This is mandatory when DMA is used, otherwise the DMA buffer
488 * is fully transmitted.
489 */
490 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS);
491
484 /* Disable interrupts */ 492 /* Disable interrupts */
485 atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask); 493 atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
486 494
@@ -513,6 +521,9 @@ static void atmel_start_tx(struct uart_port *port)
513 521
514 /* Enable interrupts */ 522 /* Enable interrupts */
515 atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask); 523 atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);
524
525 /* re-enable the transmitter */
526 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
516} 527}
517 528
518/* 529/*