diff options
-rw-r--r-- | Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl | 5 | ||||
-rw-r--r-- | include/sound/core.h | 3 | ||||
-rw-r--r-- | sound/core/init.c | 56 | ||||
-rw-r--r-- | sound/drivers/mpu401/mpu401.c | 2 | ||||
-rw-r--r-- | sound/pcmcia/pdaudiocf/pdaudiocf.c | 2 | ||||
-rw-r--r-- | sound/pcmcia/vx/vxpocket.c | 4 |
6 files changed, 9 insertions, 63 deletions
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index b8dc51ca776c..4807ef79a94d 100644 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl | |||
@@ -1054,9 +1054,8 @@ | |||
1054 | 1054 | ||
1055 | <para> | 1055 | <para> |
1056 | For a device which allows hotplugging, you can use | 1056 | For a device which allows hotplugging, you can use |
1057 | <function>snd_card_free_in_thread</function>. This one will | 1057 | <function>snd_card_free_when_closed</function>. This one will |
1058 | postpone the destruction and wait in a kernel-thread until all | 1058 | postpone the destruction until all devices are closed. |
1059 | devices are closed. | ||
1060 | </para> | 1059 | </para> |
1061 | 1060 | ||
1062 | </section> | 1061 | </section> |
diff --git a/include/sound/core.h b/include/sound/core.h index cf4001cf6248..1359c532b68e 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/sched.h> /* wake_up() */ | 25 | #include <linux/sched.h> /* wake_up() */ |
26 | #include <linux/mutex.h> /* struct mutex */ | 26 | #include <linux/mutex.h> /* struct mutex */ |
27 | #include <linux/rwsem.h> /* struct rw_semaphore */ | 27 | #include <linux/rwsem.h> /* struct rw_semaphore */ |
28 | #include <linux/workqueue.h> /* struct workqueue_struct */ | ||
29 | #include <linux/pm.h> /* pm_message_t */ | 28 | #include <linux/pm.h> /* pm_message_t */ |
30 | 29 | ||
31 | /* forward declarations */ | 30 | /* forward declarations */ |
@@ -132,7 +131,6 @@ struct snd_card { | |||
132 | int shutdown; /* this card is going down */ | 131 | int shutdown; /* this card is going down */ |
133 | int free_on_last_close; /* free in context of file_release */ | 132 | int free_on_last_close; /* free in context of file_release */ |
134 | wait_queue_head_t shutdown_sleep; | 133 | wait_queue_head_t shutdown_sleep; |
135 | struct work_struct free_workq; /* for free in workqueue */ | ||
136 | struct device *dev; | 134 | struct device *dev; |
137 | 135 | ||
138 | #ifdef CONFIG_PM | 136 | #ifdef CONFIG_PM |
@@ -245,7 +243,6 @@ struct snd_card *snd_card_new(int idx, const char *id, | |||
245 | int snd_card_disconnect(struct snd_card *card); | 243 | int snd_card_disconnect(struct snd_card *card); |
246 | int snd_card_free(struct snd_card *card); | 244 | int snd_card_free(struct snd_card *card); |
247 | int snd_card_free_when_closed(struct snd_card *card); | 245 | int snd_card_free_when_closed(struct snd_card *card); |
248 | int snd_card_free_in_thread(struct snd_card *card); | ||
249 | int snd_card_register(struct snd_card *card); | 246 | int snd_card_register(struct snd_card *card); |
250 | int snd_card_info_init(void); | 247 | int snd_card_info_init(void); |
251 | int snd_card_info_done(void); | 248 | int snd_card_info_done(void); |
diff --git a/sound/core/init.c b/sound/core/init.c index 5850d99d21e3..d7607a25acdf 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -81,8 +81,6 @@ static inline int init_info_for_card(struct snd_card *card) | |||
81 | #define init_info_for_card(card) | 81 | #define init_info_for_card(card) |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | static void snd_card_free_thread(void * __card); | ||
85 | |||
86 | /** | 84 | /** |
87 | * snd_card_new - create and initialize a soundcard structure | 85 | * snd_card_new - create and initialize a soundcard structure |
88 | * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] | 86 | * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] |
@@ -145,7 +143,6 @@ struct snd_card *snd_card_new(int idx, const char *xid, | |||
145 | INIT_LIST_HEAD(&card->ctl_files); | 143 | INIT_LIST_HEAD(&card->ctl_files); |
146 | spin_lock_init(&card->files_lock); | 144 | spin_lock_init(&card->files_lock); |
147 | init_waitqueue_head(&card->shutdown_sleep); | 145 | init_waitqueue_head(&card->shutdown_sleep); |
148 | INIT_WORK(&card->free_workq, snd_card_free_thread, card); | ||
149 | #ifdef CONFIG_PM | 146 | #ifdef CONFIG_PM |
150 | mutex_init(&card->power_lock); | 147 | mutex_init(&card->power_lock); |
151 | init_waitqueue_head(&card->power_sleep); | 148 | init_waitqueue_head(&card->power_sleep); |
@@ -413,53 +410,6 @@ int snd_card_free(struct snd_card *card) | |||
413 | 410 | ||
414 | EXPORT_SYMBOL(snd_card_free); | 411 | EXPORT_SYMBOL(snd_card_free); |
415 | 412 | ||
416 | static void snd_card_free_thread(void * __card) | ||
417 | { | ||
418 | struct snd_card *card = __card; | ||
419 | struct module * module = card->module; | ||
420 | |||
421 | if (!try_module_get(module)) { | ||
422 | snd_printk(KERN_ERR "unable to lock toplevel module for card %i in free thread\n", card->number); | ||
423 | module = NULL; | ||
424 | } | ||
425 | |||
426 | snd_card_free(card); | ||
427 | |||
428 | module_put(module); | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * snd_card_free_in_thread - call snd_card_free() in thread | ||
433 | * @card: soundcard structure | ||
434 | * | ||
435 | * This function schedules the call of snd_card_free() function in a | ||
436 | * work queue. When all devices are released (non-busy), the work | ||
437 | * is woken up and calls snd_card_free(). | ||
438 | * | ||
439 | * When a card can be disconnected at any time by hotplug service, | ||
440 | * this function should be used in disconnect (or detach) callback | ||
441 | * instead of calling snd_card_free() directly. | ||
442 | * | ||
443 | * Returns - zero otherwise a negative error code if the start of thread failed. | ||
444 | */ | ||
445 | int snd_card_free_in_thread(struct snd_card *card) | ||
446 | { | ||
447 | if (card->files == NULL) { | ||
448 | snd_card_free(card); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | if (schedule_work(&card->free_workq)) | ||
453 | return 0; | ||
454 | |||
455 | snd_printk(KERN_ERR "schedule_work() failed in snd_card_free_in_thread for card %i\n", card->number); | ||
456 | /* try to free the structure immediately */ | ||
457 | snd_card_free(card); | ||
458 | return -EFAULT; | ||
459 | } | ||
460 | |||
461 | EXPORT_SYMBOL(snd_card_free_in_thread); | ||
462 | |||
463 | static void choose_default_id(struct snd_card *card) | 413 | static void choose_default_id(struct snd_card *card) |
464 | { | 414 | { |
465 | int i, len, idx_flag = 0, loops = SNDRV_CARDS; | 415 | int i, len, idx_flag = 0, loops = SNDRV_CARDS; |
@@ -742,9 +692,9 @@ EXPORT_SYMBOL(snd_card_file_add); | |||
742 | * | 692 | * |
743 | * This function removes the file formerly added to the card via | 693 | * This function removes the file formerly added to the card via |
744 | * snd_card_file_add() function. | 694 | * snd_card_file_add() function. |
745 | * If all files are removed and the release of the card is | 695 | * If all files are removed and snd_card_free_when_closed() was |
746 | * scheduled, it will wake up the the thread to call snd_card_free() | 696 | * called beforehand, it processes the pending release of |
747 | * (see snd_card_free_in_thread() function). | 697 | * resources. |
748 | * | 698 | * |
749 | * Returns zero or a negative error code. | 699 | * Returns zero or a negative error code. |
750 | */ | 700 | */ |
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 17cc105b26fc..2de181ad0b05 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c | |||
@@ -211,7 +211,7 @@ static void __devexit snd_mpu401_pnp_remove(struct pnp_dev *dev) | |||
211 | struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev); | 211 | struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev); |
212 | 212 | ||
213 | snd_card_disconnect(card); | 213 | snd_card_disconnect(card); |
214 | snd_card_free_in_thread(card); | 214 | snd_card_free_when_closed(card); |
215 | } | 215 | } |
216 | 216 | ||
217 | static struct pnp_driver snd_mpu401_pnp_driver = { | 217 | static struct pnp_driver snd_mpu401_pnp_driver = { |
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 1c09e5f49da8..fd3590fcaedb 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c | |||
@@ -206,7 +206,7 @@ static void snd_pdacf_detach(struct pcmcia_device *link) | |||
206 | snd_pdacf_powerdown(chip); | 206 | snd_pdacf_powerdown(chip); |
207 | chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */ | 207 | chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */ |
208 | snd_card_disconnect(chip->card); | 208 | snd_card_disconnect(chip->card); |
209 | snd_card_free_in_thread(chip->card); | 209 | snd_card_free_when_closed(chip->card); |
210 | } | 210 | } |
211 | 211 | ||
212 | /* | 212 | /* |
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index cafe6640cc1a..76c85cffb40e 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -65,7 +65,7 @@ static void vxpocket_release(struct pcmcia_device *link) | |||
65 | } | 65 | } |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * destructor, called from snd_card_free_in_thread() | 68 | * destructor, called from snd_card_free_when_closed() |
69 | */ | 69 | */ |
70 | static int snd_vxpocket_dev_free(struct snd_device *device) | 70 | static int snd_vxpocket_dev_free(struct snd_device *device) |
71 | { | 71 | { |
@@ -363,7 +363,7 @@ static void vxpocket_detach(struct pcmcia_device *link) | |||
363 | chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ | 363 | chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ |
364 | snd_card_disconnect(chip->card); | 364 | snd_card_disconnect(chip->card); |
365 | vxpocket_release(link); | 365 | vxpocket_release(link); |
366 | snd_card_free_in_thread(chip->card); | 366 | snd_card_free_when_closed(chip->card); |
367 | } | 367 | } |
368 | 368 | ||
369 | /* | 369 | /* |