diff options
author | Jiri Slaby <jslaby@suse.cz> | 2012-03-05 17:52:55 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-09 00:51:13 +0400 |
commit | 48a7466f4dd0104d87a6d8dd0f25027be89c8453 (patch) | |
tree | aef96c8570d2dce03f120205103073d4282f1a5b /drivers/isdn/gigaset | |
parent | fc258f89405f63b379324d1f8388ae4810297997 (diff) | |
download | linux-48a7466f4dd0104d87a6d8dd0f25027be89c8453.tar.xz |
TTY: isdn/gigaset, use tty_port
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>
Diffstat (limited to 'drivers/isdn/gigaset')
-rw-r--r-- | drivers/isdn/gigaset/common.c | 3 | ||||
-rw-r--r-- | drivers/isdn/gigaset/gigaset.h | 3 | ||||
-rw-r--r-- | drivers/isdn/gigaset/interface.c | 46 |
3 files changed, 21 insertions, 31 deletions
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index ac0186e54bf4..880f6ef0e18d 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -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; diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 212efaf9a4e4..f877726d664b 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -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; diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 8ff50b056285..8f8814afce86 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -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); |