aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2010-06-01 16:52:57 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 16:47:42 -0400
commit61cd8a21d8a9fb4b11111270cf2d3aa919c20624 (patch)
treeb390c27925f168a4cec35446b300c4d51657f86d /drivers/serial
parent8ce73264b75be4d5ed480440ac32dfc1f25ff678 (diff)
serial: Change the wait for carrier locking
We want to push the lock/unlock into the helper functions so that we can prepare to move to using the tty_port helper. The expansion initially comes out a bit ugly but its worth the temporary expansion IMHO just so we can produce a nice testable series of changes. Signed-off-by: Alan Cox <alan@linux.intel.com> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/serial_core.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 570dca2935e2..424b1c7e50c4 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1272,6 +1272,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1272 struct uart_state *state = tty->driver_data; 1272 struct uart_state *state = tty->driver_data;
1273 struct tty_port *port; 1273 struct tty_port *port;
1274 struct uart_port *uport; 1274 struct uart_port *uport;
1275 unsigned long flags;
1275 1276
1276 BUG_ON(!kernel_locked()); 1277 BUG_ON(!kernel_locked());
1277 1278
@@ -1284,9 +1285,12 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1284 pr_debug("uart_close(%d) called\n", uport->line); 1285 pr_debug("uart_close(%d) called\n", uport->line);
1285 1286
1286 mutex_lock(&port->mutex); 1287 mutex_lock(&port->mutex);
1288 spin_lock_irqsave(&port->lock, flags);
1287 1289
1288 if (tty_hung_up_p(filp)) 1290 if (tty_hung_up_p(filp)) {
1291 spin_unlock_irqrestore(&port->lock, flags);
1289 goto done; 1292 goto done;
1293 }
1290 1294
1291 if ((tty->count == 1) && (port->count != 1)) { 1295 if ((tty->count == 1) && (port->count != 1)) {
1292 /* 1296 /*
@@ -1305,8 +1309,10 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1305 tty->name, port->count); 1309 tty->name, port->count);
1306 port->count = 0; 1310 port->count = 0;
1307 } 1311 }
1308 if (port->count) 1312 if (port->count) {
1313 spin_unlock_irqrestore(&port->lock, flags);
1309 goto done; 1314 goto done;
1315 }
1310 1316
1311 /* 1317 /*
1312 * Now we wait for the transmit buffer to clear; and we notify 1318 * Now we wait for the transmit buffer to clear; and we notify
@@ -1314,6 +1320,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1314 * setting tty->closing. 1320 * setting tty->closing.
1315 */ 1321 */
1316 tty->closing = 1; 1322 tty->closing = 1;
1323 spin_unlock_irqrestore(&port->lock, flags);
1317 1324
1318 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 1325 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1319 tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait)); 1326 tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
@@ -1340,20 +1347,26 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1340 1347
1341 tty_ldisc_flush(tty); 1348 tty_ldisc_flush(tty);
1342 1349
1343 tty->closing = 0;
1344 tty_port_tty_set(port, NULL); 1350 tty_port_tty_set(port, NULL);
1351 spin_lock_irqsave(&port->lock, flags);
1352 tty->closing = 0;
1345 1353
1346 if (port->blocked_open) { 1354 if (port->blocked_open) {
1355 spin_unlock_irqrestore(&port->lock, flags);
1347 if (port->close_delay) 1356 if (port->close_delay)
1348 msleep_interruptible(port->close_delay); 1357 msleep_interruptible(port->close_delay);
1358 spin_lock_irqsave(&port->lock, flags);
1349 } else if (!uart_console(uport)) { 1359 } else if (!uart_console(uport)) {
1360 spin_unlock_irqrestore(&port->lock, flags);
1350 uart_change_pm(state, 3); 1361 uart_change_pm(state, 3);
1362 spin_lock_irqsave(&port->lock, flags);
1351 } 1363 }
1352 1364
1353 /* 1365 /*
1354 * Wake up anyone trying to open this port. 1366 * Wake up anyone trying to open this port.
1355 */ 1367 */
1356 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); 1368 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
1369 spin_unlock_irqrestore(&port->lock, flags);
1357 wake_up_interruptible(&port->open_wait); 1370 wake_up_interruptible(&port->open_wait);
1358 1371
1359done: 1372done:
@@ -1429,6 +1442,7 @@ static void uart_hangup(struct tty_struct *tty)
1429{ 1442{
1430 struct uart_state *state = tty->driver_data; 1443 struct uart_state *state = tty->driver_data;
1431 struct tty_port *port = &state->port; 1444 struct tty_port *port = &state->port;
1445 unsigned long flags;
1432 1446
1433 BUG_ON(!kernel_locked()); 1447 BUG_ON(!kernel_locked());
1434 pr_debug("uart_hangup(%d)\n", state->uart_port->line); 1448 pr_debug("uart_hangup(%d)\n", state->uart_port->line);
@@ -1437,8 +1451,10 @@ static void uart_hangup(struct tty_struct *tty)
1437 if (port->flags & ASYNC_NORMAL_ACTIVE) { 1451 if (port->flags & ASYNC_NORMAL_ACTIVE) {
1438 uart_flush_buffer(tty); 1452 uart_flush_buffer(tty);
1439 uart_shutdown(tty, state); 1453 uart_shutdown(tty, state);
1454 spin_lock_irqsave(&port->lock, flags);
1440 port->count = 0; 1455 port->count = 0;
1441 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); 1456 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
1457 spin_unlock_irqrestore(&port->lock, flags);
1442 tty_port_tty_set(port, NULL); 1458 tty_port_tty_set(port, NULL);
1443 wake_up_interruptible(&port->open_wait); 1459 wake_up_interruptible(&port->open_wait);
1444 wake_up_interruptible(&port->delta_msr_wait); 1460 wake_up_interruptible(&port->delta_msr_wait);
@@ -1496,9 +1512,13 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
1496 struct uart_port *uport = state->uart_port; 1512 struct uart_port *uport = state->uart_port;
1497 struct tty_port *port = &state->port; 1513 struct tty_port *port = &state->port;
1498 unsigned int mctrl; 1514 unsigned int mctrl;
1515 unsigned long flags;
1499 1516
1517 spin_lock_irqsave(&port->lock, flags);
1518 if (!tty_hung_up_p(filp))
1519 port->count--;
1500 port->blocked_open++; 1520 port->blocked_open++;
1501 port->count--; 1521 spin_unlock_irqrestore(&port->lock, flags);
1502 1522
1503 add_wait_queue(&port->open_wait, &wait); 1523 add_wait_queue(&port->open_wait, &wait);
1504 while (1) { 1524 while (1) {
@@ -1535,23 +1555,26 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
1535 * not set RTS here - we want to make sure we catch 1555 * not set RTS here - we want to make sure we catch
1536 * the data from the modem. 1556 * the data from the modem.
1537 */ 1557 */
1538 if (port->tty->termios->c_cflag & CBAUD) 1558 if (port->tty->termios->c_cflag & CBAUD) {
1559 mutex_lock(&port->mutex);
1539 uart_set_mctrl(uport, TIOCM_DTR); 1560 uart_set_mctrl(uport, TIOCM_DTR);
1561 mutex_unlock(&port->mutex);
1562 }
1540 1563
1541 /* 1564 /*
1542 * and wait for the carrier to indicate that the 1565 * and wait for the carrier to indicate that the
1543 * modem is ready for us. 1566 * modem is ready for us.
1544 */ 1567 */
1568 mutex_lock(&port->mutex);
1545 spin_lock_irq(&uport->lock); 1569 spin_lock_irq(&uport->lock);
1546 uport->ops->enable_ms(uport); 1570 uport->ops->enable_ms(uport);
1547 mctrl = uport->ops->get_mctrl(uport); 1571 mctrl = uport->ops->get_mctrl(uport);
1548 spin_unlock_irq(&uport->lock); 1572 spin_unlock_irq(&uport->lock);
1573 mutex_unlock(&port->mutex);
1549 if (mctrl & TIOCM_CAR) 1574 if (mctrl & TIOCM_CAR)
1550 break; 1575 break;
1551 1576
1552 mutex_unlock(&port->mutex);
1553 schedule(); 1577 schedule();
1554 mutex_lock(&port->mutex);
1555 1578
1556 if (signal_pending(current)) 1579 if (signal_pending(current))
1557 break; 1580 break;
@@ -1559,8 +1582,11 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
1559 set_current_state(TASK_RUNNING); 1582 set_current_state(TASK_RUNNING);
1560 remove_wait_queue(&port->open_wait, &wait); 1583 remove_wait_queue(&port->open_wait, &wait);
1561 1584
1562 port->count++; 1585 spin_lock_irqsave(&port->lock, flags);
1586 if (!tty_hung_up_p(filp))
1587 port->count++;
1563 port->blocked_open--; 1588 port->blocked_open--;
1589 spin_unlock_irqrestore(&port->lock, flags);
1564 1590
1565 if (signal_pending(current)) 1591 if (signal_pending(current))
1566 return -ERESTARTSYS; 1592 return -ERESTARTSYS;
@@ -1677,9 +1703,9 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
1677 /* 1703 /*
1678 * If we succeeded, wait until the port is ready. 1704 * If we succeeded, wait until the port is ready.
1679 */ 1705 */
1706 mutex_unlock(&port->mutex);
1680 if (retval == 0) 1707 if (retval == 0)
1681 retval = uart_block_til_ready(filp, state); 1708 retval = uart_block_til_ready(filp, state);
1682 mutex_unlock(&port->mutex);
1683 1709
1684 /* 1710 /*
1685 * If this is the first open to succeed, adjust things to suit. 1711 * If this is the first open to succeed, adjust things to suit.