summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/stm32-usart.c
diff options
context:
space:
mode:
authorErwan Le Ray <erwan.leray@foss.st.com>2021-03-04 17:22:58 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-05-14 09:44:16 +0200
commit12e423331ec9cb740bdf3d14fd8a3504a2ef7721 (patch)
treebd462ef571f4d22981a2d8e43812a5ef21ef6855 /drivers/tty/serial/stm32-usart.c
parent6be27923140ac350f51bb94132a9ba1fbf274aab (diff)
serial: stm32: fix incorrect characters on console
[ Upstream commit f264c6f6aece81a9f8fbdf912b20bd3feb476a7a ] Incorrect characters are observed on console during boot. This issue occurs when init/main.c is modifying termios settings to open /dev/console on the rootfs. This patch adds a waiting loop in set_termios to wait for TX shift register empty (and TX FIFO if any) before stopping serial port. Fixes: 48a6092fb41f ("serial: stm32-usart: Add STM32 USART Driver") Signed-off-by: Erwan Le Ray <erwan.leray@foss.st.com> Link: https://lore.kernel.org/r/20210304162308.8984-4-erwan.leray@foss.st.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/tty/serial/stm32-usart.c')
-rw-r--r--drivers/tty/serial/stm32-usart.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index bf83e6c212f5..6756f73fb220 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -688,8 +688,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned int baud, bits;
u32 usartdiv, mantissa, fraction, oversampling;
tcflag_t cflag = termios->c_cflag;
- u32 cr1, cr2, cr3;
+ u32 cr1, cr2, cr3, isr;
unsigned long flags;
+ int ret;
if (!stm32_port->hw_flow_control)
cflag &= ~CRTSCTS;
@@ -698,6 +699,15 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
spin_lock_irqsave(&port->lock, flags);
+ ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
+ isr,
+ (isr & USART_SR_TC),
+ 10, 100000);
+
+ /* Send the TC error message only when ISR_TC is not set. */
+ if (ret)
+ dev_err(port->dev, "Transmission is not complete\n");
+
/* Stop serial port and reset value */
writel_relaxed(0, port->membase + ofs->cr1);