serial: 8250-fsl: Only do the break workaround if IIR signals RLSI
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Wed, 13 Dec 2023 17:43:12 +0000 (18:43 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 Dec 2023 13:23:32 +0000 (14:23 +0100)
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>
Link: https://lore.kernel.org/r/20231213174312.2341013-1-u.kleine-koenig@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_fsl.c

index 5cf675eadefe11bf616c3d3ed2b530b53cae9147..b4ed442082a8521b61ec6d87cc01864a3e9a475e 100644 (file)
@@ -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);