summaryrefslogtreecommitdiffstats
path: root/sound/core/sound.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-20 09:41:44 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-20 09:41:44 -0700
commit7f06a8b26aba1dc03b42272dc0089a800372c575 (patch)
tree7c67198f83d069eb13fd417e022d111b7e4c82a1 /sound/core/sound.c
parentc3ad33c9bcb6616999953af76f16318120fe3691 (diff)
parentd71f4cece4bd97d05592836202fc04ff2e7817e3 (diff)
downloadlinux-7f06a8b26aba1dc03b42272dc0089a800372c575.tar.bz2
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (250 commits) ALSA: hda: Storage class should be before const qualifier ASoC: tpa6130a2: Remove CPVSS and HPVdd supplies ASoC: tpa6130a2: Define output pins with SND_SOC_DAPM_OUTPUT ASoC: sdp4430 - add sdp4430 pcm ops to DAI. ASoC: TWL6040: Enable earphone path in codec ASoC: SDP4430: Add support for Earphone speaker ASoC: SDP4430: Add sdp4430 machine driver ASoC: tlv320dac33: Avoid powering off while in BIAS_OFF ASoC: tlv320dac33: Use dev_dbg in dac33_hard_power function ALSA: sound/pci/asihpi: Use kzalloc ALSA: hdmi - dont fail on extra nodes ALSA: intelhdmi - add id for the CougarPoint chipset ALSA: intelhdmi - user friendly codec name ALSA: intelhdmi - add dependency on SND_DYNAMIC_MINORS ALSA: asihpi: incorrect range check ALSA: asihpi: testing the wrong variable ALSA: es1688: add pedantic range checks ARM: McBSP: Add support for omap4 in McBSP driver ARM: McBSP: Fix request for irq in OMAP4 OMAP: McBSP: Add 32-bit mode support ...
Diffstat (limited to 'sound/core/sound.c')
-rw-r--r--sound/core/sound.c73
1 files changed, 38 insertions, 35 deletions
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 563d1967a0ad..ac42af42b787 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
EXPORT_SYMBOL(snd_lookup_minor_data);
-static int __snd_open(struct inode *inode, struct file *file)
+#ifdef CONFIG_MODULES
+static struct snd_minor *autoload_device(unsigned int minor)
+{
+ int dev;
+ mutex_unlock(&sound_mutex); /* release lock temporarily */
+ dev = SNDRV_MINOR_DEVICE(minor);
+ if (dev == SNDRV_MINOR_CONTROL) {
+ /* /dev/aloadC? */
+ int card = SNDRV_MINOR_CARD(minor);
+ if (snd_cards[card] == NULL)
+ snd_request_card(card);
+ } else if (dev == SNDRV_MINOR_GLOBAL) {
+ /* /dev/aloadSEQ */
+ snd_request_other(minor);
+ }
+ mutex_lock(&sound_mutex); /* reacuire lock */
+ return snd_minors[minor];
+}
+#else /* !CONFIG_MODULES */
+#define autoload_device(minor) NULL
+#endif /* CONFIG_MODULES */
+
+static int snd_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct snd_minor *mptr = NULL;
@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file)
if (minor >= ARRAY_SIZE(snd_minors))
return -ENODEV;
+ mutex_lock(&sound_mutex);
mptr = snd_minors[minor];
if (mptr == NULL) {
-#ifdef CONFIG_MODULES
- int dev = SNDRV_MINOR_DEVICE(minor);
- if (dev == SNDRV_MINOR_CONTROL) {
- /* /dev/aloadC? */
- int card = SNDRV_MINOR_CARD(minor);
- if (snd_cards[card] == NULL)
- snd_request_card(card);
- } else if (dev == SNDRV_MINOR_GLOBAL) {
- /* /dev/aloadSEQ */
- snd_request_other(minor);
- }
-#ifndef CONFIG_SND_DYNAMIC_MINORS
- /* /dev/snd/{controlC?,seq} */
- mptr = snd_minors[minor];
- if (mptr == NULL)
-#endif
-#endif
+ mptr = autoload_device(minor);
+ if (!mptr) {
+ mutex_unlock(&sound_mutex);
return -ENODEV;
+ }
}
old_fops = file->f_op;
file->f_op = fops_get(mptr->f_ops);
if (file->f_op == NULL) {
file->f_op = old_fops;
- return -ENODEV;
+ err = -ENODEV;
}
- if (file->f_op->open)
+ mutex_unlock(&sound_mutex);
+ if (err < 0)
+ return err;
+
+ if (file->f_op->open) {
err = file->f_op->open(inode, file);
- if (err) {
- fops_put(file->f_op);
- file->f_op = fops_get(old_fops);
+ if (err) {
+ fops_put(file->f_op);
+ file->f_op = fops_get(old_fops);
+ }
}
fops_put(old_fops);
return err;
}
-
-/* BKL pushdown: nasty #ifdef avoidance wrapper */
-static int snd_open(struct inode *inode, struct file *file)
-{
- int ret;
-
- lock_kernel();
- ret = __snd_open(inode, file);
- unlock_kernel();
- return ret;
-}
-
static const struct file_operations snd_fops =
{
.owner = THIS_MODULE,