{
struct async_struct * info = tty->driver_data;
unsigned long orig_jiffies, char_time;
+ int tty_was_locked = tty_locked();
int lsr;
if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
orig_jiffies = jiffies;
- tty_lock_nested(); /* tty_wait_until_sent is called from lots of places */
+ /*
+ * tty_wait_until_sent is called from lots of places,
+ * with or without the BTM.
+ */
+ if (!tty_was_locked)
+ tty_lock();
/*
* Set the check interval to be 1/5 of the estimated time to
* send a single character, and make it at least 1. The check
break;
}
__set_current_state(TASK_RUNNING);
- tty_unlock();
+ if (!tty_was_locked)
+ tty_unlock();
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
#endif
printk("jiff=%lu...", jiffies);
#endif
- tty_lock_nested(); /* always held already since we come from ->close */
/* We go through the loop at least once because we can't tell
* exactly when the last character exits the shifter. There can
* be at least two characters waiting to be sent after the buffers
bdp--;
} while (bdp->status & BD_SC_READY);
current->state = TASK_RUNNING;
- tty_unlock();
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
#endif
static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
struct ktermios *old_termios);
-static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
+static void __uart_wait_until_sent(struct uart_port *port, int timeout);
static void uart_change_pm(struct uart_state *state, int pm_state);
/*
tty->closing = 1;
spin_unlock_irqrestore(&port->lock, flags);
- if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
+ if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+ /*
+ * hack: open-coded tty_wait_until_sent to avoid
+ * recursive tty_lock
+ */
+ long timeout = msecs_to_jiffies(port->closing_wait);
+ if (wait_event_interruptible_timeout(tty->write_wait,
+ !tty_chars_in_buffer(tty), timeout) >= 0)
+ __uart_wait_until_sent(uport, timeout);
+ }
/*
* At this point, we stop accepting input. To do this, we
* has completely drained; this is especially
* important if there is a transmit FIFO!
*/
- uart_wait_until_sent(tty, uport->timeout);
+ __uart_wait_until_sent(uport, uport->timeout);
}
uart_shutdown(tty, state);
mutex_unlock(&port->mutex);
}
-static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
+static void __uart_wait_until_sent(struct uart_port *port, int timeout)
{
- struct uart_state *state = tty->driver_data;
- struct uart_port *port = state->uart_port;
unsigned long char_time, expire;
if (port->type == PORT_UNKNOWN || port->fifosize == 0)
return;
- tty_lock_nested(); /* already locked when coming from close */
-
/*
* Set the check interval to be 1/5 of the estimated time to
* send a single character, and make it at least 1. The check
break;
}
set_current_state(TASK_RUNNING); /* might not be needed */
+}
+
+static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+ struct uart_state *state = tty->driver_data;
+ struct uart_port *port = state->uart_port;
+
+ tty_lock();
+ __uart_wait_until_sent(port, timeout);
tty_unlock();
}