aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-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
4 files changed, 7 insertions, 57 deletions
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/*