diff mbox series

serial: 8250-fsl: Only do the break workaround if IIR signals RLSI

Message ID 20231213174312.2341013-1-u.kleine-koenig@pengutronix.de
State New
Headers show
Series serial: 8250-fsl: Only do the break workaround if IIR signals RLSI | expand

Commit Message

Uwe Kleine-König Dec. 13, 2023, 5:43 p.m. UTC
It can happen that while a break is received the transmitter gets empty
and IIR signals a Transmitter holding register empty (THRI) event. In
this case it's too early for the break workaround. Still doing it then
results in the THRI event not being rereported which makes the driver
miss that and e.g. for RS485 half-duplex communication it fails to
switch back to RX mode.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 drivers/tty/serial/8250/8250_fsl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Hello,

I already sent this patch some time ago in a series with two other
patches. One of them got negative review feedback (and wasn't applied)
the other was applied as commit d2d4bd217ccd ("serial: 8250-fsl: Expand
description of the MPC83xx UART's misbehaviour"). This one didn't
receive any feedback (and wasn't applied, too).

So here comes the patch again, rebased to today's next.
See
https://lore.kernel.org/linux-serial/20230524122754.481816-4-u.kleine-koenig@pengutronix.de
for the previous submission.
diff mbox series

Patch

diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
index 5cf675eadefe..b4ed442082a8 100644
--- a/drivers/tty/serial/8250/8250_fsl.c
+++ b/drivers/tty/serial/8250/8250_fsl.c
@@ -51,7 +51,8 @@  int fsl8250_handle_irq(struct uart_port *port)
 	 * immediately and interrupt the CPU again. The hardware clears LSR.BI
 	 * when the next valid char is read.)
 	 */
-	if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) {
+	if (unlikely((iir & UART_IIR_ID) == UART_IIR_RLSI &&
+		     (up->lsr_saved_flags & UART_LSR_BI))) {
 		up->lsr_saved_flags &= ~UART_LSR_BI;
 		port->serial_in(port, UART_RX);
 		uart_port_unlock_irqrestore(&up->port, flags);