Patch "serial: stm32: prevent TDR register overwrite when sending x_char" has been added to the 5.10-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

    serial: stm32: prevent TDR register overwrite when sending x_char

to the 5.10-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:
     serial-stm32-prevent-tdr-register-overwrite-when-sen.patch
and it can be found in the queue-5.10 subdirectory.

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



commit 0bdd10a0970a47105a5f77da57df07d6a26d58e0
Author: Valentin Caron <valentin.caron@xxxxxxxxxxx>
Date:   Tue Jan 11 17:44:40 2022 +0100

    serial: stm32: prevent TDR register overwrite when sending x_char
    
    [ Upstream commit d3d079bde07e1b7deaeb57506dc0b86010121d17 ]
    
    When sending x_char in stm32_usart_transmit_chars(), driver can overwrite
    the value of TDR register by the value of x_char. If this happens, the
    previous value that was present in TDR register will not be sent through
    uart.
    
    This code checks if the previous value in TDR register is sent before
    writing the x_char value into register.
    
    Fixes: 48a6092fb41f ("serial: stm32-usart: Add STM32 USART Driver")
    Cc: stable <stable@xxxxxxxxxxxxxxx>
    Signed-off-by: Valentin Caron <valentin.caron@xxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20220111164441.6178-2-valentin.caron@xxxxxxxxxxx
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 0eadf0547175c..6afae051ba8d1 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -420,10 +420,22 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
 	struct stm32_port *stm32_port = to_stm32_port(port);
 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
 	struct circ_buf *xmit = &port->state->xmit;
+	u32 isr;
+	int ret;
 
 	if (port->x_char) {
 		if (stm32_port->tx_dma_busy)
 			stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+
+		/* Check that TDR is empty before filling FIFO */
+		ret =
+		readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
+						  isr,
+						  (isr & USART_SR_TXE),
+						  10, 1000);
+		if (ret)
+			dev_warn(port->dev, "1 character may be erased\n");
+
 		writel_relaxed(port->x_char, port->membase + ofs->tdr);
 		port->x_char = 0;
 		port->icount.tx++;



[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