]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
4619dcbe1b93b7e5002df1984349b403d68d4756
[thirdparty/kernel/stable-queue.git] /
1 From 2411fd94ceaa6e11326e95d6ebf876cbfed28d23 Mon Sep 17 00:00:00 2001
2 From: Sherry Sun <sherry.sun@nxp.com>
3 Date: Thu, 23 Feb 2023 17:39:41 +0800
4 Subject: tty: serial: fsl_lpuart: skip waiting for transmission complete when UARTCTRL_SBK is asserted
5
6 From: Sherry Sun <sherry.sun@nxp.com>
7
8 commit 2411fd94ceaa6e11326e95d6ebf876cbfed28d23 upstream.
9
10 According to LPUART RM, Transmission Complete Flag becomes 0 if queuing
11 a break character by writing 1 to CTRL[SBK], so here need to skip
12 waiting for transmission complete when UARTCTRL_SBK is asserted,
13 otherwise the kernel may stuck here.
14 And actually set_termios() adds transmission completion waiting to avoid
15 data loss or data breakage when changing the baud rate, but we don't
16 need to worry about this when queuing break characters.
17
18 Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
19 Cc: stable <stable@kernel.org>
20 Link: https://lore.kernel.org/r/20230223093941.31790-1-sherry.sun@nxp.com
21 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22 ---
23 drivers/tty/serial/fsl_lpuart.c | 12 +++++++++---
24 1 file changed, 9 insertions(+), 3 deletions(-)
25
26 --- a/drivers/tty/serial/fsl_lpuart.c
27 +++ b/drivers/tty/serial/fsl_lpuart.c
28 @@ -2185,9 +2185,15 @@ lpuart32_set_termios(struct uart_port *p
29 /* update the per-port timeout */
30 uart_update_timeout(port, termios->c_cflag, baud);
31
32 - /* wait transmit engin complete */
33 - lpuart32_write(&sport->port, 0, UARTMODIR);
34 - lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
35 + /*
36 + * LPUART Transmission Complete Flag may never be set while queuing a break
37 + * character, so skip waiting for transmission complete when UARTCTRL_SBK is
38 + * asserted.
39 + */
40 + if (!(old_ctrl & UARTCTRL_SBK)) {
41 + lpuart32_write(&sport->port, 0, UARTMODIR);
42 + lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
43 + }
44
45 /* disable transmit and receive */
46 lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),