diff options
author | Tilman Schmidt <tilman@imap.cc> | 2008-02-06 04:38:30 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:41:12 -0500 |
commit | ee51ef0ecbb68fdd7beab8f7b0a20eebe6fd0a62 (patch) | |
tree | 3886b66626b763d98f2bd71eae6d89689248d210 | |
parent | e468c04894f36045cf93d1384183a461014b6840 (diff) |
ser_gigaset: convert mutex to completion
The ser_gigaset ISDN driver was using a mutex in its close() method for
waiting for other running ldisc methods to finish. That's what completions
are for. Incidentally, this also avoids a spurious "BUG: lock held at task
exit time" message when the driver's userspace daemon daemonizes itself.
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/isdn/gigaset/ser-gigaset.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index f2bb1aeb0c80..fceeb1d57682 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/poll.h> | 19 | #include <linux/poll.h> |
20 | #include <linux/completion.h> | ||
20 | 21 | ||
21 | /* Version Information */ | 22 | /* Version Information */ |
22 | #define DRIVER_AUTHOR "Tilman Schmidt" | 23 | #define DRIVER_AUTHOR "Tilman Schmidt" |
@@ -48,7 +49,7 @@ struct ser_cardstate { | |||
48 | struct platform_device dev; | 49 | struct platform_device dev; |
49 | struct tty_struct *tty; | 50 | struct tty_struct *tty; |
50 | atomic_t refcnt; | 51 | atomic_t refcnt; |
51 | struct mutex dead_mutex; | 52 | struct completion dead_cmp; |
52 | }; | 53 | }; |
53 | 54 | ||
54 | static struct platform_driver device_driver = { | 55 | static struct platform_driver device_driver = { |
@@ -498,7 +499,7 @@ static struct cardstate *cs_get(struct tty_struct *tty) | |||
498 | static void cs_put(struct cardstate *cs) | 499 | static void cs_put(struct cardstate *cs) |
499 | { | 500 | { |
500 | if (atomic_dec_and_test(&cs->hw.ser->refcnt)) | 501 | if (atomic_dec_and_test(&cs->hw.ser->refcnt)) |
501 | mutex_unlock(&cs->hw.ser->dead_mutex); | 502 | complete(&cs->hw.ser->dead_cmp); |
502 | } | 503 | } |
503 | 504 | ||
504 | /* | 505 | /* |
@@ -527,8 +528,8 @@ gigaset_tty_open(struct tty_struct *tty) | |||
527 | 528 | ||
528 | cs->dev = &cs->hw.ser->dev.dev; | 529 | cs->dev = &cs->hw.ser->dev.dev; |
529 | cs->hw.ser->tty = tty; | 530 | cs->hw.ser->tty = tty; |
530 | mutex_init(&cs->hw.ser->dead_mutex); | ||
531 | atomic_set(&cs->hw.ser->refcnt, 1); | 531 | atomic_set(&cs->hw.ser->refcnt, 1); |
532 | init_completion(&cs->hw.ser->dead_cmp); | ||
532 | 533 | ||
533 | tty->disc_data = cs; | 534 | tty->disc_data = cs; |
534 | 535 | ||
@@ -543,7 +544,6 @@ gigaset_tty_open(struct tty_struct *tty) | |||
543 | } | 544 | } |
544 | 545 | ||
545 | gig_dbg(DEBUG_INIT, "Startup of HLL done"); | 546 | gig_dbg(DEBUG_INIT, "Startup of HLL done"); |
546 | mutex_lock(&cs->hw.ser->dead_mutex); | ||
547 | return 0; | 547 | return 0; |
548 | 548 | ||
549 | error: | 549 | error: |
@@ -577,7 +577,7 @@ gigaset_tty_close(struct tty_struct *tty) | |||
577 | else { | 577 | else { |
578 | /* wait for running methods to finish */ | 578 | /* wait for running methods to finish */ |
579 | if (!atomic_dec_and_test(&cs->hw.ser->refcnt)) | 579 | if (!atomic_dec_and_test(&cs->hw.ser->refcnt)) |
580 | mutex_lock(&cs->hw.ser->dead_mutex); | 580 | wait_for_completion(&cs->hw.ser->dead_cmp); |
581 | } | 581 | } |
582 | 582 | ||
583 | /* stop operations */ | 583 | /* stop operations */ |