Skip to content

Commit

Permalink
serial-core: restore termios settings when resume console ports
Browse files Browse the repository at this point in the history
The commit 4547be7 rewrites suspend and resume functions. According
to this rewrite, when a serial port is a printk console device and
can suspend(without set no_console_suspend flag), it will definitely
call set_termios function during its resume, but parameter termios
isn't initialized, this will pass an unpredictable config to the
serial port. If this serial port is not a userspace opened tty device
, a suspend and resume action will make this serial port unusable.
I.E. ttyS0 is a printk console device, ttyS1 or keyboard+display is
userspace tty device, a suspend/resume action will make ttyS0
unusable.

If a serial port is both a printk console device and an opened tty
device, this issue can be overcome because it will call set_termios
again with the correct parameter in the uart_change_speed function.

Refer to the deleted content of commit 4547be7, revert parts relate
to restore settings into parameter termios. It is safe because if
a serial port is a printk console only device, the only meaningful
field in termios is c_cflag and its old config is saved in
uport->cons->cflag, if this port is also an opened tty device,
it will clear uport->cons->cflag in the uart_open and the old config
is saved in tty->termios.

Signed-off-by: Jason Wang <jason77.wang@gmail.com>
Acked-by: Stanislav Brabec <sbrabec@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Jason Wang authored and Greg Kroah-Hartman committed Oct 22, 2010
1 parent ca2e71a commit 891b9dd
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions drivers/serial/serial_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,18 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
* Re-enable the console device after suspending.
*/
if (console_suspend_enabled && uart_console(uport)) {
/*
* First try to use the console cflag setting.
*/
memset(&termios, 0, sizeof(struct ktermios));
termios.c_cflag = uport->cons->cflag;

/*
* If that's unset, use the tty termios setting.
*/
if (port->tty && port->tty->termios && termios.c_cflag == 0)
termios = *(port->tty->termios);

uart_change_pm(state, 0);
uport->ops->set_termios(uport, &termios, NULL);
console_start(uport->cons);
Expand Down

0 comments on commit 891b9dd

Please sign in to comment.