[PATCH 2/2] serial: lpuart: test the receive flag, not the FIFO counter

Mehmet Fide <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
From: Mehmet Fide <[email protected]>

On the 8 bit register variant, the only user of which is fsl,vf610-lpuart,
_lpuart_serial_init() disables the FIFO:

	/* Disable FIFO and flush buffer */
	__raw_writeb(0x0, &base->upfifo);

while _lpuart_serial_tstc() asks the receive FIFO counter whether a
character arrived:

	if (__raw_readb(&base->urcfifo) == 0)
		return 0;

With the FIFO disabled the dataword lands in the data register and raises
S1[RDRF], but RCFIFO stays zero, so tstc() never reports a character. The
console is then output only: autoboot cannot be interrupted, ctrlc() never
fires, and anything polling for a key waits forever.

_lpuart_serial_getc() in the same driver already tests S1, and the 32 bit
variant enables its FIFO in _lpuart32_serial_init() before reading the
RXCOUNT field of WATER, so only this path is inconsistent. Test S1 the way
getc() does.

Tested on a Colibri VF50: U-Boot printed its whole log over UART0 but
accepted no input at all, neither a key during the boot delay nor Ctrl-C
during a sleep, while Linux received on the same pads with the same pin
mux. With the fix the boot delay can be interrupted, including with
bootdelay=0, where the key is already buffered when abortboot_single_key()
checks.

Signed-off-by: Mehmet Fide <[email protected]>
---
 drivers/serial/serial_lpuart.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index 9fdb6503085..9c02b3a77ca 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -198,10 +198,11 @@ static int _lpuart_serial_tstc(struct lpuart_serial_plat *plat)
 {
 	struct lpuart_fsl *base = plat->reg;
 
-	if (__raw_readb(&base->urcfifo) == 0)
-		return 0;
-
-	return 1;
+	/*
+	 * The receive FIFO counter stays at zero because _lpuart_serial_init()
+	 * disables the FIFO, so ask the status register, the way getc() does.
+	 */
+	return __raw_readb(&base->us1) & (US1_RDRF | US1_OR) ? 1 : 0;
 }
 
 /*
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.