aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:46:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:40 -0500
commita6614999e800cf3a134ce93ea46ef837e3c0e76e (patch)
tree56b0a29ed004a284561a4c3ff3ee52075acabb65 /drivers/char
parent7834909f1eb96ba7c49ca2b9e3a69b500a2cff76 (diff)
tty: Introduce some close helpers for ports
Again this is a lot of common code we can unify Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/isicom.c66
-rw-r--r--drivers/char/istallion.c78
-rw-r--r--drivers/char/mxser.c56
-rw-r--r--drivers/char/riscom8.c49
-rw-r--r--drivers/char/stallion.c39
-rw-r--r--drivers/char/synclink.c58
-rw-r--r--drivers/char/synclink_gt.c51
-rw-r--r--drivers/char/synclinkmp.c58
-rw-r--r--drivers/char/tty_port.c58
9 files changed, 123 insertions, 390 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index bac55cf4424..24aa6e88e22 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -945,76 +945,30 @@ static void isicom_flush_buffer(struct tty_struct *tty)
945 945
946static void isicom_close(struct tty_struct *tty, struct file *filp) 946static void isicom_close(struct tty_struct *tty, struct file *filp)
947{ 947{
948 struct isi_port *port = tty->driver_data; 948 struct isi_port *ip = tty->driver_data;
949 struct tty_port *port = &ip->port;
949 struct isi_board *card; 950 struct isi_board *card;
950 unsigned long flags; 951 unsigned long flags;
951 952
952 if (!port) 953 BUG_ON(!ip);
953 return;
954 card = port->card;
955 if (isicom_paranoia_check(port, tty->name, "isicom_close"))
956 return;
957
958 pr_dbg("Close start!!!.\n");
959
960 spin_lock_irqsave(&port->port.lock, flags);
961 if (tty_hung_up_p(filp)) {
962 spin_unlock_irqrestore(&port->port.lock, flags);
963 return;
964 }
965
966 if (tty->count == 1 && port->port.count != 1) {
967 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
968 "count tty->count = 1 port count = %d.\n",
969 card->base, port->port.count);
970 port->port.count = 1;
971 }
972 if (--port->port.count < 0) {
973 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
974 "count for channel%d = %d", card->base, port->channel,
975 port->port.count);
976 port->port.count = 0;
977 }
978 954
979 if (port->port.count) { 955 card = ip->card;
980 spin_unlock_irqrestore(&port->port.lock, flags); 956 if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
981 return; 957 return;
982 }
983 port->port.flags |= ASYNC_CLOSING;
984 tty->closing = 1;
985 spin_unlock_irqrestore(&port->port.lock, flags);
986 958
987 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
988 tty_wait_until_sent(tty, port->port.closing_wait);
989 /* indicate to the card that no more data can be received 959 /* indicate to the card that no more data can be received
990 on this port */ 960 on this port */
991 spin_lock_irqsave(&card->card_lock, flags); 961 spin_lock_irqsave(&card->card_lock, flags);
992 if (port->port.flags & ASYNC_INITIALIZED) { 962 if (port->flags & ASYNC_INITIALIZED) {
993 card->port_status &= ~(1 << port->channel); 963 card->port_status &= ~(1 << ip->channel);
994 outw(card->port_status, card->base + 0x02); 964 outw(card->port_status, card->base + 0x02);
995 } 965 }
996 isicom_shutdown_port(port); 966 isicom_shutdown_port(ip);
997 spin_unlock_irqrestore(&card->card_lock, flags); 967 spin_unlock_irqrestore(&card->card_lock, flags);
998 968
999 isicom_flush_buffer(tty); 969 isicom_flush_buffer(tty);
1000 tty_ldisc_flush(tty); 970
1001 971 tty_port_close_end(port, tty);
1002 spin_lock_irqsave(&port->port.lock, flags);
1003 tty->closing = 0;
1004
1005 if (port->port.blocked_open) {
1006 spin_unlock_irqrestore(&port->port.lock, flags);
1007 if (port->port.close_delay) {
1008 pr_dbg("scheduling until time out.\n");
1009 msleep_interruptible(
1010 jiffies_to_msecs(port->port.close_delay));
1011 }
1012 spin_lock_irqsave(&port->port.lock, flags);
1013 wake_up_interruptible(&port->port.open_wait);
1014 }
1015 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1016 wake_up_interruptible(&port->port.close_wait);
1017 spin_unlock_irqrestore(&port->port.lock, flags);
1018} 972}
1019 973
1020/* write et all */ 974/* write et all */
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 4c69ab97339..5c3dc6b8411 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -767,7 +767,7 @@ static int stli_parsebrd(struct stlconf *confp, char **argp)
767 break; 767 break;
768 } 768 }
769 if (i == ARRAY_SIZE(stli_brdstr)) { 769 if (i == ARRAY_SIZE(stli_brdstr)) {
770 printk("STALLION: unknown board name, %s?\n", argp[0]); 770 printk(KERN_WARNING "istallion: unknown board name, %s?\n", argp[0]);
771 return 0; 771 return 0;
772 } 772 }
773 773
@@ -855,21 +855,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
855 return; 855 return;
856 port = &portp->port; 856 port = &portp->port;
857 857
858 spin_lock_irqsave(&port->lock, flags); 858 if (tty_port_close_start(port, tty, filp) == 0)
859 if (tty_hung_up_p(filp)) {
860 spin_unlock_irqrestore(&port->lock, flags);
861 return;
862 }
863 if (tty->count == 1 && port->count != 1)
864 port->count = 1;
865 if (port->count-- > 1) {
866 spin_unlock_irqrestore(&port->lock, flags);
867 return; 859 return;
868 }
869
870 port->flags |= ASYNC_CLOSING;
871 tty->closing = 1;
872 spin_unlock_irqrestore(&port->lock, flags);
873 860
874/* 861/*
875 * May want to wait for data to drain before closing. The BUSY flag 862 * May want to wait for data to drain before closing. The BUSY flag
@@ -882,6 +869,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
882 stli_flushchars(tty); 869 stli_flushchars(tty);
883 spin_unlock_irqrestore(&stli_lock, flags); 870 spin_unlock_irqrestore(&stli_lock, flags);
884 871
872 /* We end up doing this twice for the moment. This needs looking at
873 eventually. Note we still use portp->closing_wait as a result */
885 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) 874 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
886 tty_wait_until_sent(tty, portp->closing_wait); 875 tty_wait_until_sent(tty, portp->closing_wait);
887 876
@@ -905,17 +894,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
905 set_bit(ST_DOFLUSHRX, &portp->state); 894 set_bit(ST_DOFLUSHRX, &portp->state);
906 stli_flushbuffer(tty); 895 stli_flushbuffer(tty);
907 896
908 tty->closing = 0; 897 tty_port_close_end(port, tty);
909 tty_port_tty_set(&portp->port, NULL); 898 tty_port_tty_set(port, NULL);
910
911 if (port->blocked_open) {
912 if (portp->close_delay)
913 msleep_interruptible(jiffies_to_msecs(portp->close_delay));
914 wake_up_interruptible(&port->open_wait);
915 }
916
917 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
918 wake_up_interruptible(&port->close_wait);
919} 899}
920 900
921/*****************************************************************************/ 901/*****************************************************************************/
@@ -1482,7 +1462,7 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s
1482 sio.irq = 0; 1462 sio.irq = 0;
1483 sio.flags = portp->port.flags; 1463 sio.flags = portp->port.flags;
1484 sio.baud_base = portp->baud_base; 1464 sio.baud_base = portp->baud_base;
1485 sio.close_delay = portp->close_delay; 1465 sio.close_delay = portp->port.close_delay;
1486 sio.closing_wait = portp->closing_wait; 1466 sio.closing_wait = portp->closing_wait;
1487 sio.custom_divisor = portp->custom_divisor; 1467 sio.custom_divisor = portp->custom_divisor;
1488 sio.xmit_fifo_size = 0; 1468 sio.xmit_fifo_size = 0;
@@ -1514,7 +1494,7 @@ static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *s
1514 return -EFAULT; 1494 return -EFAULT;
1515 if (!capable(CAP_SYS_ADMIN)) { 1495 if (!capable(CAP_SYS_ADMIN)) {
1516 if ((sio.baud_base != portp->baud_base) || 1496 if ((sio.baud_base != portp->baud_base) ||
1517 (sio.close_delay != portp->close_delay) || 1497 (sio.close_delay != portp->port.close_delay) ||
1518 ((sio.flags & ~ASYNC_USR_MASK) != 1498 ((sio.flags & ~ASYNC_USR_MASK) !=
1519 (portp->port.flags & ~ASYNC_USR_MASK))) 1499 (portp->port.flags & ~ASYNC_USR_MASK)))
1520 return -EPERM; 1500 return -EPERM;
@@ -1523,7 +1503,7 @@ static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *s
1523 portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | 1503 portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
1524 (sio.flags & ASYNC_USR_MASK); 1504 (sio.flags & ASYNC_USR_MASK);
1525 portp->baud_base = sio.baud_base; 1505 portp->baud_base = sio.baud_base;
1526 portp->close_delay = sio.close_delay; 1506 portp->port.close_delay = sio.close_delay;
1527 portp->closing_wait = sio.closing_wait; 1507 portp->closing_wait = sio.closing_wait;
1528 portp->custom_divisor = sio.custom_divisor; 1508 portp->custom_divisor = sio.custom_divisor;
1529 1509
@@ -2065,7 +2045,7 @@ static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigne
2065 unsigned char __iomem *bits; 2045 unsigned char __iomem *bits;
2066 2046
2067 if (test_bit(ST_CMDING, &portp->state)) { 2047 if (test_bit(ST_CMDING, &portp->state)) {
2068 printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n", 2048 printk(KERN_ERR "istallion: command already busy, cmd=%x!\n",
2069 (int) cmd); 2049 (int) cmd);
2070 return; 2050 return;
2071 } 2051 }
@@ -2625,7 +2605,7 @@ static int stli_initports(struct stlibrd *brdp)
2625 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { 2605 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
2626 portp = kzalloc(sizeof(struct stliport), GFP_KERNEL); 2606 portp = kzalloc(sizeof(struct stliport), GFP_KERNEL);
2627 if (!portp) { 2607 if (!portp) {
2628 printk("STALLION: failed to allocate port structure\n"); 2608 printk(KERN_WARNING "istallion: failed to allocate port structure\n");
2629 continue; 2609 continue;
2630 } 2610 }
2631 tty_port_init(&portp->port); 2611 tty_port_init(&portp->port);
@@ -2635,7 +2615,7 @@ static int stli_initports(struct stlibrd *brdp)
2635 portp->brdnr = brdp->brdnr; 2615 portp->brdnr = brdp->brdnr;
2636 portp->panelnr = panelnr; 2616 portp->panelnr = panelnr;
2637 portp->baud_base = STL_BAUDBASE; 2617 portp->baud_base = STL_BAUDBASE;
2638 portp->close_delay = STL_CLOSEDELAY; 2618 portp->port.close_delay = STL_CLOSEDELAY;
2639 portp->closing_wait = 30 * HZ; 2619 portp->closing_wait = 30 * HZ;
2640 init_waitqueue_head(&portp->port.open_wait); 2620 init_waitqueue_head(&portp->port.open_wait);
2641 init_waitqueue_head(&portp->port.close_wait); 2621 init_waitqueue_head(&portp->port.close_wait);
@@ -2692,7 +2672,7 @@ static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offse
2692 unsigned char val; 2672 unsigned char val;
2693 2673
2694 if (offset > brdp->memsize) { 2674 if (offset > brdp->memsize) {
2695 printk(KERN_ERR "STALLION: shared memory pointer=%x out of " 2675 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2696 "range at line=%d(%d), brd=%d\n", 2676 "range at line=%d(%d), brd=%d\n",
2697 (int) offset, line, __LINE__, brdp->brdnr); 2677 (int) offset, line, __LINE__, brdp->brdnr);
2698 ptr = NULL; 2678 ptr = NULL;
@@ -2766,7 +2746,7 @@ static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long off
2766 unsigned char val; 2746 unsigned char val;
2767 2747
2768 if (offset > brdp->memsize) { 2748 if (offset > brdp->memsize) {
2769 printk(KERN_ERR "STALLION: shared memory pointer=%x out of " 2749 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2770 "range at line=%d(%d), brd=%d\n", 2750 "range at line=%d(%d), brd=%d\n",
2771 (int) offset, line, __LINE__, brdp->brdnr); 2751 (int) offset, line, __LINE__, brdp->brdnr);
2772 ptr = NULL; 2752 ptr = NULL;
@@ -2818,7 +2798,7 @@ static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long off
2818 unsigned char val; 2798 unsigned char val;
2819 2799
2820 if (offset > brdp->memsize) { 2800 if (offset > brdp->memsize) {
2821 printk(KERN_ERR "STALLION: shared memory pointer=%x out of " 2801 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2822 "range at line=%d(%d), brd=%d\n", 2802 "range at line=%d(%d), brd=%d\n",
2823 (int) offset, line, __LINE__, brdp->brdnr); 2803 (int) offset, line, __LINE__, brdp->brdnr);
2824 ptr = NULL; 2804 ptr = NULL;
@@ -2863,7 +2843,7 @@ static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long of
2863 unsigned char val; 2843 unsigned char val;
2864 2844
2865 if (offset > brdp->memsize) { 2845 if (offset > brdp->memsize) {
2866 printk(KERN_ERR "STALLION: shared memory pointer=%x out of " 2846 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2867 "range at line=%d(%d), board=%d\n", 2847 "range at line=%d(%d), board=%d\n",
2868 (int) offset, line, __LINE__, brdp->brdnr); 2848 (int) offset, line, __LINE__, brdp->brdnr);
2869 ptr = NULL; 2849 ptr = NULL;
@@ -2928,7 +2908,7 @@ static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offse
2928 void __iomem *ptr; 2908 void __iomem *ptr;
2929 2909
2930 if (offset > brdp->memsize) { 2910 if (offset > brdp->memsize) {
2931 printk(KERN_ERR "STALLION: shared memory pointer=%x out of " 2911 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2932 "range at line=%d(%d), brd=%d\n", 2912 "range at line=%d(%d), brd=%d\n",
2933 (int) offset, line, __LINE__, brdp->brdnr); 2913 (int) offset, line, __LINE__, brdp->brdnr);
2934 ptr = NULL; 2914 ptr = NULL;
@@ -2994,7 +2974,7 @@ static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offs
2994 unsigned char val; 2974 unsigned char val;
2995 2975
2996 if (offset > brdp->memsize) { 2976 if (offset > brdp->memsize) {
2997 printk(KERN_ERR "STALLION: shared memory pointer=%x out of " 2977 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2998 "range at line=%d(%d), brd=%d\n", 2978 "range at line=%d(%d), brd=%d\n",
2999 (int) offset, line, __LINE__, brdp->brdnr); 2979 (int) offset, line, __LINE__, brdp->brdnr);
3000 ptr = NULL; 2980 ptr = NULL;
@@ -3433,7 +3413,7 @@ static int stli_startbrd(struct stlibrd *brdp)
3433#endif 3413#endif
3434 3414
3435 if (nrdevs < (brdp->nrports + 1)) { 3415 if (nrdevs < (brdp->nrports + 1)) {
3436 printk(KERN_ERR "STALLION: slave failed to allocate memory for " 3416 printk(KERN_ERR "istallion: slave failed to allocate memory for "
3437 "all devices, devices=%d\n", nrdevs); 3417 "all devices, devices=%d\n", nrdevs);
3438 brdp->nrports = nrdevs - 1; 3418 brdp->nrports = nrdevs - 1;
3439 } 3419 }
@@ -3443,13 +3423,13 @@ static int stli_startbrd(struct stlibrd *brdp)
3443 brdp->bitsize = (nrdevs + 7) / 8; 3423 brdp->bitsize = (nrdevs + 7) / 8;
3444 memoff = readl(&hdrp->memp); 3424 memoff = readl(&hdrp->memp);
3445 if (memoff > brdp->memsize) { 3425 if (memoff > brdp->memsize) {
3446 printk(KERN_ERR "STALLION: corrupted shared memory region?\n"); 3426 printk(KERN_ERR "istallion: corrupted shared memory region?\n");
3447 rc = -EIO; 3427 rc = -EIO;
3448 goto stli_donestartup; 3428 goto stli_donestartup;
3449 } 3429 }
3450 memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff); 3430 memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff);
3451 if (readw(&memp->dtype) != TYP_ASYNCTRL) { 3431 if (readw(&memp->dtype) != TYP_ASYNCTRL) {
3452 printk(KERN_ERR "STALLION: no slave control device found\n"); 3432 printk(KERN_ERR "istallion: no slave control device found\n");
3453 goto stli_donestartup; 3433 goto stli_donestartup;
3454 } 3434 }
3455 memp++; 3435 memp++;
@@ -3534,7 +3514,7 @@ static int __devinit stli_brdinit(struct stlibrd *brdp)
3534 retval = stli_initonb(brdp); 3514 retval = stli_initonb(brdp);
3535 break; 3515 break;
3536 default: 3516 default:
3537 printk(KERN_ERR "STALLION: board=%d is unknown board " 3517 printk(KERN_ERR "istallion: board=%d is unknown board "
3538 "type=%d\n", brdp->brdnr, brdp->brdtype); 3518 "type=%d\n", brdp->brdnr, brdp->brdtype);
3539 retval = -ENODEV; 3519 retval = -ENODEV;
3540 } 3520 }
@@ -3543,7 +3523,7 @@ static int __devinit stli_brdinit(struct stlibrd *brdp)
3543 return retval; 3523 return retval;
3544 3524
3545 stli_initports(brdp); 3525 stli_initports(brdp);
3546 printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x " 3526 printk(KERN_INFO "istallion: %s found, board=%d io=%x mem=%x "
3547 "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], 3527 "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
3548 brdp->brdnr, brdp->iobase, (int) brdp->memaddr, 3528 brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
3549 brdp->nrpanels, brdp->nrports); 3529 brdp->nrpanels, brdp->nrports);
@@ -3637,7 +3617,7 @@ static int stli_eisamemprobe(struct stlibrd *brdp)
3637 if (! foundit) { 3617 if (! foundit) {
3638 brdp->memaddr = 0; 3618 brdp->memaddr = 0;
3639 brdp->membase = NULL; 3619 brdp->membase = NULL;
3640 printk(KERN_ERR "STALLION: failed to probe shared memory " 3620 printk(KERN_ERR "istallion: failed to probe shared memory "
3641 "region for %s in EISA slot=%d\n", 3621 "region for %s in EISA slot=%d\n",
3642 stli_brdnames[brdp->brdtype], (brdp->iobase >> 12)); 3622 stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
3643 return -ENODEV; 3623 return -ENODEV;
@@ -3782,7 +3762,7 @@ static int __devinit stli_pciprobe(struct pci_dev *pdev,
3782 mutex_lock(&stli_brdslock); 3762 mutex_lock(&stli_brdslock);
3783 brdnr = stli_getbrdnr(); 3763 brdnr = stli_getbrdnr();
3784 if (brdnr < 0) { 3764 if (brdnr < 0) {
3785 printk(KERN_INFO "STALLION: too many boards found, " 3765 printk(KERN_INFO "istallion: too many boards found, "
3786 "maximum supported %d\n", STL_MAXBRDS); 3766 "maximum supported %d\n", STL_MAXBRDS);
3787 mutex_unlock(&stli_brdslock); 3767 mutex_unlock(&stli_brdslock);
3788 retval = -EIO; 3768 retval = -EIO;
@@ -3854,7 +3834,7 @@ static struct stlibrd *stli_allocbrd(void)
3854 3834
3855 brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL); 3835 brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL);
3856 if (!brdp) { 3836 if (!brdp) {
3857 printk(KERN_ERR "STALLION: failed to allocate memory " 3837 printk(KERN_ERR "istallion: failed to allocate memory "
3858 "(size=%Zd)\n", sizeof(struct stlibrd)); 3838 "(size=%Zd)\n", sizeof(struct stlibrd));
3859 return NULL; 3839 return NULL;
3860 } 3840 }
@@ -4493,7 +4473,7 @@ static int __init istallion_module_init(void)
4493 4473
4494 stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); 4474 stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
4495 if (!stli_txcookbuf) { 4475 if (!stli_txcookbuf) {
4496 printk(KERN_ERR "STALLION: failed to allocate memory " 4476 printk(KERN_ERR "istallion: failed to allocate memory "
4497 "(size=%d)\n", STLI_TXBUFSIZE); 4477 "(size=%d)\n", STLI_TXBUFSIZE);
4498 retval = -ENOMEM; 4478 retval = -ENOMEM;
4499 goto err; 4479 goto err;
@@ -4518,7 +4498,7 @@ static int __init istallion_module_init(void)
4518 4498
4519 retval = tty_register_driver(stli_serial); 4499 retval = tty_register_driver(stli_serial);
4520 if (retval) { 4500 if (retval) {
4521 printk(KERN_ERR "STALLION: failed to register serial driver\n"); 4501 printk(KERN_ERR "istallion: failed to register serial driver\n");
4522 goto err_ttyput; 4502 goto err_ttyput;
4523 } 4503 }
4524 4504
@@ -4532,7 +4512,7 @@ static int __init istallion_module_init(void)
4532 */ 4512 */
4533 retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem); 4513 retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem);
4534 if (retval) { 4514 if (retval) {
4535 printk(KERN_ERR "STALLION: failed to register serial memory " 4515 printk(KERN_ERR "istallion: failed to register serial memory "
4536 "device\n"); 4516 "device\n");
4537 goto err_deinit; 4517 goto err_deinit;
4538 } 4518 }
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 08ba6eb1a38..402c9f217f8 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1080,58 +1080,27 @@ static void mxser_flush_buffer(struct tty_struct *tty)
1080static void mxser_close(struct tty_struct *tty, struct file *filp) 1080static void mxser_close(struct tty_struct *tty, struct file *filp)
1081{ 1081{
1082 struct mxser_port *info = tty->driver_data; 1082 struct mxser_port *info = tty->driver_data;
1083 struct tty_port *port = &info->port;
1083 1084
1084 unsigned long timeout; 1085 unsigned long timeout;
1085 unsigned long flags;
1086 1086
1087 if (tty->index == MXSER_PORTS) 1087 if (tty->index == MXSER_PORTS)
1088 return; 1088 return;
1089 if (!info) 1089 if (!info)
1090 return; 1090 return;
1091 1091
1092 spin_lock_irqsave(&info->port.lock, flags); 1092 if (tty_port_close_start(port, tty, filp) == 0)
1093
1094 if (tty_hung_up_p(filp)) {
1095 spin_unlock_irqrestore(&info->port.lock, flags);
1096 return;
1097 }
1098 if ((tty->count == 1) && (info->port.count != 1)) {
1099 /*
1100 * Uh, oh. tty->count is 1, which means that the tty
1101 * structure will be freed. Info->port.count should always
1102 * be one in these conditions. If it's greater than
1103 * one, we've got real problems, since it means the
1104 * serial port won't be shutdown.
1105 */
1106 printk(KERN_ERR "mxser_close: bad serial port count; "
1107 "tty->count is 1, info->port.count is %d\n", info->port.count);
1108 info->port.count = 1;
1109 }
1110 if (--info->port.count < 0) {
1111 printk(KERN_ERR "mxser_close: bad serial port count for "
1112 "ttys%d: %d\n", tty->index, info->port.count);
1113 info->port.count = 0;
1114 }
1115 if (info->port.count) {
1116 spin_unlock_irqrestore(&info->port.lock, flags);
1117 return; 1093 return;
1118 } 1094
1119 info->port.flags |= ASYNC_CLOSING;
1120 spin_unlock_irqrestore(&info->port.lock, flags);
1121 /* 1095 /*
1122 * Save the termios structure, since this port may have 1096 * Save the termios structure, since this port may have
1123 * separate termios for callout and dialin. 1097 * separate termios for callout and dialin.
1098 *
1099 * FIXME: Can this go ?
1124 */ 1100 */
1125 if (info->port.flags & ASYNC_NORMAL_ACTIVE) 1101 if (info->port.flags & ASYNC_NORMAL_ACTIVE)
1126 info->normal_termios = *tty->termios; 1102 info->normal_termios = *tty->termios;
1127 /* 1103 /*
1128 * Now we wait for the transmit buffer to clear; and we notify
1129 * the line discipline to only process XON/XOFF characters.
1130 */
1131 tty->closing = 1;
1132 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1133 tty_wait_until_sent(tty, info->port.closing_wait);
1134 /*
1135 * At this point we stop accepting input. To do this, we 1104 * At this point we stop accepting input. To do this, we
1136 * disable the receive line status interrupts, and tell the 1105 * disable the receive line status interrupts, and tell the
1137 * interrupt driver to stop checking the data ready bit in the 1106 * interrupt driver to stop checking the data ready bit in the
@@ -1156,19 +1125,12 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1156 } 1125 }
1157 } 1126 }
1158 mxser_shutdown(tty); 1127 mxser_shutdown(tty);
1159
1160 mxser_flush_buffer(tty); 1128 mxser_flush_buffer(tty);
1161 tty_ldisc_flush(tty);
1162
1163 tty->closing = 0;
1164 tty_port_tty_set(&info->port, NULL);
1165 if (info->port.blocked_open) {
1166 if (info->port.close_delay)
1167 schedule_timeout_interruptible(info->port.close_delay);
1168 wake_up_interruptible(&info->port.open_wait);
1169 }
1170 1129
1171 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 1130 /* Right now the tty_port set is done outside of the close_end helper
1131 as we don't yet have everyone using refcounts */
1132 tty_port_close_end(port, tty);
1133 tty_port_tty_set(port, NULL);
1172} 1134}
1173 1135
1174static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) 1136static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index af34c2054a0..9ac5febd8ab 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -929,35 +929,11 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
929 if (!port || rc_paranoia_check(port, tty->name, "close")) 929 if (!port || rc_paranoia_check(port, tty->name, "close"))
930 return; 930 return;
931 931
932 spin_lock_irqsave(&port->port.lock, flags);
933
934 if (tty_hung_up_p(filp))
935 goto out;
936
937 bp = port_Board(port); 932 bp = port_Board(port);
938 if ((tty->count == 1) && (port->port.count != 1)) { 933
939 printk(KERN_INFO "rc%d: rc_close: bad port count;" 934 if (tty_port_close_start(&port->port, tty, filp) == 0)
940 " tty->count is 1, port count is %d\n", 935 return;
941 board_No(bp), port->port.count); 936
942 port->port.count = 1;
943 }
944 if (--port->port.count < 0) {
945 printk(KERN_INFO "rc%d: rc_close: bad port count "
946 "for tty%d: %d\n",
947 board_No(bp), port_No(port), port->port.count);
948 port->port.count = 0;
949 }
950 if (port->port.count)
951 goto out;
952 port->port.flags |= ASYNC_CLOSING;
953 /*
954 * Now we wait for the transmit buffer to clear; and we notify
955 * the line discipline to only process XON/XOFF characters.
956 */
957 tty->closing = 1;
958 spin_unlock_irqrestore(&port->port.lock, flags);
959 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
960 tty_wait_until_sent(tty, port->port.closing_wait);
961 /* 937 /*
962 * At this point we stop accepting input. To do this, we 938 * At this point we stop accepting input. To do this, we
963 * disable the receive line status interrupts, and tell the 939 * disable the receive line status interrupts, and tell the
@@ -989,23 +965,8 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
989 rc_shutdown_port(tty, bp, port); 965 rc_shutdown_port(tty, bp, port);
990 rc_flush_buffer(tty); 966 rc_flush_buffer(tty);
991 spin_unlock_irqrestore(&riscom_lock, flags); 967 spin_unlock_irqrestore(&riscom_lock, flags);
992 tty_ldisc_flush(tty);
993 968
994 spin_lock_irqsave(&port->port.lock, flags); 969 tty_port_close_end(&port->port, tty);
995 tty->closing = 0;
996 port->port.tty = NULL;
997 if (port->port.blocked_open) {
998 spin_unlock_irqrestore(&port->port.lock, flags);
999 if (port->port.close_delay)
1000 msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
1001 wake_up_interruptible(&port->port.open_wait);
1002 spin_lock_irqsave(&port->port.lock, flags);
1003 }
1004 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1005 wake_up_interruptible(&port->port.close_wait);
1006
1007out:
1008 spin_unlock_irqrestore(&riscom_lock, flags);
1009} 970}
1010 971
1011static int rc_write(struct tty_struct *tty, 972static int rc_write(struct tty_struct *tty,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 77eef61c46f..e1e0dd89ac9 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -833,40 +833,20 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
833 pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); 833 pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
834 834
835 portp = tty->driver_data; 835 portp = tty->driver_data;
836 if (portp == NULL) 836 BUG_ON(portp == NULL);
837 return; 837
838 port = &portp->port; 838 port = &portp->port;
839 839
840 spin_lock_irqsave(&port->lock, flags); 840 if (tty_port_close_start(port, tty, filp) == 0)
841 if (tty_hung_up_p(filp)) {
842 spin_unlock_irqrestore(&port->lock, flags);
843 return; 841 return;
844 }
845 if (tty->count == 1 && port->count != 1)
846 port->count = 1;
847 if (port->count-- > 1) {
848 spin_unlock_irqrestore(&port->lock, flags);
849 return;
850 }
851
852 port->count = 0;
853 port->flags |= ASYNC_CLOSING;
854
855/* 842/*
856 * May want to wait for any data to drain before closing. The BUSY 843 * May want to wait for any data to drain before closing. The BUSY
857 * flag keeps track of whether we are still sending or not - it is 844 * flag keeps track of whether we are still sending or not - it is
858 * very accurate for the cd1400, not quite so for the sc26198. 845 * very accurate for the cd1400, not quite so for the sc26198.
859 * (The sc26198 has no "end-of-data" interrupt only empty FIFO) 846 * (The sc26198 has no "end-of-data" interrupt only empty FIFO)
860 */ 847 */
861 tty->closing = 1;
862
863 spin_unlock_irqrestore(&port->lock, flags);
864
865 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
866 tty_wait_until_sent(tty, portp->closing_wait);
867 stl_waituntilsent(tty, (HZ / 2)); 848 stl_waituntilsent(tty, (HZ / 2));
868 849
869
870 spin_lock_irqsave(&port->lock, flags); 850 spin_lock_irqsave(&port->lock, flags);
871 portp->port.flags &= ~ASYNC_INITIALIZED; 851 portp->port.flags &= ~ASYNC_INITIALIZED;
872 spin_unlock_irqrestore(&port->lock, flags); 852 spin_unlock_irqrestore(&port->lock, flags);
@@ -883,20 +863,9 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
883 portp->tx.head = NULL; 863 portp->tx.head = NULL;
884 portp->tx.tail = NULL; 864 portp->tx.tail = NULL;
885 } 865 }
886 set_bit(TTY_IO_ERROR, &tty->flags);
887 tty_ldisc_flush(tty);
888 866
889 tty->closing = 0; 867 tty_port_close_end(port, tty);
890 tty_port_tty_set(port, NULL); 868 tty_port_tty_set(port, NULL);
891
892 if (port->blocked_open) {
893 if (portp->close_delay)
894 msleep_interruptible(jiffies_to_msecs(portp->close_delay));
895 wake_up_interruptible(&portp->port.open_wait);
896 }
897
898 portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
899 wake_up_interruptible(&port->close_wait);
900} 869}
901 870
902/*****************************************************************************/ 871/*****************************************************************************/
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 0ded4ed3da3..fbd5a5ce2e1 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -3104,70 +3104,18 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
3104 if (debug_level >= DEBUG_LEVEL_INFO) 3104 if (debug_level >= DEBUG_LEVEL_INFO)
3105 printk("%s(%d):mgsl_close(%s) entry, count=%d\n", 3105 printk("%s(%d):mgsl_close(%s) entry, count=%d\n",
3106 __FILE__,__LINE__, info->device_name, info->port.count); 3106 __FILE__,__LINE__, info->device_name, info->port.count);
3107
3108 if (!info->port.count)
3109 return;
3110 3107
3111 if (tty_hung_up_p(filp)) 3108 if (tty_port_close_start(&info->port, tty, filp) == 0)
3112 goto cleanup; 3109 goto cleanup;
3113 3110
3114 if ((tty->count == 1) && (info->port.count != 1)) {
3115 /*
3116 * tty->count is 1 and the tty structure will be freed.
3117 * info->port.count should be one in this case.
3118 * if it's not, correct it so that the port is shutdown.
3119 */
3120 printk("mgsl_close: bad refcount; tty->count is 1, "
3121 "info->port.count is %d\n", info->port.count);
3122 info->port.count = 1;
3123 }
3124
3125 info->port.count--;
3126
3127 /* if at least one open remaining, leave hardware active */
3128 if (info->port.count)
3129 goto cleanup;
3130
3131 info->port.flags |= ASYNC_CLOSING;
3132
3133 /* set tty->closing to notify line discipline to
3134 * only process XON/XOFF characters. Only the N_TTY
3135 * discipline appears to use this (ppp does not).
3136 */
3137 tty->closing = 1;
3138
3139 /* wait for transmit data to clear all layers */
3140
3141 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
3142 if (debug_level >= DEBUG_LEVEL_INFO)
3143 printk("%s(%d):mgsl_close(%s) calling tty_wait_until_sent\n",
3144 __FILE__,__LINE__, info->device_name );
3145 tty_wait_until_sent(tty, info->port.closing_wait);
3146 }
3147
3148 if (info->port.flags & ASYNC_INITIALIZED) 3111 if (info->port.flags & ASYNC_INITIALIZED)
3149 mgsl_wait_until_sent(tty, info->timeout); 3112 mgsl_wait_until_sent(tty, info->timeout);
3150
3151 mgsl_flush_buffer(tty); 3113 mgsl_flush_buffer(tty);
3152
3153 tty_ldisc_flush(tty); 3114 tty_ldisc_flush(tty);
3154
3155 shutdown(info); 3115 shutdown(info);
3156 3116
3157 tty->closing = 0; 3117 tty_port_close_end(&info->port, tty);
3158 info->port.tty = NULL; 3118 info->port.tty = NULL;
3159
3160 if (info->port.blocked_open) {
3161 if (info->port.close_delay) {
3162 msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
3163 }
3164 wake_up_interruptible(&info->port.open_wait);
3165 }
3166
3167 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
3168
3169 wake_up_interruptible(&info->port.close_wait);
3170
3171cleanup: 3119cleanup:
3172 if (debug_level >= DEBUG_LEVEL_INFO) 3120 if (debug_level >= DEBUG_LEVEL_INFO)
3173 printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__, 3121 printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__,
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 625c9bde3be..53544e21f19 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -720,44 +720,9 @@ static void close(struct tty_struct *tty, struct file *filp)
720 return; 720 return;
721 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count)); 721 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count));
722 722
723 if (!info->port.count) 723 if (tty_port_close_start(&info->port, tty, filp) == 0)
724 return;
725
726 if (tty_hung_up_p(filp))
727 goto cleanup; 724 goto cleanup;
728 725
729 if ((tty->count == 1) && (info->port.count != 1)) {
730 /*
731 * tty->count is 1 and the tty structure will be freed.
732 * info->port.count should be one in this case.
733 * if it's not, correct it so that the port is shutdown.
734 */
735 DBGERR(("%s close: bad refcount; tty->count=1, "
736 "info->port.count=%d\n", info->device_name, info->port.count));
737 info->port.count = 1;
738 }
739
740 info->port.count--;
741
742 /* if at least one open remaining, leave hardware active */
743 if (info->port.count)
744 goto cleanup;
745
746 info->port.flags |= ASYNC_CLOSING;
747
748 /* set tty->closing to notify line discipline to
749 * only process XON/XOFF characters. Only the N_TTY
750 * discipline appears to use this (ppp does not).
751 */
752 tty->closing = 1;
753
754 /* wait for transmit data to clear all layers */
755
756 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
757 DBGINFO(("%s call tty_wait_until_sent\n", info->device_name));
758 tty_wait_until_sent(tty, info->port.closing_wait);
759 }
760
761 if (info->port.flags & ASYNC_INITIALIZED) 726 if (info->port.flags & ASYNC_INITIALIZED)
762 wait_until_sent(tty, info->timeout); 727 wait_until_sent(tty, info->timeout);
763 flush_buffer(tty); 728 flush_buffer(tty);
@@ -765,20 +730,8 @@ static void close(struct tty_struct *tty, struct file *filp)
765 730
766 shutdown(info); 731 shutdown(info);
767 732
768 tty->closing = 0; 733 tty_port_close_end(&info->port, tty);
769 info->port.tty = NULL; 734 info->port.tty = NULL;
770
771 if (info->port.blocked_open) {
772 if (info->port.close_delay) {
773 msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
774 }
775 wake_up_interruptible(&info->port.open_wait);
776 }
777
778 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
779
780 wake_up_interruptible(&info->port.close_wait);
781
782cleanup: 735cleanup:
783 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count)); 736 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count));
784} 737}
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 1f5c21ec4b1..2aac55bcf5f 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -810,70 +810,18 @@ static void close(struct tty_struct *tty, struct file *filp)
810 printk("%s(%d):%s close() entry, count=%d\n", 810 printk("%s(%d):%s close() entry, count=%d\n",
811 __FILE__,__LINE__, info->device_name, info->port.count); 811 __FILE__,__LINE__, info->device_name, info->port.count);
812 812
813 if (!info->port.count) 813 if (tty_port_close_start(&info->port, tty, filp) == 0)
814 return;
815
816 if (tty_hung_up_p(filp))
817 goto cleanup;
818
819 if ((tty->count == 1) && (info->port.count != 1)) {
820 /*
821 * tty->count is 1 and the tty structure will be freed.
822 * info->port.count should be one in this case.
823 * if it's not, correct it so that the port is shutdown.
824 */
825 printk("%s(%d):%s close: bad refcount; tty->count is 1, "
826 "info->port.count is %d\n",
827 __FILE__,__LINE__, info->device_name, info->port.count);
828 info->port.count = 1;
829 }
830
831 info->port.count--;
832
833 /* if at least one open remaining, leave hardware active */
834 if (info->port.count)
835 goto cleanup; 814 goto cleanup;
836 815
837 info->port.flags |= ASYNC_CLOSING;
838
839 /* set tty->closing to notify line discipline to
840 * only process XON/XOFF characters. Only the N_TTY
841 * discipline appears to use this (ppp does not).
842 */
843 tty->closing = 1;
844
845 /* wait for transmit data to clear all layers */
846
847 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
848 if (debug_level >= DEBUG_LEVEL_INFO)
849 printk("%s(%d):%s close() calling tty_wait_until_sent\n",
850 __FILE__,__LINE__, info->device_name );
851 tty_wait_until_sent(tty, info->port.closing_wait);
852 }
853
854 if (info->port.flags & ASYNC_INITIALIZED) 816 if (info->port.flags & ASYNC_INITIALIZED)
855 wait_until_sent(tty, info->timeout); 817 wait_until_sent(tty, info->timeout);
856 818
857 flush_buffer(tty); 819 flush_buffer(tty);
858
859 tty_ldisc_flush(tty); 820 tty_ldisc_flush(tty);
860
861 shutdown(info); 821 shutdown(info);
862 822
863 tty->closing = 0; 823 tty_port_close_end(&info->port, tty);
864 info->port.tty = NULL; 824 info->port.tty = NULL;
865
866 if (info->port.blocked_open) {
867 if (info->port.close_delay) {
868 msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
869 }
870 wake_up_interruptible(&info->port.open_wait);
871 }
872
873 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
874
875 wake_up_interruptible(&info->port.close_wait);
876
877cleanup: 825cleanup:
878 if (debug_level >= DEBUG_LEVEL_INFO) 826 if (debug_level >= DEBUG_LEVEL_INFO)
879 printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__, 827 printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__,
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 0723664fe0a..b3175f54fe0 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -257,3 +257,61 @@ int tty_port_block_til_ready(struct tty_port *port,
257} 257}
258EXPORT_SYMBOL(tty_port_block_til_ready); 258EXPORT_SYMBOL(tty_port_block_til_ready);
259 259
260int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
261{
262 unsigned long flags;
263
264 spin_lock_irqsave(&port->lock, flags);
265 if (tty_hung_up_p(filp)) {
266 spin_unlock_irqrestore(&port->lock, flags);
267 return 0;
268 }
269
270 if( tty->count == 1 && port->count != 1) {
271 printk(KERN_WARNING
272 "tty_port_close_start: tty->count = 1 port count = %d.\n",
273 port->count);
274 port->count = 1;
275 }
276 if (--port->count < 0) {
277 printk(KERN_WARNING "tty_port_close_start: count = %d\n",
278 port->count);
279 port->count = 0;
280 }
281
282 if (port->count) {
283 spin_unlock_irqrestore(&port->lock, flags);
284 return 0;
285 }
286 port->flags |= ASYNC_CLOSING;
287 tty->closing = 1;
288 spin_unlock_irqrestore(&port->lock, flags);
289 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
290 tty_wait_until_sent(tty, port->closing_wait);
291 return 1;
292}
293EXPORT_SYMBOL(tty_port_close_start);
294
295void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
296{
297 unsigned long flags;
298
299 tty_ldisc_flush(tty);
300
301 spin_lock_irqsave(&port->lock, flags);
302 tty->closing = 0;
303
304 if (port->blocked_open) {
305 spin_unlock_irqrestore(&port->lock, flags);
306 if (port->close_delay) {
307 msleep_interruptible(
308 jiffies_to_msecs(port->close_delay));
309 }
310 spin_lock_irqsave(&port->lock, flags);
311 wake_up_interruptible(&port->open_wait);
312 }
313 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
314 wake_up_interruptible(&port->close_wait);
315 spin_unlock_irqrestore(&port->lock, flags);
316}
317EXPORT_SYMBOL(tty_port_close_end);