diff options
author | Jiri Slaby <jslaby@suse.cz> | 2012-03-05 08:52:55 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-08 15:51:13 -0500 |
commit | 48a7466f4dd0104d87a6d8dd0f25027be89c8453 (patch) | |
tree | aef96c8570d2dce03f120205103073d4282f1a5b /drivers/isdn | |
parent | fc258f89405f63b379324d1f8388ae4810297997 (diff) |
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')
-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, | |||
720 | 720 | ||
721 | tasklet_init(&cs->event_tasklet, gigaset_handle_event, | 721 | tasklet_init(&cs->event_tasklet, gigaset_handle_event, |
722 | (unsigned long) cs); | 722 | (unsigned long) cs); |
723 | tty_port_init(&cs->port); | ||
723 | cs->commands_pending = 0; | 724 | cs->commands_pending = 0; |
724 | cs->cur_at_seq = 0; | 725 | cs->cur_at_seq = 0; |
725 | cs->gotfwver = -1; | 726 | cs->gotfwver = -1; |
726 | cs->open_count = 0; | ||
727 | cs->dev = NULL; | 727 | cs->dev = NULL; |
728 | cs->tty = NULL; | ||
729 | cs->tty_dev = NULL; | 728 | cs->tty_dev = NULL; |
730 | cs->cidmode = cidmode != 0; | 729 | cs->cidmode = cidmode != 0; |
731 | cs->tabnocid = gigaset_tab_nocid; | 730 | 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 { | |||
433 | spinlock_t cmdlock; | 433 | spinlock_t cmdlock; |
434 | unsigned curlen, cmdbytes; | 434 | unsigned curlen, cmdbytes; |
435 | 435 | ||
436 | unsigned open_count; | 436 | struct tty_port port; |
437 | struct tty_struct *tty; | ||
438 | struct tasklet_struct if_wake_tasklet; | 437 | struct tasklet_struct if_wake_tasklet; |
439 | unsigned control_state; | 438 | unsigned control_state; |
440 | 439 | ||
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 = { | |||
146 | static int if_open(struct tty_struct *tty, struct file *filp) | 146 | static int if_open(struct tty_struct *tty, struct file *filp) |
147 | { | 147 | { |
148 | struct cardstate *cs; | 148 | struct cardstate *cs; |
149 | unsigned long flags; | ||
150 | 149 | ||
151 | gig_dbg(DEBUG_IF, "%d+%d: %s()", | 150 | gig_dbg(DEBUG_IF, "%d+%d: %s()", |
152 | tty->driver->minor_start, tty->index, __func__); | 151 | tty->driver->minor_start, tty->index, __func__); |
@@ -161,12 +160,10 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
161 | } | 160 | } |
162 | tty->driver_data = cs; | 161 | tty->driver_data = cs; |
163 | 162 | ||
164 | ++cs->open_count; | 163 | ++cs->port.count; |
165 | 164 | ||
166 | if (cs->open_count == 1) { | 165 | if (cs->port.count == 1) { |
167 | spin_lock_irqsave(&cs->lock, flags); | 166 | tty_port_tty_set(&cs->port, tty); |
168 | cs->tty = tty; | ||
169 | spin_unlock_irqrestore(&cs->lock, flags); | ||
170 | tty->low_latency = 1; | 167 | tty->low_latency = 1; |
171 | } | 168 | } |
172 | 169 | ||
@@ -177,7 +174,6 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
177 | static void if_close(struct tty_struct *tty, struct file *filp) | 174 | static void if_close(struct tty_struct *tty, struct file *filp) |
178 | { | 175 | { |
179 | struct cardstate *cs = tty->driver_data; | 176 | struct cardstate *cs = tty->driver_data; |
180 | unsigned long flags; | ||
181 | 177 | ||
182 | if (!cs) { /* happens if we didn't find cs in open */ | 178 | if (!cs) { /* happens if we didn't find cs in open */ |
183 | printk(KERN_DEBUG "%s: no cardstate\n", __func__); | 179 | printk(KERN_DEBUG "%s: no cardstate\n", __func__); |
@@ -190,15 +186,10 @@ static void if_close(struct tty_struct *tty, struct file *filp) | |||
190 | 186 | ||
191 | if (!cs->connected) | 187 | if (!cs->connected) |
192 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ | 188 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ |
193 | else if (!cs->open_count) | 189 | else if (!cs->port.count) |
194 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 190 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
195 | else { | 191 | else if (!--cs->port.count) |
196 | if (!--cs->open_count) { | 192 | tty_port_tty_set(&cs->port, NULL); |
197 | spin_lock_irqsave(&cs->lock, flags); | ||
198 | cs->tty = NULL; | ||
199 | spin_unlock_irqrestore(&cs->lock, flags); | ||
200 | } | ||
201 | } | ||
202 | 193 | ||
203 | mutex_unlock(&cs->mutex); | 194 | mutex_unlock(&cs->mutex); |
204 | 195 | ||
@@ -511,10 +502,13 @@ out: | |||
511 | /* wakeup tasklet for the write operation */ | 502 | /* wakeup tasklet for the write operation */ |
512 | static void if_wake(unsigned long data) | 503 | static void if_wake(unsigned long data) |
513 | { | 504 | { |
514 | struct cardstate *cs = (struct cardstate *) data; | 505 | struct cardstate *cs = (struct cardstate *)data; |
506 | struct tty_struct *tty = tty_port_tty_get(&cs->port); | ||
515 | 507 | ||
516 | if (cs->tty) | 508 | if (tty) { |
517 | tty_wakeup(cs->tty); | 509 | tty_wakeup(tty); |
510 | tty_kref_put(tty); | ||
511 | } | ||
518 | } | 512 | } |
519 | 513 | ||
520 | /*** interface to common ***/ | 514 | /*** interface to common ***/ |
@@ -567,18 +561,16 @@ void gigaset_if_free(struct cardstate *cs) | |||
567 | void gigaset_if_receive(struct cardstate *cs, | 561 | void gigaset_if_receive(struct cardstate *cs, |
568 | unsigned char *buffer, size_t len) | 562 | unsigned char *buffer, size_t len) |
569 | { | 563 | { |
570 | unsigned long flags; | 564 | struct tty_struct *tty = tty_port_tty_get(&cs->port); |
571 | struct tty_struct *tty; | ||
572 | 565 | ||
573 | spin_lock_irqsave(&cs->lock, flags); | 566 | if (tty == NULL) { |
574 | tty = cs->tty; | ||
575 | if (tty == NULL) | ||
576 | gig_dbg(DEBUG_IF, "receive on closed device"); | 567 | gig_dbg(DEBUG_IF, "receive on closed device"); |
577 | else { | 568 | return; |
578 | tty_insert_flip_string(tty, buffer, len); | ||
579 | tty_flip_buffer_push(tty); | ||
580 | } | 569 | } |
581 | spin_unlock_irqrestore(&cs->lock, flags); | 570 | |
571 | tty_insert_flip_string(tty, buffer, len); | ||
572 | tty_flip_buffer_push(tty); | ||
573 | tty_kref_put(tty); | ||
582 | } | 574 | } |
583 | EXPORT_SYMBOL_GPL(gigaset_if_receive); | 575 | EXPORT_SYMBOL_GPL(gigaset_if_receive); |
584 | 576 | ||