]> git.baikalelectronics.ru Git - kernel.git/commitdiff
tty: serial: fsl_lpuart: skip waiting for transmission complete when UARTCTRL_SBK...
authorSherry Sun <sherry.sun@nxp.com>
Thu, 23 Feb 2023 09:39:41 +0000 (17:39 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Mar 2023 12:33:55 +0000 (13:33 +0100)
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 <sherry.sun@nxp.com>
Cc: stable <stable@kernel.org>
Link: https://lore.kernel.org/r/20230223093941.31790-1-sherry.sun@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/fsl_lpuart.c

index f9d667ce1619e985a379070c3c47c7fb2cb4846c..c51883f34ac2b56a19fa3ab5e71f2a0879b144af 100644 (file)
@@ -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),