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

Commit d5f735e5 authored by Pavel Machek's avatar Pavel Machek Committed by Linus Torvalds
Browse files

[PATCH] serial core: work around sub-driver bugs



We're presently getting oopses because Bluetooth (and possibly other) drivers
are calling core functions after things have been shut down.

So rather than oopsing, let's drop a warning then take avoiding action, so the
machine survives.  Once all the sub-drivers are fixed up we can remove the
take-avoiding-action part.

Signed-off-by: default avatarPavel Machek <pavel@suse.cz>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1c6cc5fd
Loading
Loading
Loading
Loading
+29 −3
Original line number Diff line number Diff line
@@ -71,6 +71,11 @@ static void uart_change_pm(struct uart_state *state, int pm_state);
void uart_write_wakeup(struct uart_port *port)
{
	struct uart_info *info = port->info;
	/*
	 * This means you called this function _after_ the port was
	 * closed.  No cookie for you.
	 */
	BUG_ON(!info);
	tasklet_schedule(&info->tlet);
}

@@ -474,11 +479,23 @@ static int
uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
	struct uart_state *state = tty->driver_data;
	struct uart_port *port = state->port;
	struct circ_buf *circ = &state->info->xmit;
	struct uart_port *port;
	struct circ_buf *circ;
	unsigned long flags;
	int c, ret = 0;

	/*
	 * This means you called this function _after_ the port was
	 * closed.  No cookie for you.
	 */
	if (!state || !state->info) {
		WARN_ON(1);
		return -EL3HLT;
	}

	port = state->port;
	circ = &state->info->xmit;

	if (!circ->buf)
		return 0;

@@ -521,6 +538,15 @@ static void uart_flush_buffer(struct tty_struct *tty)
	struct uart_port *port = state->port;
	unsigned long flags;

	/*
	 * This means you called this function _after_ the port was
	 * closed.  No cookie for you.
	 */
	if (!state || !state->info) {
		WARN_ON(1);
		return;
	}

	DPRINTK("uart_flush_buffer(%d) called\n", tty->index);

	spin_lock_irqsave(&port->lock, flags);