summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2006-10-17 13:26:34 +0200
committerChris Wright <chrisw@sous-sol.org>2006-11-03 17:33:46 -0800
commit4d496dde1429e99c49070190cb4ec1f3c3effbdd (patch)
tree86e7f955609c5acfce065d63ca2d1467e217012e /drivers
parent9b1bb2cd3271ea65aad59708d466917f368562cf (diff)
[PATCH] SERIAL: Fix oops when removing suspended serial port
[SERIAL] Fix oops when removing suspended serial port A serial card might have been removed when the system is resumed. This results in a suspended port being shut down, which results in the ports shutdown method being called twice in a row. This causes BUGs. Avoid this by tracking the suspended state separately from the initialised state. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: maximilian attems <maks@sternwelten.at> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/serial/serial_core.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 372e47f7d596..c59dcb7a8d66 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1932,6 +1932,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
if (state->info && state->info->flags & UIF_INITIALIZED) {
const struct uart_ops *ops = port->ops;
+ state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
+ | UIF_SUSPENDED;
+
spin_lock_irq(&port->lock);
ops->stop_tx(port);
ops->set_mctrl(port, 0);
@@ -1991,7 +1994,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
console_start(port->cons);
}
- if (state->info && state->info->flags & UIF_INITIALIZED) {
+ if (state->info && state->info->flags & UIF_SUSPENDED) {
const struct uart_ops *ops = port->ops;
int ret;
@@ -2003,15 +2006,17 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
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.
*/
- state->info->flags &= ~UIF_INITIALIZED;
uart_shutdown(state);
}
+
+ state->info->flags &= ~UIF_SUSPENDED;
}
mutex_unlock(&state->mutex);