]> Git Repo - linux.git/commitdiff
tty/serial: atmel_serial: BUG: stop DMA from transmitting in stop_tx
authorRichard Genoud <[email protected]>
Tue, 13 Dec 2016 16:27:56 +0000 (17:27 +0100)
committerGreg Kroah-Hartman <[email protected]>
Wed, 11 Jan 2017 07:18:45 +0000 (08:18 +0100)
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: <[email protected]> (beware, this won't apply before 4.3)
Signed-off-by: Richard Genoud <[email protected]>
Acked-by: Nicolas Ferre <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/tty/serial/atmel_serial.c

index 168b10cad47b5437c2152313fcad026e2747300a..f9d42de5ab2d6e909c3e1967f9b8c9ddc180882c 100644 (file)
@@ -481,6 +481,14 @@ static void atmel_stop_tx(struct uart_port *port)
                /* 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);
 
@@ -513,6 +521,9 @@ static void atmel_start_tx(struct uart_port *port)
 
        /* 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);
 }
 
 /*
This page took 0.058355 seconds and 4 git commands to generate.