diff options
Diffstat (limited to 'sound/core/init.c')
-rw-r--r-- | sound/core/init.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/sound/core/init.c b/sound/core/init.c index 0c4dc40376a7..d64416f0a281 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -49,8 +49,7 @@ static const struct file_operations snd_shutdown_f_ops; /* locked for registering/using */ static DECLARE_BITMAP(snd_cards_lock, SNDRV_CARDS); -struct snd_card *snd_cards[SNDRV_CARDS]; -EXPORT_SYMBOL(snd_cards); +static struct snd_card *snd_cards[SNDRV_CARDS]; static DEFINE_MUTEX(snd_card_mutex); @@ -268,6 +267,26 @@ int snd_card_new(struct device *parent, int idx, const char *xid, } EXPORT_SYMBOL(snd_card_new); +/** + * snd_card_ref - Get the card object from the index + * @idx: the card index + * + * Returns a card object corresponding to the given index or NULL if not found. + * Release the object via snd_card_unref(). + */ +struct snd_card *snd_card_ref(int idx) +{ + struct snd_card *card; + + mutex_lock(&snd_card_mutex); + card = snd_cards[idx]; + if (card) + get_device(&card->card_dev); + mutex_unlock(&snd_card_mutex); + return card; +} +EXPORT_SYMBOL_GPL(snd_card_ref); + /* return non-zero if a card is already locked */ int snd_card_locked(int card) { @@ -382,14 +401,7 @@ int snd_card_disconnect(struct snd_card *card) card->shutdown = 1; spin_unlock(&card->files_lock); - /* phase 1: disable fops (user space) operations for ALSA API */ - mutex_lock(&snd_card_mutex); - snd_cards[card->number] = NULL; - clear_bit(card->number, snd_cards_lock); - mutex_unlock(&snd_card_mutex); - - /* phase 2: replace file->f_op with special dummy operations */ - + /* replace file->f_op with special dummy operations */ spin_lock(&card->files_lock); list_for_each_entry(mfile, &card->files_list, list) { /* it's critical part, use endless loop */ @@ -405,7 +417,7 @@ int snd_card_disconnect(struct snd_card *card) } spin_unlock(&card->files_lock); - /* phase 3: notify all connected devices about disconnection */ + /* notify all connected devices about disconnection */ /* at this point, they cannot respond to any calls except release() */ #if IS_ENABLED(CONFIG_SND_MIXER_OSS) @@ -421,6 +433,13 @@ int snd_card_disconnect(struct snd_card *card) device_del(&card->card_dev); card->registered = false; } + + /* disable fops (user space) operations for ALSA API */ + mutex_lock(&snd_card_mutex); + snd_cards[card->number] = NULL; + clear_bit(card->number, snd_cards_lock); + mutex_unlock(&snd_card_mutex); + #ifdef CONFIG_PM wake_up(&card->power_sleep); #endif |