Messages in this thread Patch in this message | | | Subject | [PATCH] serial-core: resume serial hardware with no_console_suspend | From | Stanislav Brabec <> | Date | Tue, 15 Sep 2009 15:38:58 +0200 |
| |
Hardware may need re-initialization to get serial port working after resume. It does not happen with no_console_suspend. Attached patch attempts to fix it.
The patch attempts to keep hardware running before suspend and run hardware re-initialization after resume. Maybe simpler approach is possible.
Signed-off-by: Stanislav Brabec <sbrabec@suse.cz>
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index b0bb29d..43cc1ab 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1990,12 +1990,6 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) mutex_lock(&state->mutex); - if (!console_suspend_enabled && uart_console(port)) { - /* we're going to avoid suspending serial console */ - mutex_unlock(&state->mutex); - return 0; - } - tty_dev = device_find_child(port->dev, &match, serial_match_port); if (device_may_wakeup(tty_dev)) { enable_irq_wake(port->irq); @@ -2003,20 +1997,23 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) mutex_unlock(&state->mutex); return 0; } - port->suspended = 1; + if (console_suspend_enabled || !uart_console(port)) + port->suspended = 1; if (state->info.flags & UIF_INITIALIZED) { const struct uart_ops *ops = port->ops; int tries; - state->info.flags = (state->info.flags & ~UIF_INITIALIZED) - | UIF_SUSPENDED; + if (console_suspend_enabled || !uart_console(port)) { + state->info.flags = (state->info.flags & ~UIF_INITIALIZED) + | UIF_SUSPENDED; - spin_lock_irq(&port->lock); - ops->stop_tx(port); - ops->set_mctrl(port, 0); - ops->stop_rx(port); - spin_unlock_irq(&port->lock); + spin_lock_irq(&port->lock); + ops->stop_tx(port); + ops->set_mctrl(port, 0); + ops->stop_rx(port); + spin_unlock_irq(&port->lock); + } /* * Wait for the transmitter to empty. @@ -2031,16 +2028,18 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) drv->dev_name, drv->tty_driver->name_base + port->line); - ops->shutdown(port); + if (console_suspend_enabled || !uart_console(port)) + ops->shutdown(port); } /* * Disable the console device before suspending. */ - if (uart_console(port)) + if (console_suspend_enabled && uart_console(port)) console_stop(port->cons); - uart_change_pm(state, 3); + if (console_suspend_enabled || !uart_console(port)) + uart_change_pm(state, 3); mutex_unlock(&state->mutex); @@ -2055,12 +2054,6 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) mutex_lock(&state->mutex); - if (!console_suspend_enabled && uart_console(port)) { - /* no need to resume serial console, it wasn't suspended */ - mutex_unlock(&state->mutex); - return 0; - } - tty_dev = device_find_child(port->dev, &match, serial_match_port); if (!port->suspended && device_may_wakeup(tty_dev)) { disable_irq_wake(port->irq); @@ -2100,21 +2093,23 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) spin_lock_irq(&port->lock); ops->set_mctrl(port, 0); spin_unlock_irq(&port->lock); - ret = ops->startup(port); - if (ret == 0) { - uart_change_speed(state, NULL); - spin_lock_irq(&port->lock); - ops->set_mctrl(port, port->mctrl); - ops->start_tx(port); - spin_unlock_irq(&port->lock); - state->info.flags |= UIF_INITIALIZED; - } else { - /* - * Failed to resume - maybe hardware went away? - * Clear the "initialized" flag so we won't try - * to call the low level drivers shutdown method. - */ - uart_shutdown(state); + if (console_suspend_enabled || !uart_console(port)) { + ret = ops->startup(port); + if (ret == 0) { + uart_change_speed(state, NULL); + spin_lock_irq(&port->lock); + ops->set_mctrl(port, port->mctrl); + ops->start_tx(port); + spin_unlock_irq(&port->lock); + state->info.flags |= UIF_INITIALIZED; + } else { + /* + * Failed to resume - maybe hardware went away? + * Clear the "initialized" flag so we won't try + * to call the low level drivers shutdown method. + */ + uart_shutdown(state); + } } state->info.flags &= ~UIF_SUSPENDED;
-- Best Regards / S pozdravem,
Stanislav Brabec software developer --------------------------------------------------------------------- SUSE LINUX, s. r. o. e-mail: sbrabec@suse.cz Lihovarská 1060/12 tel: +420 284 028 966, +49 911 740538747 190 00 Praha 9 fax: +420 284 028 951 Czech Republic http://www.suse.cz/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |