Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: kref nozomi

Update the nozomi driver to use krefs

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Alan Cox and committed by
Linus Torvalds
33dd474a c9f19e96

+45 -40
+45 -40
drivers/char/nozomi.c
··· 353 353 354 354 /* This holds all information that is needed regarding a port */ 355 355 struct port { 356 + struct tty_port port; 356 357 u8 update_flow_control; 357 358 struct ctrl_ul ctrl_ul; 358 359 struct ctrl_dl ctrl_dl; ··· 366 365 u8 toggle_ul; 367 366 u16 token_dl; 368 367 369 - struct tty_struct *tty; 370 - int tty_open_count; 371 368 /* mutex to ensure one access patch to this port */ 372 369 struct mutex tty_sem; 373 370 wait_queue_head_t tty_wait; ··· 787 788 * Return 1 - send buffer to card and ack. 788 789 * Return 0 - don't ack, don't send buffer to card. 789 790 */ 790 - static int send_data(enum port_type index, const struct nozomi *dc) 791 + static int send_data(enum port_type index, struct nozomi *dc) 791 792 { 792 793 u32 size = 0; 793 - const struct port *port = &dc->port[index]; 794 + struct port *port = &dc->port[index]; 794 795 const u8 toggle = port->toggle_ul; 795 796 void __iomem *addr = port->ul_addr[toggle]; 796 797 const u32 ul_size = port->ul_size[toggle]; 797 - struct tty_struct *tty = port->tty; 798 + struct tty_struct *tty = tty_port_tty_get(&port->port); 798 799 799 800 /* Get data from tty and place in buf for now */ 800 801 size = __kfifo_get(port->fifo_ul, dc->send_buf, ··· 802 803 803 804 if (size == 0) { 804 805 DBG4("No more data to send, disable link:"); 806 + tty_kref_put(tty); 805 807 return 0; 806 808 } 807 809 ··· 815 815 if (tty) 816 816 tty_wakeup(tty); 817 817 818 + tty_kref_put(tty); 818 819 return 1; 819 820 } 820 821 ··· 827 826 u32 offset = 4; 828 827 struct port *port = &dc->port[index]; 829 828 void __iomem *addr = port->dl_addr[port->toggle_dl]; 830 - struct tty_struct *tty = port->tty; 829 + struct tty_struct *tty = tty_port_tty_get(&port->port); 831 830 int i; 832 831 833 832 if (unlikely(!tty)) { ··· 871 870 } 872 871 873 872 set_bit(index, &dc->flip); 874 - 873 + tty_kref_put(tty); 875 874 return 1; 876 875 } 877 876 ··· 1277 1276 1278 1277 exit_handler: 1279 1278 spin_unlock(&dc->spin_mutex); 1280 - for (a = 0; a < NOZOMI_MAX_PORTS; a++) 1281 - if (test_and_clear_bit(a, &dc->flip)) 1282 - tty_flip_buffer_push(dc->port[a].tty); 1279 + for (a = 0; a < NOZOMI_MAX_PORTS; a++) { 1280 + struct tty_struct *tty; 1281 + if (test_and_clear_bit(a, &dc->flip)) { 1282 + tty = tty_port_tty_get(&dc->port[a].port); 1283 + if (tty) 1284 + tty_flip_buffer_push(tty); 1285 + tty_kref_put(tty); 1286 + } 1287 + } 1283 1288 return IRQ_HANDLED; 1284 1289 none: 1285 1290 spin_unlock(&dc->spin_mutex); ··· 1460 1453 1461 1454 for (i = 0; i < MAX_PORT; i++) { 1462 1455 mutex_init(&dc->port[i].tty_sem); 1463 - dc->port[i].tty_open_count = 0; 1464 - dc->port[i].tty = NULL; 1456 + tty_port_init(&dc->port[i].port); 1465 1457 tty_register_device(ntty_driver, dc->index_start + i, 1466 1458 &pdev->dev); 1467 1459 } 1468 - 1469 1460 return 0; 1470 1461 1471 1462 err_free_sbuf: ··· 1487 1482 1488 1483 flush_scheduled_work(); 1489 1484 1490 - for (i = 0; i < MAX_PORT; ++i) 1491 - if (dc->port[i].tty && \ 1492 - list_empty(&dc->port[i].tty->hangup_work.entry)) 1493 - tty_hangup(dc->port[i].tty); 1494 - 1485 + for (i = 0; i < MAX_PORT; ++i) { 1486 + struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port); 1487 + if (tty && list_empty(&tty->hangup_work.entry)) 1488 + tty_hangup(tty); 1489 + tty_kref_put(tty); 1490 + } 1491 + /* Racy below - surely should wait for scheduled work to be done or 1492 + complete off a hangup method ? */ 1495 1493 while (dc->open_ttys) 1496 1494 msleep(1); 1497 - 1498 1495 for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) 1499 1496 tty_unregister_device(ntty_driver, i); 1500 1497 } ··· 1586 1579 if (mutex_lock_interruptible(&port->tty_sem)) 1587 1580 return -ERESTARTSYS; 1588 1581 1589 - port->tty_open_count++; 1582 + port->port.count++; 1590 1583 dc->open_ttys++; 1591 1584 1592 1585 /* Enable interrupt downlink for channel */ 1593 - if (port->tty_open_count == 1) { 1586 + if (port->port.count == 1) { 1587 + /* FIXME: is this needed now ? */ 1594 1588 tty->low_latency = 1; 1595 1589 tty->driver_data = port; 1596 - port->tty = tty; 1590 + tty_port_tty_set(&port->port, tty); 1597 1591 DBG1("open: %d", port->token_dl); 1598 1592 spin_lock_irqsave(&dc->spin_mutex, flags); 1599 1593 dc->last_ier = dc->last_ier | port->token_dl; 1600 1594 writew(dc->last_ier, dc->reg_ier); 1601 1595 spin_unlock_irqrestore(&dc->spin_mutex, flags); 1602 1596 } 1603 - 1604 1597 mutex_unlock(&port->tty_sem); 1605 - 1606 1598 return 0; 1607 1599 } 1608 1600 ··· 1612 1606 static void ntty_close(struct tty_struct *tty, struct file *file) 1613 1607 { 1614 1608 struct nozomi *dc = get_dc_by_tty(tty); 1615 - struct port *port = tty->driver_data; 1609 + struct port *nport = tty->driver_data; 1610 + struct tty_port *port = &nport->port; 1616 1611 unsigned long flags; 1617 1612 1618 - if (!dc || !port) 1613 + if (!dc || !nport) 1619 1614 return; 1620 1615 1621 - if (mutex_lock_interruptible(&port->tty_sem)) 1622 - return; 1616 + /* Users cannot interrupt a close */ 1617 + mutex_lock(&nport->tty_sem); 1623 1618 1624 - if (!port->tty_open_count) 1625 - goto exit; 1619 + WARN_ON(!port->count); 1626 1620 1627 1621 dc->open_ttys--; 1628 - port->tty_open_count--; 1622 + port->count--; 1623 + tty_port_tty_set(port, NULL); 1629 1624 1630 - if (port->tty_open_count == 0) { 1631 - DBG1("close: %d", port->token_dl); 1625 + if (port->count == 0) { 1626 + DBG1("close: %d", nport->token_dl); 1632 1627 spin_lock_irqsave(&dc->spin_mutex, flags); 1633 - dc->last_ier &= ~(port->token_dl); 1628 + dc->last_ier &= ~(nport->token_dl); 1634 1629 writew(dc->last_ier, dc->reg_ier); 1635 1630 spin_unlock_irqrestore(&dc->spin_mutex, flags); 1636 1631 } 1637 - 1638 - exit: 1639 - mutex_unlock(&port->tty_sem); 1632 + mutex_unlock(&nport->tty_sem); 1640 1633 } 1641 1634 1642 1635 /* ··· 1665 1660 return -EAGAIN; 1666 1661 } 1667 1662 1668 - if (unlikely(!port->tty_open_count)) { 1663 + if (unlikely(!port->port.count)) { 1669 1664 DBG1(" "); 1670 1665 goto exit; 1671 1666 } ··· 1715 1710 if (!mutex_trylock(&port->tty_sem)) 1716 1711 return 0; 1717 1712 1718 - if (!port->tty_open_count) 1713 + if (!port->port.count) 1719 1714 goto exit; 1720 1715 1721 1716 room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); ··· 1871 1866 goto exit_in_buffer; 1872 1867 } 1873 1868 1874 - if (unlikely(!port->tty_open_count)) { 1869 + if (unlikely(!port->port.count)) { 1875 1870 dev_err(&dc->pdev->dev, "No tty open?\n"); 1876 1871 rval = -ENODEV; 1877 1872 goto exit_in_buffer;