[PATCH v2 1/3] serial: amba-pl011: fix indefinite RS485 post-send delay
From: Fan Wu
Date: Fri Jul 31 2026 - 05:12:40 EST
The RS485 stop hrtimer is used both to drain the transmitter and to wait
out delay_rts_after_send. The callback cannot tell the two apart, so it
restarts the post-send delay on every expiry and the timer never stops.
Add a WAIT_AFTER_SEND_DELAY state so its expiry ends the stop sequence
instead of restarting the delay.
Fixes: 2c1fd53af21b ("serial: amba-pl011: Fix RTS handling in RS485 mode")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@xxxxxxxxxx>
---
drivers/tty/serial/amba-pl011.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 7f17d288c807..b212e2bcd41a 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -253,6 +253,7 @@ enum pl011_rs485_tx_state {
WAIT_AFTER_RTS,
SEND,
WAIT_AFTER_SEND,
+ WAIT_AFTER_SEND_DELAY,
};
/*
@@ -1285,6 +1286,7 @@ static void pl011_rs485_tx_stop(struct uart_amba_port *uap)
return;
}
if (port->rs485.delay_rts_after_send > 0) {
+ uap->rs485_tx_state = WAIT_AFTER_SEND_DELAY;
hrtimer_start(&uap->trigger_stop_tx,
ms_to_ktime(port->rs485.delay_rts_after_send),
HRTIMER_MODE_REL);
@@ -1350,7 +1352,8 @@ static void pl011_rs485_tx_start(struct uart_amba_port *uap)
uap->rs485_tx_state = SEND;
return;
}
- if (uap->rs485_tx_state == WAIT_AFTER_SEND) {
+ if (uap->rs485_tx_state == WAIT_AFTER_SEND ||
+ uap->rs485_tx_state == WAIT_AFTER_SEND_DELAY) {
hrtimer_try_to_cancel(&uap->trigger_stop_tx);
uap->rs485_tx_state = SEND;
return;
@@ -1417,7 +1420,8 @@ static enum hrtimer_restart pl011_trigger_stop_tx(struct hrtimer *t)
unsigned long flags;
uart_port_lock_irqsave(&uap->port, &flags);
- if (uap->rs485_tx_state == WAIT_AFTER_SEND)
+ if (uap->rs485_tx_state == WAIT_AFTER_SEND ||
+ uap->rs485_tx_state == WAIT_AFTER_SEND_DELAY)
pl011_rs485_tx_stop(uap);
uart_port_unlock_irqrestore(&uap->port, flags);
--
2.34.1