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

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



commit ea7be0e69f83dbf28be5787229e6ac8f0802dde3
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 200cd293d14d5..810a1b0b65203 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -421,10 +421,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