serial: imx: set_termios(): preserve RTS state
authorSergey Organov <sorganov@gmail.com>
Wed, 26 Jun 2019 14:11:30 +0000 (17:11 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Jul 2019 17:35:42 +0000 (19:35 +0200)
imx_set_termios() cleared RTS on every call, now fixed.

Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Sergey Organov <sorganov@gmail.com>
Link: https://lore.kernel.org/r/1561558293-7683-5-git-send-email-sorganov@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/imx.c

index 1cb891b..57d6e6b 100644 (file)
@@ -1562,7 +1562,14 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
 
        spin_lock_irqsave(&sport->port.lock, flags);
 
-       ucr2 = UCR2_SRST | UCR2_IRTS;
+       /*
+        * Read current UCR2 and save it for future use, then clear all the bits
+        * except those we will or may need to preserve.
+        */
+       old_ucr2 = imx_uart_readl(sport, UCR2);
+       ucr2 = old_ucr2 & (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN | UCR2_CTS);
+
+       ucr2 |= UCR2_SRST | UCR2_IRTS;
        if ((termios->c_cflag & CSIZE) == CS8)
                ucr2 |= UCR2_WS;
 
@@ -1631,7 +1638,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
        imx_uart_writel(sport,
                        old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN),
                        UCR1);
-       old_ucr2 = imx_uart_readl(sport, UCR2);
        imx_uart_writel(sport, old_ucr2 & ~UCR2_ATEN, UCR2);
 
        while (!(imx_uart_readl(sport, USR2) & USR2_TXDC))
@@ -1639,7 +1645,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
 
        /* then, disable everything */
        imx_uart_writel(sport, old_ucr2 & ~(UCR2_TXEN | UCR2_RXEN | UCR2_ATEN), UCR2);
-       old_ucr2 &= (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN);
 
        /* custom-baudrate handling */
        div = sport->port.uartclk / (baud * 16);
@@ -1677,8 +1682,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
 
        imx_uart_writel(sport, old_ucr1, UCR1);
 
-       /* set the parity, stop bits and data size */
-       imx_uart_writel(sport, ucr2 | old_ucr2, UCR2);
+       imx_uart_writel(sport, ucr2, UCR2);
 
        if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
                imx_uart_enable_ms(&sport->port);