serial: imx: set_mctrl(): correctly restore autoRTS state
authorSergey Organov <sorganov@gmail.com>
Fri, 26 Jul 2019 18:52:40 +0000 (21:52 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Sep 2019 10:43:46 +0000 (12:43 +0200)
imx_uart_set_mctrl() happened to set UCR2_CTSC bit whenever TIOCM_RTS
was set, no matter if RTS/CTS handshake is enabled or not. Now fixed by
turning handshake on only when CRTSCTS bit for the port is set.

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/1564167161-3972-3-git-send-email-sorganov@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/imx.c

index 32f36d8..059ba35 100644 (file)
@@ -974,10 +974,22 @@ static void imx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
        if (!(port->rs485.flags & SER_RS485_ENABLED)) {
                u32 ucr2;
 
+               /*
+                * Turn off autoRTS if RTS is lowered and restore autoRTS
+                * setting if RTS is raised.
+                */
                ucr2 = imx_uart_readl(sport, UCR2);
                ucr2 &= ~(UCR2_CTS | UCR2_CTSC);
-               if (mctrl & TIOCM_RTS)
-                       ucr2 |= UCR2_CTS | UCR2_CTSC;
+               if (mctrl & TIOCM_RTS) {
+                       ucr2 |= UCR2_CTS;
+                       /*
+                        * UCR2_IRTS is unset if and only if the port is
+                        * configured for CRTSCTS, so we use inverted UCR2_IRTS
+                        * to get the state to restore to.
+                        */
+                       if (!(ucr2 & UCR2_IRTS))
+                               ucr2 |= UCR2_CTSC;
+               }
                imx_uart_writel(sport, ucr2, UCR2);
        }