Skip to content

Commit c97f2a6

Browse files
vladimirolteangregkh
authored andcommitted
tty: serial: fsl_lpuart: LS1021A has a FIFO size of 16 words, like LS1028A
Prior to the commit that this one fixes, the FIFO size was derived from the read-only register LPUARTx_FIFO[TXFIFOSIZE] using the following formula: TX FIFO size = 2 ^ (LPUARTx_FIFO[TXFIFOSIZE] - 1) The documentation for LS1021A is a mess. Under chapter 26.1.3 LS1021A LPUART module special consideration, it mentions TXFIFO_SZ and RXFIFO_SZ being equal to 4, and in the register description for LPUARTx_FIFO, it shows the out-of-reset value of TXFIFOSIZE and RXFIFOSIZE fields as "011", even though these registers read as "101" in reality. And when LPUART on LS1021A was working, the "101" value did correspond to "16 datawords", by applying the formula above, even though the documentation is wrong again (!!!!) and says that "101" means 64 datawords (hint: it doesn't). So the "new" formula created by commit f77ebb2 has all the premises of being wrong for LS1021A, because it relied only on false data and no actual experimentation. Interestingly, in commit c2f448c ("tty: serial: fsl_lpuart: add LS1028A support"), Michael Walle applied a workaround to this by manually setting the FIFO widths for LS1028A. It looks like the same values are used by LS1021A as well, in fact. When the driver thinks that it has a deeper FIFO than it really has, getty (user space) output gets truncated. Many thanks to Michael for pointing out where to look. Fixes: f77ebb2 ("tty: serial: fsl_lpuart: correct the FIFO depth size") Suggested-by: Michael Walle <michael@walle.cc> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://lore.kernel.org/r/20201023013429.3551026-1-vladimir.oltean@nxp.com Reviewed-by:Fugang Duan <fugang.duan@nxp.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 82776f6 commit c97f2a6

1 file changed

Lines changed: 7 additions & 6 deletions

File tree

drivers/tty/serial/fsl_lpuart.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,10 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
314314
/* Forward declare this for the dma callbacks*/
315315
static void lpuart_dma_tx_complete(void *arg);
316316

317-
static inline bool is_ls1028a_lpuart(struct lpuart_port *sport)
317+
static inline bool is_layerscape_lpuart(struct lpuart_port *sport)
318318
{
319-
return sport->devtype == LS1028A_LPUART;
319+
return (sport->devtype == LS1021A_LPUART ||
320+
sport->devtype == LS1028A_LPUART);
320321
}
321322

322323
static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport)
@@ -1701,11 +1702,11 @@ static int lpuart32_startup(struct uart_port *port)
17011702
UARTFIFO_FIFOSIZE_MASK);
17021703

17031704
/*
1704-
* The LS1028A has a fixed length of 16 words. Although it supports the
1705-
* RX/TXSIZE fields their encoding is different. Eg the reference manual
1706-
* states 0b101 is 16 words.
1705+
* The LS1021A and LS1028A have a fixed FIFO depth of 16 words.
1706+
* Although they support the RX/TXSIZE fields, their encoding is
1707+
* different. Eg the reference manual states 0b101 is 16 words.
17071708
*/
1708-
if (is_ls1028a_lpuart(sport)) {
1709+
if (is_layerscape_lpuart(sport)) {
17091710
sport->rxfifo_size = 16;
17101711
sport->txfifo_size = 16;
17111712
sport->port.fifosize = sport->txfifo_size;

0 commit comments

Comments
 (0)