[PATCH 2/2] tty: serial: lpuart: disable hardware flow control in lpuart32_startup()

From: Sherry Sun (OSS)

Date: Wed Oct 21 2026 - 23:14:33 EST


From: Sherry Sun <sherry.sun@xxxxxxx>

The RXRTSE/TXCTSE bits in UARTMODIR are configured by set_termios()
according to CRTSCTS and are left untouched by shutdown(), so they keep
their value from the previous session when the port is started again.

On open, and on resume when a tty is attached, the serial core calls
ops->startup() before set_termios(). lpuart32_startup() enables the
receiver (UARTCTRL_RE), and with RXRTSE still set from the previous
session RTS is asserted immediately. The remote side may then start
sending before set_termios() deasserts RTS again, disables TE/RE and
reprograms the baud rate, so the characters in flight are lost or
corrupted.

Clear RXRTSE/TXCTSE at the beginning of lpuart32_startup() instead.
Together with set_termios() keeping both bits masked until its last
UARTMODIR write, RTS now stays deasserted from startup() until the port
is fully configured. The flow control setting itself is still owned by
set_termios().

Fixes: 380c966c093e ("tty: serial: fsl_lpuart: add 32-bit register interface support")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Sherry Sun <sherry.sun@xxxxxxx>
---
drivers/tty/serial/fsl_lpuart.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 70b69870aaba..87737f0e0f21 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1889,7 +1889,19 @@ static void lpuart32_hw_setup(struct lpuart_port *sport)
static int lpuart32_startup(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
- u32 fifo;
+ u32 fifo, modem;
+
+ /*
+ * The hardware flow control is configured by set_termios(), which the
+ * serial core calls after startup() to apply the termios settings. Keep
+ * it disabled until then, otherwise the RXRTSE left over from the
+ * previous session asserts RTS as soon as the receiver is enabled
+ * below, and the remote side may start sending while set_termios()
+ * still reconfigures the receiver.
+ */
+ modem = lpuart32_read(port, UARTMODIR);
+ modem &= ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
+ lpuart32_write(port, modem, UARTMODIR);

/* determine FIFO size */
fifo = lpuart32_read(port, UARTFIFO);

--
2.50.1