[PATCH 04/13] serial: linflexuart: Correctly clear UARTSR in buffer mode

Larisa Grigore posted 13 patches 1 month, 2 weeks ago
[PATCH 04/13] serial: linflexuart: Correctly clear UARTSR in buffer mode
Posted by Larisa Grigore 1 month, 2 weeks ago
The TX interrupt handler should not clear RX-related fields in UARTSR,
and vice versa.
The handler checks UARTSR.DRFRFE before invoking linflex_rxint, and
UARTSR.DTFTFF before invoking linflex_txint.
Incorrectly clearing these bits may cause the interrupt handler to miss
characters.
Same applies to linflex_console_putchar which should clear only
UARTSR.DTFTFF.

Fixes: 09864c1cdf5c ("tty: serial: Add linflexuart driver for S32V234")
Signed-off-by: Larisa Grigore <larisa.grigore@oss.nxp.com>
---
 drivers/tty/serial/fsl_linflexuart.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c
index 9111e7af62ea..a48240b0a5f2 100644
--- a/drivers/tty/serial/fsl_linflexuart.c
+++ b/drivers/tty/serial/fsl_linflexuart.c
@@ -169,7 +169,7 @@ static void linflex_put_char(struct uart_port *sport, unsigned char c)
 				LINFLEXD_UARTSR_DTFTFF)
 		;
 
-	writel(status | LINFLEXD_UARTSR_DTFTFF, sport->membase + UARTSR);
+	writel(LINFLEXD_UARTSR_DTFTFF, sport->membase + UARTSR);
 }
 
 static inline void linflex_transmit_buffer(struct uart_port *sport)
@@ -255,7 +255,8 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id)
 				sport->icount.parity++;
 		}
 
-		writel(status, sport->membase + UARTSR);
+
+		writel(~(u32)LINFLEXD_UARTSR_DTFTFF, sport->membase + UARTSR);
 		status = readl(sport->membase + UARTSR);
 
 		if (brk) {
@@ -573,9 +574,7 @@ static void linflex_console_putchar(struct uart_port *port, unsigned char ch)
 				!= LINFLEXD_UARTSR_DTFTFF)
 			;
 
-		writel((readl(port->membase + UARTSR) |
-					LINFLEXD_UARTSR_DTFTFF),
-					port->membase + UARTSR);
+		writel(LINFLEXD_UARTSR_DTFTFF, port->membase + UARTSR);
 	}
 }
 
-- 
2.47.0