]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
serial: stm32: fix incorrect characters on console
authorErwan Le Ray <erwan.leray@foss.st.com>
Thu, 4 Mar 2021 16:22:58 +0000 (17:22 +0100)
committerKelsey Skunberg <kelsey.skunberg@canonical.com>
Mon, 24 May 2021 23:46:18 +0000 (17:46 -0600)
BugLink: https://bugs.launchpad.net/bugs/1929455
[ 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>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Kelsey Skunberg <kelsey.skunberg@canonical.com>
drivers/tty/serial/stm32-usart.c

index 909a0d991ba1d471cbef765b90f97af27730bb69..70155e0c3b021df6801461927ac754eea9c7e7e7 100644 (file)
@@ -736,8 +736,9 @@ static void stm32_usart_set_termios(struct uart_port *port,
        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;
@@ -746,6 +747,15 @@ static void stm32_usart_set_termios(struct uart_port *port,
 
        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);