From: Sherry Sun Date: Thu, 23 Feb 2023 09:39:41 +0000 (+0800) Subject: tty: serial: fsl_lpuart: skip waiting for transmission complete when UARTCTRL_SBK... X-Git-Tag: baikal/mips/sdk6.1~85 X-Git-Url: https://git.baikalelectronics.ru/sdk/?a=commitdiff_plain;h=d8aef680904f5cfc9fa5fb0b3dc586a1bdcc942c;p=kernel.git tty: serial: fsl_lpuart: skip waiting for transmission complete when UARTCTRL_SBK is asserted commit 0655203e4c78c41d4f3dfb93bc417b1e9c895faf upstream. According to LPUART RM, Transmission Complete Flag becomes 0 if queuing a break character by writing 1 to CTRL[SBK], so here need to skip waiting for transmission complete when UARTCTRL_SBK is asserted, otherwise the kernel may stuck here. And actually set_termios() adds transmission completion waiting to avoid data loss or data breakage when changing the baud rate, but we don't need to worry about this when queuing break characters. Signed-off-by: Sherry Sun Cc: stable Link: https://lore.kernel.org/r/20230223093941.31790-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index f9d667ce1619e..c51883f34ac2b 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2184,9 +2184,15 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); - /* wait transmit engin complete */ - lpuart32_write(&sport->port, 0, UARTMODIR); - lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC); + /* + * LPUART Transmission Complete Flag may never be set while queuing a break + * character, so skip waiting for transmission complete when UARTCTRL_SBK is + * asserted. + */ + if (!(old_ctrl & UARTCTRL_SBK)) { + lpuart32_write(&sport->port, 0, UARTMODIR); + lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC); + } /* disable transmit and receive */ lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),