Clear the STAT register OR bit every time in .tstc callback, otherwise
a condition may occur when data are fed into the RX FIFO, the FIFO did
overflow, the OR bit is set and prevents any new data from being added
into the RX FIFO, the OR bit is never cleared, and watermark read back
is always 0. If this condition occurs, the .tstc callback will always
report no new characters, and the OR bit will never be cleared, so the
U-Boot shell will be unresponsive until next reboot or kernel boot.

This is easy to trigger on MX95, power on the system and send traffic
on UART from host to the MX95, the MX95 FIFO will overflow and the
U-Boot console will become unresponsive.

Fix this by clearing the OR bit early, in .tstc callback. This way,
even if an overflow occurs, there will be slight loss of RX data, but
the U-Boot console will not become unresponsive.

Signed-off-by: Marek Vasut <[email protected]>
---
Cc: Andrew Goodbody <[email protected]>
Cc: Peng Fan <[email protected]>
Cc: Tom Rini <[email protected]>
Cc: [email protected]
---
 drivers/serial/serial_lpuart.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index 9fdb6503085..70be9d50634 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -366,10 +366,14 @@ static int _lpuart32_serial_putc(struct 
lpuart_serial_plat *plat,
 static int _lpuart32_serial_tstc(struct lpuart_serial_plat *plat)
 {
        struct lpuart_fsl_reg32 *base = plat->reg;
-       u32 water;
+       u32 stat, water;
 
        lpuart_read32(plat->flags, &base->water, &water);
 
+       lpuart_read32(plat->flags, &base->stat, &stat);
+       if (stat & STAT_OR)
+               lpuart_write32(plat->flags, &base->stat, STAT_OR);
+
        if ((water >> 24) == 0)
                return 0;
 
-- 
2.53.0

Reply via email to