[PATCH v2 2/2] serial: amba-pl011: keep RS485 transmission running on reconfiguration
From: Nicolai Buchwitz
Date: Sat Oct 17 2026 - 02:18:33 EST
Changing the RS485 settings while RS485 stays enabled calls
pl011_rs485_tx_stop(), also while a transmission is in progress. Unlike
pl011_stop_tx() it leaves the TX interrupt enabled, so the remaining
data is still pushed into the FIFO after the drain turned off the
transmitter. The FIFO never empties, the port stalls, and closing it
hangs in pl011_dma_shutdown() waiting for the transmitter to go idle.
A start still waiting for delay_rts_before_send is dropped as well.
Only stop the transmitter when no transmission is in progress. The
call is still needed there, it sets the idle RTS level when the port
is configured or resumed. A transmission in progress sets that level
when it ends.
An active break counts as a transmission too. Forget it only when
leaving RS485 mode, so that pl011_break_ctl() still ends the
transmission when the break ends.
Fixes: 8d479237727c ("serial: amba-pl011: add RS485 support")
Cc: stable@xxxxxxxxxxxxxxx # 6.18.x
Signed-off-by: Nicolai Buchwitz <nb@xxxxxxxxxxx>
---
drivers/tty/serial/amba-pl011.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 3b9cce435c650..036a7245f1f29 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2506,8 +2506,6 @@ static int pl011_rs485_config(struct uart_port *port, struct ktermios *termios,
container_of(port, struct uart_amba_port, port);
bool tx_stopped = uart_tx_stopped(port);
- uap->rs485_break = false;
-
/*
* Output is marked stopped before stop_tx pauses DMA. Pause it now, so
* that clearing TXE below cannot strand DMA data in the FIFO. Output
@@ -2521,6 +2519,8 @@ static int pl011_rs485_config(struct uart_port *port, struct ktermios *termios,
bool tx_pending = uap->rs485_tx_state == WAIT_AFTER_RTS;
u32 cr = pl011_read(uap, REG_CR);
+ uap->rs485_break = false;
+
/*
* Leaving RS485 mode, which only enables the transmitter while
* sending. Don't stop it, as that stalls a DMA transfer still
@@ -2543,7 +2543,9 @@ static int pl011_rs485_config(struct uart_port *port, struct ktermios *termios,
tty_port_initialized(&port->state->port) &&
pl011_tx_pending(uap, tx_stopped)) {
pl011_rs485_tx_resume(uap, rs485, tx_stopped);
- } else if (port->rs485.flags & SER_RS485_ENABLED) {
+ } else if ((port->rs485.flags & SER_RS485_ENABLED) &&
+ uap->rs485_tx_state == OFF) {
+ /* Set the idle level now, a transmission sets it when done */
pl011_rs485_tx_stop(uap);
}
--
2.53.0