| From 89d8232411a85b9a6b12fd5da4d07d8a138a8e0c Mon Sep 17 00:00:00 2001 |
| From: Richard Genoud <richard.genoud@gmail.com> |
| Date: Tue, 13 Dec 2016 17:27:56 +0100 |
| Subject: tty/serial: atmel_serial: BUG: stop DMA from transmitting in stop_tx |
| |
| From: Richard Genoud <richard.genoud@gmail.com> |
| |
| commit 89d8232411a85b9a6b12fd5da4d07d8a138a8e0c upstream. |
| |
| 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) |
| |
| 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> |
| |
| --- |
| drivers/tty/serial/atmel_serial.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| --- a/drivers/tty/serial/atmel_serial.c |
| +++ b/drivers/tty/serial/atmel_serial.c |
| @@ -470,6 +470,14 @@ static void atmel_stop_tx(struct uart_po |
| /* disable PDC transmit */ |
| atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS); |
| } |
| + |
| + /* |
| + * Disable the transmitter. |
| + * This is mandatory when DMA is used, otherwise the DMA buffer |
| + * is fully transmitted. |
| + */ |
| + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS); |
| + |
| /* Disable interrupts */ |
| atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask); |
| |
| @@ -502,6 +510,9 @@ static void atmel_start_tx(struct uart_p |
| |
| /* Enable interrupts */ |
| atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask); |
| + |
| + /* re-enable the transmitter */ |
| + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN); |
| } |
| |
| /* |