aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl5
-rw-r--r--include/sound/core.h3
-rw-r--r--sound/core/init.c56
-rw-r--r--sound/drivers/mpu401/mpu401.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c2
-rw-r--r--sound/pcmcia/vx/vxpocket.c4
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,
245int snd_card_disconnect(struct snd_card *card); 243int snd_card_disconnect(struct snd_card *card);
246int snd_card_free(struct snd_card *card); 244int snd_card_free(struct snd_card *card);
247int snd_card_free_when_closed(struct snd_card *card); 245int snd_card_free_when_closed(struct snd_card *card);
248int snd_card_free_in_thread(struct snd_card *card);
249int snd_card_register(struct snd_card *card); 246int snd_card_register(struct snd_card *card);
250int snd_card_info_init(void); 247int snd_card_info_init(void);
251int snd_card_info_done(void); 248int 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
84static 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
414EXPORT_SYMBOL(snd_card_free); 411EXPORT_SYMBOL(snd_card_free);
415 412
416static 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 */
445int 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
461EXPORT_SYMBOL(snd_card_free_in_thread);
462
463static void choose_default_id(struct snd_card *card) 413static 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
217static struct pnp_driver snd_mpu401_pnp_driver = { 217static 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 */
70static int snd_vxpocket_dev_free(struct snd_device *device) 70static 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/*