Skip to content

Commit 692a8eb

Browse files
mogasergiugregkh
authored andcommitted
tty: serial: atmel: Preserve previous USART mode if RS485 disabled
Whenever the atmel_rs485_config() driver method would be called, the USART mode is reset to normal mode before even checking if RS485 flag is set, thus resulting in losing the previous USART mode in the case where the checking fails. Some tools, such as `linux-serial-test`, lead to the driver calling this method when doing the setup of the serial port: after setting the port mode (Hardware Flow Control, Normal Mode, RS485 Mode, etc.), `linux-serial-test` tries to enable/disable RS485 depending on the commandline arguments that were passed. Example of how this issue could reveal itself: When doing a serial communication with Hardware Flow Control through `linux-serial-test`, the tool would lead to the driver roughly doing the following: - set the corresponding bit to 1 (ATMEL_US_USMODE_HWHS bit in the ATMEL_US_MR register) through the atmel_set_termios() to enable Hardware Flow Control - disable RS485 through the atmel_config_rs485() method Thus, when the latter is called, the mode will be reset and the previously set bit is unset, leaving USART in normal mode instead of the expected Hardware Flow Control mode. This fix ensures that this reset is only done if the checking for RS485 succeeds and that the previous mode is preserved otherwise. Fixes: e8faff7 ("ARM: 6092/1: atmel_serial: support for RS485 communications") Cc: stable <stable@kernel.org> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Sergiu Moga <sergiu.moga@microchip.com> Link: https://lore.kernel.org/r/20220824142902.502596-1-sergiu.moga@microchip.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent d5a2e08 commit 692a8eb

File tree

1 file changed

+1
-3
lines changed

1 file changed

+1
-3
lines changed

drivers/tty/serial/atmel_serial.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,6 @@ static int atmel_config_rs485(struct uart_port *port, struct ktermios *termios,
294294

295295
mode = atmel_uart_readl(port, ATMEL_US_MR);
296296

297-
/* Resetting serial mode to RS232 (0x0) */
298-
mode &= ~ATMEL_US_USMODE;
299-
300297
if (rs485conf->flags & SER_RS485_ENABLED) {
301298
dev_dbg(port->dev, "Setting UART to RS485\n");
302299
if (rs485conf->flags & SER_RS485_RX_DURING_TX)
@@ -306,6 +303,7 @@ static int atmel_config_rs485(struct uart_port *port, struct ktermios *termios,
306303

307304
atmel_uart_writel(port, ATMEL_US_TTGR,
308305
rs485conf->delay_rts_after_send);
306+
mode &= ~ATMEL_US_USMODE;
309307
mode |= ATMEL_US_USMODE_RS485;
310308
} else {
311309
dev_dbg(port->dev, "Setting UART to RS232\n");

0 commit comments

Comments
 (0)