Skip to content

Commit d3d079b

Browse files
VCASTMgregkh
authored andcommitted
serial: stm32: prevent TDR register overwrite when sending x_char
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: 48a6092 ("serial: stm32-usart: Add STM32 USART Driver") Cc: stable <[email protected]> Signed-off-by: Valentin Caron <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 8838b2a commit d3d079b

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

drivers/tty/serial/stm32-usart.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,11 +550,23 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
550550
struct stm32_port *stm32_port = to_stm32_port(port);
551551
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
552552
struct circ_buf *xmit = &port->state->xmit;
553+
u32 isr;
554+
int ret;
553555

554556
if (port->x_char) {
555557
if (stm32_usart_tx_dma_started(stm32_port) &&
556558
stm32_usart_tx_dma_enabled(stm32_port))
557559
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
560+
561+
/* Check that TDR is empty before filling FIFO */
562+
ret =
563+
readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
564+
isr,
565+
(isr & USART_SR_TXE),
566+
10, 1000);
567+
if (ret)
568+
dev_warn(port->dev, "1 character may be erased\n");
569+
558570
writel_relaxed(port->x_char, port->membase + ofs->tdr);
559571
port->x_char = 0;
560572
port->icount.tx++;

0 commit comments

Comments
 (0)