mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
serial: amba-pl011: fix indefinite RS485 post-send delay
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: 2c1fd53af2 ("serial: amba-pl011: Fix RTS handling in RS485 mode")
Cc: stable <stable@kernel.org>
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260731085915.326775-2-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a7ad003445
commit
dcb2f7576c
|
|
@ -309,6 +309,7 @@ enum pl011_rs485_tx_state {
|
|||
WAIT_AFTER_RTS,
|
||||
SEND,
|
||||
WAIT_AFTER_SEND,
|
||||
WAIT_AFTER_SEND_DELAY,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -1350,6 +1351,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);
|
||||
|
|
@ -1415,7 +1417,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;
|
||||
|
|
@ -1482,7 +1485,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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user