Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 207913
b: refs/heads/master
c: 2036521
h: refs/heads/master
i:
  207911: 5ed1f2d
v: v3
  • Loading branch information
Arnd Bergmann authored and Greg Kroah-Hartman committed Aug 10, 2010
1 parent 9763e6f commit 6609761
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 60af22d2ed490554cc92c8d0fed0b5b9cf687568
refs/heads/master: 203652192634c1fce5e79df0a8ff2fabfaefd3ab
11 changes: 9 additions & 2 deletions trunk/drivers/char/amiserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
{
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"))
Expand All @@ -1538,7 +1539,12 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)

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
Expand Down Expand Up @@ -1579,7 +1585,8 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
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
Expand Down
2 changes: 0 additions & 2 deletions trunk/drivers/serial/68360serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -1705,7 +1705,6 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
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
Expand Down Expand Up @@ -1734,7 +1733,6 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
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
Expand Down
2 changes: 0 additions & 2 deletions trunk/drivers/serial/crisv10.c
Original file line number Diff line number Diff line change
Expand Up @@ -3935,7 +3935,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
* Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO
* R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k)
*/
tty_lock_nested(); /* locked already when coming from close */
orig_jiffies = jiffies;
while (info->xmit.head != info->xmit.tail || /* More in send queue */
(*info->ostatusadr & 0x007f) || /* more in FIFO */
Expand All @@ -3952,7 +3951,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
curr_time_usec - info->last_tx_active_usec;
}
set_current_state(TASK_RUNNING);
tty_unlock();
}

/*
Expand Down
31 changes: 22 additions & 9 deletions trunk/drivers/serial/serial_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static struct lock_class_key port_lock_key;

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);

/*
Expand Down Expand Up @@ -1322,8 +1322,16 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
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
Expand All @@ -1339,7 +1347,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
* 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);
Expand Down Expand Up @@ -1373,17 +1381,13 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
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
Expand Down Expand Up @@ -1429,6 +1433,15 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
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();
}

Expand Down

0 comments on commit 6609761

Please sign in to comment.