diff options
-rw-r--r-- | drivers/char/tty_ldisc.c | 18 | ||||
-rw-r--r-- | include/linux/tty_ldisc.h | 2 |
2 files changed, 9 insertions, 11 deletions
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index acd76b767d4c..fd175e60aad5 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -142,7 +142,7 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc) | |||
142 | /* lock it */ | 142 | /* lock it */ |
143 | ldops->refcount++; | 143 | ldops->refcount++; |
144 | ld->ops = ldops; | 144 | ld->ops = ldops; |
145 | ld->refcount = 0; | 145 | atomic_set(&ld->users, 0); |
146 | err = 0; | 146 | err = 0; |
147 | } | 147 | } |
148 | } | 148 | } |
@@ -206,7 +206,7 @@ static void tty_ldisc_put(struct tty_ldisc *ld) | |||
206 | ldo->refcount--; | 206 | ldo->refcount--; |
207 | module_put(ldo->owner); | 207 | module_put(ldo->owner); |
208 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 208 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
209 | WARN_ON(ld->refcount); | 209 | WARN_ON(atomic_read(&ld->users)); |
210 | kfree(ld); | 210 | kfree(ld); |
211 | } | 211 | } |
212 | 212 | ||
@@ -297,7 +297,7 @@ static int tty_ldisc_try(struct tty_struct *tty) | |||
297 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 297 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
298 | ld = tty->ldisc; | 298 | ld = tty->ldisc; |
299 | if (test_bit(TTY_LDISC, &tty->flags)) { | 299 | if (test_bit(TTY_LDISC, &tty->flags)) { |
300 | ld->refcount++; | 300 | atomic_inc(&ld->users); |
301 | ret = 1; | 301 | ret = 1; |
302 | } | 302 | } |
303 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 303 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
@@ -324,7 +324,7 @@ struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) | |||
324 | { | 324 | { |
325 | /* wait_event is a macro */ | 325 | /* wait_event is a macro */ |
326 | wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); | 326 | wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); |
327 | WARN_ON(tty->ldisc->refcount == 0); | 327 | WARN_ON(atomic_read(&tty->ldisc->users) == 0); |
328 | return tty->ldisc; | 328 | return tty->ldisc; |
329 | } | 329 | } |
330 | EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); | 330 | EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); |
@@ -365,11 +365,9 @@ void tty_ldisc_deref(struct tty_ldisc *ld) | |||
365 | BUG_ON(ld == NULL); | 365 | BUG_ON(ld == NULL); |
366 | 366 | ||
367 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 367 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
368 | if (ld->refcount == 0) | 368 | if (atomic_read(&ld->users) == 0) |
369 | printk(KERN_ERR "tty_ldisc_deref: no references.\n"); | 369 | printk(KERN_ERR "tty_ldisc_deref: no references.\n"); |
370 | else | 370 | else if (atomic_dec_and_test(&ld->users)) |
371 | ld->refcount--; | ||
372 | if (ld->refcount == 0) | ||
373 | wake_up(&tty_ldisc_wait); | 371 | wake_up(&tty_ldisc_wait); |
374 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 372 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
375 | } | 373 | } |
@@ -536,10 +534,10 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty) | |||
536 | { | 534 | { |
537 | unsigned long flags; | 535 | unsigned long flags; |
538 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 536 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
539 | while (tty->ldisc->refcount) { | 537 | while (atomic_read(&tty->ldisc->users)) { |
540 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 538 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
541 | if (wait_event_timeout(tty_ldisc_wait, | 539 | if (wait_event_timeout(tty_ldisc_wait, |
542 | tty->ldisc->refcount == 0, 5 * HZ) == 0) | 540 | atomic_read(&tty->ldisc->users) == 0, 5 * HZ) == 0) |
543 | return -EBUSY; | 541 | return -EBUSY; |
544 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 542 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
545 | } | 543 | } |
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 40f38d896777..0c4ee9b88f85 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h | |||
@@ -144,7 +144,7 @@ struct tty_ldisc_ops { | |||
144 | 144 | ||
145 | struct tty_ldisc { | 145 | struct tty_ldisc { |
146 | struct tty_ldisc_ops *ops; | 146 | struct tty_ldisc_ops *ops; |
147 | int refcount; | 147 | atomic_t users; |
148 | }; | 148 | }; |
149 | 149 | ||
150 | #define TTY_LDISC_MAGIC 0x5403 | 150 | #define TTY_LDISC_MAGIC 0x5403 |