]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
serial: stm32-usart: Correct CSIZE, bits, and parity
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Thu, 19 May 2022 08:18:07 +0000 (11:18 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 May 2022 16:32:40 +0000 (18:32 +0200)
Add CSIZE sanitization for unsupported CSIZE configurations. In
addition, if parity is asked for but CSx was unsupported, the sensible
result is CS8+parity which requires setting USART_CR1_M0 like with 9
bits.

Incorrect CSIZE results in miscalculation of the frame bits in
tty_get_char_size() or in its predecessor where the roughly the same
code is directly within uart_update_timeout().

Fixes: c8a9d043947b (serial: stm32: fix word length configuration)
Cc: Erwan Le Ray <erwan.leray@st.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220519081808.3776-9-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/stm32-usart.c

index 764415b8e8f03861f14334973b92a682e5b9627d..b7b44f4050d49acace4a4ac48fa7a1b01ec8d561 100644 (file)
@@ -1088,13 +1088,22 @@ static void stm32_usart_set_termios(struct uart_port *port,
         * CS8 or (CS7 + parity), 8 bits word aka [M1:M0] = 0b00
         * M0 and M1 already cleared by cr1 initialization.
         */
-       if (bits == 9)
+       if (bits == 9) {
                cr1 |= USART_CR1_M0;
-       else if ((bits == 7) && cfg->has_7bits_data)
+       } else if ((bits == 7) && cfg->has_7bits_data) {
                cr1 |= USART_CR1_M1;
-       else if (bits != 8)
+       } else if (bits != 8) {
                dev_dbg(port->dev, "Unsupported data bits config: %u bits\n"
                        , bits);
+               cflag &= ~CSIZE;
+               cflag |= CS8;
+               termios->c_cflag = cflag;
+               bits = 8;
+               if (cflag & PARENB) {
+                       bits++;
+                       cr1 |= USART_CR1_M0;
+               }
+       }
 
        if (ofs->rtor != UNDEF_REG && (stm32_port->rx_ch ||
                                       (stm32_port->fifoen &&