TTY: isdn/gigaset, use tty_port
authorJiri Slaby <jslaby@suse.cz>
Mon, 5 Mar 2012 13:52:55 +0000 (14:52 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Mar 2012 20:51:13 +0000 (12:51 -0800)
Let us port the code to use tty_port. We now use open_count and tty
from there. This allows us also to use tty_port_tty_set with tty
refcounting instead of hand-written locking and logic.

Note that tty and open_count are no longer protected by cs->lock. It is
protected by tty_port->lock. But since all the places where they were
used are now switched to the helpers, we are fine.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Hansjoerg Lipp <hjlipp@web.de>
Acked-by: Tilman Schmidt <tilman@imap.cc>
Cc: <gigaset307x-common@lists.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/gigaset.h
drivers/isdn/gigaset/interface.c

index ac0186e54bf4db8635e278f7b734296cf5cc16b5..880f6ef0e18da416da5f55e54b5f01aa08ebe953 100644 (file)
@@ -720,12 +720,11 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
 
        tasklet_init(&cs->event_tasklet, gigaset_handle_event,
                     (unsigned long) cs);
+       tty_port_init(&cs->port);
        cs->commands_pending = 0;
        cs->cur_at_seq = 0;
        cs->gotfwver = -1;
-       cs->open_count = 0;
        cs->dev = NULL;
-       cs->tty = NULL;
        cs->tty_dev = NULL;
        cs->cidmode = cidmode != 0;
        cs->tabnocid = gigaset_tab_nocid;
index 212efaf9a4e4ed261105bd39132ee885531c4930..f877726d664bdf2587664e3c6d9cfa1c128311fe 100644 (file)
@@ -433,8 +433,7 @@ struct cardstate {
        spinlock_t cmdlock;
        unsigned curlen, cmdbytes;
 
-       unsigned open_count;
-       struct tty_struct *tty;
+       struct tty_port port;
        struct tasklet_struct if_wake_tasklet;
        unsigned control_state;
 
index 8ff50b05628557d95af9511120e84536b11b07d5..8f8814afce867396e74804a299b8ad78840d498d 100644 (file)
@@ -146,7 +146,6 @@ static const struct tty_operations if_ops = {
 static int if_open(struct tty_struct *tty, struct file *filp)
 {
        struct cardstate *cs;
-       unsigned long flags;
 
        gig_dbg(DEBUG_IF, "%d+%d: %s()",
                tty->driver->minor_start, tty->index, __func__);
@@ -161,12 +160,10 @@ static int if_open(struct tty_struct *tty, struct file *filp)
        }
        tty->driver_data = cs;
 
-       ++cs->open_count;
+       ++cs->port.count;
 
-       if (cs->open_count == 1) {
-               spin_lock_irqsave(&cs->lock, flags);
-               cs->tty = tty;
-               spin_unlock_irqrestore(&cs->lock, flags);
+       if (cs->port.count == 1) {
+               tty_port_tty_set(&cs->port, tty);
                tty->low_latency = 1;
        }
 
@@ -177,7 +174,6 @@ static int if_open(struct tty_struct *tty, struct file *filp)
 static void if_close(struct tty_struct *tty, struct file *filp)
 {
        struct cardstate *cs = tty->driver_data;
-       unsigned long flags;
 
        if (!cs) { /* happens if we didn't find cs in open */
                printk(KERN_DEBUG "%s: no cardstate\n", __func__);
@@ -190,15 +186,10 @@ static void if_close(struct tty_struct *tty, struct file *filp)
 
        if (!cs->connected)
                gig_dbg(DEBUG_IF, "not connected");     /* nothing to do */
-       else if (!cs->open_count)
+       else if (!cs->port.count)
                dev_warn(cs->dev, "%s: device not opened\n", __func__);
-       else {
-               if (!--cs->open_count) {
-                       spin_lock_irqsave(&cs->lock, flags);
-                       cs->tty = NULL;
-                       spin_unlock_irqrestore(&cs->lock, flags);
-               }
-       }
+       else if (!--cs->port.count)
+               tty_port_tty_set(&cs->port, NULL);
 
        mutex_unlock(&cs->mutex);
 
@@ -511,10 +502,13 @@ out:
 /* wakeup tasklet for the write operation */
 static void if_wake(unsigned long data)
 {
-       struct cardstate *cs = (struct cardstate *) data;
+       struct cardstate *cs = (struct cardstate *)data;
+       struct tty_struct *tty = tty_port_tty_get(&cs->port);
 
-       if (cs->tty)
-               tty_wakeup(cs->tty);
+       if (tty) {
+               tty_wakeup(tty);
+               tty_kref_put(tty);
+       }
 }
 
 /*** interface to common ***/
@@ -567,18 +561,16 @@ void gigaset_if_free(struct cardstate *cs)
 void gigaset_if_receive(struct cardstate *cs,
                        unsigned char *buffer, size_t len)
 {
-       unsigned long flags;
-       struct tty_struct *tty;
+       struct tty_struct *tty = tty_port_tty_get(&cs->port);
 
-       spin_lock_irqsave(&cs->lock, flags);
-       tty = cs->tty;
-       if (tty == NULL)
+       if (tty == NULL) {
                gig_dbg(DEBUG_IF, "receive on closed device");
-       else {
-               tty_insert_flip_string(tty, buffer, len);
-               tty_flip_buffer_push(tty);
+               return;
        }
-       spin_unlock_irqrestore(&cs->lock, flags);
+
+       tty_insert_flip_string(tty, buffer, len);
+       tty_flip_buffer_push(tty);
+       tty_kref_put(tty);
 }
 EXPORT_SYMBOL_GPL(gigaset_if_receive);