diff options
author | Jason Wang <jason77.wang@gmail.com> | 2010-08-21 03:14:42 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:20:02 -0400 |
commit | 891b9dd10764352926e1e107756aa229dfa2c210 (patch) | |
tree | 62b3ce0f32123fdd8de05044da2d06194ef90fdc /drivers/serial | |
parent | ca2e71aa8cfb0056ce720f3fd53f59f5fac4a3e1 (diff) |
serial-core: restore termios settings when resume console ports
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>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/serial_core.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index ff21200f94f4..bc6cddd10294 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -2066,6 +2066,18 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2066 | * Re-enable the console device after suspending. | 2066 | * Re-enable the console device after suspending. |
2067 | */ | 2067 | */ |
2068 | if (console_suspend_enabled && uart_console(uport)) { | 2068 | if (console_suspend_enabled && uart_console(uport)) { |
2069 | /* | ||
2070 | * First try to use the console cflag setting. | ||
2071 | */ | ||
2072 | memset(&termios, 0, sizeof(struct ktermios)); | ||
2073 | termios.c_cflag = uport->cons->cflag; | ||
2074 | |||
2075 | /* | ||
2076 | * If that's unset, use the tty termios setting. | ||
2077 | */ | ||
2078 | if (port->tty && port->tty->termios && termios.c_cflag == 0) | ||
2079 | termios = *(port->tty->termios); | ||
2080 | |||
2069 | uart_change_pm(state, 0); | 2081 | uart_change_pm(state, 0); |
2070 | uport->ops->set_termios(uport, &termios, NULL); | 2082 | uport->ops->set_termios(uport, &termios, NULL); |
2071 | console_start(uport->cons); | 2083 | console_start(uport->cons); |