Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3a16e7c authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by Greg Kroah-Hartman
Browse files

serial: stm32-usart: Correct CSIZE, bits, and parity



[ Upstream commit 1deeda8d2877c18bc2b9eeee10dd6d2628852848 ]

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: c8a9d043 (serial: stm32: fix word length configuration)
Cc: Erwan Le Ray <erwan.leray@st.com>
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220519081808.3776-9-ilpo.jarvinen@linux.intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 29d96363
Loading
Loading
Loading
Loading
+12 −3
Original line number Original line Diff line number Diff line
@@ -745,13 +745,22 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
	 * CS8 or (CS7 + parity), 8 bits word aka [M1:M0] = 0b00
	 * CS8 or (CS7 + parity), 8 bits word aka [M1:M0] = 0b00
	 * M0 and M1 already cleared by cr1 initialization.
	 * M0 and M1 already cleared by cr1 initialization.
	 */
	 */
	if (bits == 9)
	if (bits == 9) {
		cr1 |= USART_CR1_M0;
		cr1 |= USART_CR1_M0;
	else if ((bits == 7) && cfg->has_7bits_data)
	} else if ((bits == 7) && cfg->has_7bits_data) {
		cr1 |= USART_CR1_M1;
		cr1 |= USART_CR1_M1;
	else if (bits != 8)
	} else if (bits != 8) {
		dev_dbg(port->dev, "Unsupported data bits config: %u bits\n"
		dev_dbg(port->dev, "Unsupported data bits config: %u bits\n"
			, bits);
			, 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 ||
	if (ofs->rtor != UNDEF_REG && (stm32_port->rx_ch ||
				       stm32_port->fifoen)) {
				       stm32_port->fifoen)) {