79 lines
2.6 KiB
Diff
79 lines
2.6 KiB
Diff
From git-commits-head-owner@vger.kernel.org Wed Oct 4 17:49:26 2006
|
|
|
|
commit a6b93a908508810c5d51dd9b390283345af6f2d9
|
|
tree 71b48d3a659a025ebf333abfeec7b828becb60cb
|
|
parent fe59d5372ae719ca4550958f1e5bb4dd6eeac9cd
|
|
author Russell King <rmk@dyn-67.arm.linux.org.uk> 1159719460 +0100
|
|
committer Russell King <rmk+kernel@arm.linux.org.uk> 1159719460 +0100
|
|
|
|
[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>
|
|
|
|
fixed lined offset -maks
|
|
|
|
drivers/serial/serial_core.c | 9 +++++++--
|
|
include/linux/serial_core.h | 1 +
|
|
2 files changed, 8 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
|
|
index d814bb1..397147a 100644
|
|
--- a/drivers/serial/serial_core.c
|
|
+++ b/drivers/serial/serial_core.c
|
|
@@ -1932,6 +1932,9 @@ #endif
|
|
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 @@ #endif
|
|
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 @@ #endif
|
|
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);
|
|
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
|
|
index 86501a3..f9fdf97 100644
|
|
--- a/include/linux/serial_core.h
|
|
+++ b/include/linux/serial_core.h
|
|
@@ -319,6 +319,7 @@ #define UIF_CHECK_CD ((__force uif_t) (
|
|
#define UIF_CTS_FLOW ((__force uif_t) (1 << 26))
|
|
#define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29))
|
|
#define UIF_INITIALIZED ((__force uif_t) (1 << 31))
|
|
+#define UIF_SUSPENDED ((__force uif_t) (1 << 30))
|
|
|
|
int blocked_open;
|
|
|