Re: [PATCH] 8250: Don't restore NS16550 mode when console suspendis disabled

From: Deepak Saxena
Date: Wed May 13 2009 - 14:05:47 EST


On May 13 2009, at 16:35, Alan Cox was caught saying:
> Deepak's original patch from 2008 is actually much better. He puts the
> chip back in the right hardware configuration for the speed. He doesn't
> randomly regress other platforms and configurations and he does it by
> calling the standard methods in the driver to do the job.
>
> http://dev.laptop.org/~dsaxena/patches/console_suspend_old.patch
>
> It also has another advantage - it fixes the behaviour for almost
> everything in drivers/serial not just a specific uart. Technically he
> should take tty->termios_mutex before state->mutex in that code path as
> the upstream code has changed but in every other respect its the proper
> solution.

I thought the fact that we were touching a core driver to fix what
seemed like an XO issue was too intrusive.

> So can we apply Deepak's original correct 2008 patch instead please ?

I've updated it with proper header and attached.

~Deepak

Set proper console speed on resume if console suspend is disabled

Commit b5b82df6, from May 2007, breaks no_console_suspend on the OLPC
XO laptop. Basically what happens is that upon returning from resume,
serial8250_resume_port() will reconfigure the port for high speed
mode and all console output will be garbled, making debug of the
resume path painful. This patch modifies uart_resume_port() to
reset the port to the state it was in before we suspended.

Original patch by Marcelo Tosatti

Signed-off-by: Deepak Saxena <dsaxena@xxxxxxxxxx>

diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index b0bb29d..3b71038 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -2052,11 +2052,26 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
struct uart_state *state = drv->state + port->line;
struct device *tty_dev;
struct uart_match match = {port, drv};
+ struct ktermios termios;

mutex_lock(&state->mutex);

+ /*
+ * First try to use the console cflag setting.
+ */
+ memset(&termios, 0, sizeof(struct ktermios));
+ termios.c_cflag = port->cons->cflag;
+
+ /*
+ * If that's unset, use the tty termios setting.
+ */
+ if (termios.c_cflag == 0)
+ termios = *state->info.port.tty->termios;
+
+
if (!console_suspend_enabled && uart_console(port)) {
/* no need to resume serial console, it wasn't suspended */
+ port->ops->set_termios(port, &termios, NULL);
mutex_unlock(&state->mutex);
return 0;
}
@@ -2073,20 +2088,6 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
* Re-enable the console device after suspending.
*/
if (uart_console(port)) {
- struct ktermios termios;
-
- /*
- * First try to use the console cflag setting.
- */
- memset(&termios, 0, sizeof(struct ktermios));
- termios.c_cflag = port->cons->cflag;
-
- /*
- * If that's unset, use the tty termios setting.
- */
- if (state->info.port.tty && termios.c_cflag == 0)
- termios = *state->info.port.tty->termios;
-
uart_change_pm(state, 0);
port->ops->set_termios(port, &termios, NULL);
console_start(port->cons);