From: Narendra Hadke nhadke@marvell.com
stable inclusion from stable-v5.10.137 commit 3bdda8656a1b74879f6b3889133ccc85decb0b3f category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I60PLB
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit a7209541239e5dd44d981289e5f9059222d40fd1 upstream.
For mvebu uart2, error bits are not cleared on buffer read. This causes interrupt loop and system hang.
Cc: stable@vger.kernel.org Reviewed-by: Yi Guo yi.guo@cavium.com Reviewed-by: Nadav Haklai nadavh@marvell.com Signed-off-by: Narendra Hadke nhadke@marvell.com Signed-off-by: Pali Rohár pali@kernel.org Link: https://lore.kernel.org/r/20220726091221.12358-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Wei Li liwei391@huawei.com --- drivers/tty/serial/mvebu-uart.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index e941f57de953..bbf1b0b37b11 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -238,6 +238,7 @@ static void mvebu_uart_rx_chars(struct uart_port *port, unsigned int status) struct tty_port *tport = &port->state->port; unsigned char ch = 0; char flag = 0; + int ret;
do { if (status & STAT_RX_RDY(port)) { @@ -250,6 +251,16 @@ static void mvebu_uart_rx_chars(struct uart_port *port, unsigned int status) port->icount.parity++; }
+ /* + * For UART2, error bits are not cleared on buffer read. + * This causes interrupt loop and system hang. + */ + if (IS_EXTENDED(port) && (status & STAT_BRK_ERR)) { + ret = readl(port->membase + UART_STAT); + ret |= STAT_BRK_ERR; + writel(ret, port->membase + UART_STAT); + } + if (status & STAT_BRK_DET) { port->icount.brk++; status &= ~(STAT_FRM_ERR | STAT_PAR_ERR);