serial: 8250-fsl: Expand description of the MPC83xx UART's misbehaviour
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Wed, 24 May 2023 12:27:52 +0000 (14:27 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 31 May 2023 09:46:59 +0000 (10:46 +0100)
After working quite a bit on erratic behaviour of the MPC83xx UART I
(think I) understood the problem. Expand the description accoringly to
conserve the knowledge for the future.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20230524122754.481816-2-u.kleine-koenig@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_fsl.c

index 8adfaa1..00f46b9 100644 (file)
@@ -38,7 +38,19 @@ int fsl8250_handle_irq(struct uart_port *port)
                return 0;
        }
 
-       /* This is the WAR; if last event was BRK, then read and return */
+       /*
+        * For a single break the hardware reports LSR.BI for each character
+        * time. This is described in the MPC8313E chip errata as "General17".
+        * A typical break has a duration of 0.3s, with a 115200n8 configuration
+        * that (theoretically) corresponds to ~3500 interrupts in these 0.3s.
+        * In practise it's less (around 500) because of hardware
+        * and software latencies. The workaround recommended by the vendor is
+        * to read the RX register (to clear LSR.DR and thus prevent a FIFO
+        * aging interrupt). To prevent the irq from retriggering LSR must not be
+        * read. (This would clear LSR.BI, hardware would reassert the BI event
+        * 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)) {
                up->lsr_saved_flags &= ~UART_LSR_BI;
                port->serial_in(port, UART_RX);