Patch "tty: serial: fsl_lpuart: disable the CTS when send break signal" has been added to the 4.19-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    tty: serial: fsl_lpuart: disable the CTS when send break signal

to the 4.19-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     tty-serial-fsl_lpuart-disable-the-cts-when-send-brea.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 662171d477ba26884d08a8ca0fb4226e0d54bfe1
Author: Sherry Sun <sherry.sun@xxxxxxx>
Date:   Wed Dec 14 11:11:35 2022 +0800

    tty: serial: fsl_lpuart: disable the CTS when send break signal
    
    [ Upstream commit c4c81db5cf8bc53d6160c3abf26d382c841aa434 ]
    
    LPUART IP has a bug that it treats the CTS as higher priority than the
    break signal, which cause the break signal sending through UARTCTRL_SBK
    may impacted by the CTS input if the HW flow control is enabled.
    
    Add this workaround patch to fix the IP bug, we can disable CTS before
    asserting SBK to avoid any interference from CTS, and re-enable it when
    break off.
    
    Such as for the bluetooth chip power save feature, host can let the BT
    chip get into sleep state by sending a UART break signal, and wake it up
    by turning off the UART break. If the BT chip enters the sleep mode
    successfully, it will pull up the CTS line, if the BT chip is woken up,
    it will pull down the CTS line. If without this workaround patch, the
    UART TX pin cannot send the break signal successfully as it affected by
    the BT CTS pin. After adding this patch, the BT power save feature can
    work well.
    
    Signed-off-by: Sherry Sun <sherry.sun@xxxxxxx>
    Link: https://lore.kernel.org/r/20221214031137.28815-2-sherry.sun@xxxxxxx
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 069d02354c825..6ea1d23623e51 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1195,12 +1195,32 @@ static void lpuart_break_ctl(struct uart_port *port, int break_state)
 
 static void lpuart32_break_ctl(struct uart_port *port, int break_state)
 {
-	unsigned long temp;
+	unsigned long temp, modem;
+	struct tty_struct *tty;
+	unsigned int cflag = 0;
+
+	tty = tty_port_tty_get(&port->state->port);
+	if (tty) {
+		cflag = tty->termios.c_cflag;
+		tty_kref_put(tty);
+	}
 
 	temp = lpuart32_read(port, UARTCTRL) & ~UARTCTRL_SBK;
+	modem = lpuart32_read(port, UARTMODIR);
 
-	if (break_state != 0)
+	if (break_state != 0) {
 		temp |= UARTCTRL_SBK;
+		/*
+		 * LPUART CTS has higher priority than SBK, need to disable CTS before
+		 * asserting SBK to avoid any interference if flow control is enabled.
+		 */
+		if (cflag & CRTSCTS && modem & UARTMODIR_TXCTSE)
+			lpuart32_write(port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
+	} else {
+		/* Re-enable the CTS when break off. */
+		if (cflag & CRTSCTS && !(modem & UARTMODIR_TXCTSE))
+			lpuart32_write(port, modem | UARTMODIR_TXCTSE, UARTMODIR);
+	}
 
 	lpuart32_write(port, temp, UARTCTRL);
 }



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux