summaryrefslogtreecommitdiff
path: root/drivers/tty
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-22 10:40:22 +0200
commit607938e2f8ebe4c35a5ccc03851d55d562437df2 (patch)
tree44a958340f0760d630fb5879c4f208ee7674c2cd /drivers/tty
parenta0285e90a759843cc93f95c86b4aa9f5cd5f842c (diff)
downloadlinux-607938e2f8ebe4c35a5ccc03851d55d562437df2.tar.gz
linux-607938e2f8ebe4c35a5ccc03851d55d562437df2.tar.bz2
linux-607938e2f8ebe4c35a5ccc03851d55d562437df2.zip
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')
-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 ea8b591dd46f..f325019887b2 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -476,8 +476,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned int baud;
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;
@@ -486,6 +487,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);