diff options
| author | Erwan Le Ray <erwan.leray@foss.st.com> | 2021-03-04 17:22:58 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-05-22 10:40:22 +0200 |
| commit | 607938e2f8ebe4c35a5ccc03851d55d562437df2 (patch) | |
| tree | 44a958340f0760d630fb5879c4f208ee7674c2cd /drivers/tty | |
| parent | a0285e90a759843cc93f95c86b4aa9f5cd5f842c (diff) | |
| download | linux-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.c | 12 |
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); |
