Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6b93a90 authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent fe59d537
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1940,6 +1940,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);
@@ -2006,7 +2009,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;

@@ -2018,15 +2021,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);
+1 −0
Original line number Diff line number Diff line
@@ -319,6 +319,7 @@ struct uart_info {
#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;