@@ -1563,7 +1563,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;
@@ -1632,7 +1639,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))
@@ -1640,7 +1646,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);
@@ -1678,8 +1683,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);
imx_set_termios() cleared RTS on every call, now fixed. Signed-off-by: Sergey Organov <sorganov@gmail.com> --- drivers/tty/serial/imx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)