diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/arm/aaci.c | 24 | ||||
-rw-r--r-- | sound/arm/aaci.h | 2 |
2 files changed, 17 insertions, 9 deletions
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 24d3013c023..65685afd8f7 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -370,7 +370,7 @@ static int __aaci_pcm_open(struct aaci *aaci, struct aaci_runtime *aacirun) { struct snd_pcm_runtime *runtime = substream->runtime; - int ret; + int ret = 0; aacirun->substream = substream; runtime->private_data = aacirun; @@ -391,14 +391,15 @@ static int __aaci_pcm_open(struct aaci *aaci, */ runtime->hw.fifo_size = aaci->fifosize * 2; - ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED, - DRIVER_NAME, aaci); - if (ret) - goto out; - - return 0; + mutex_lock(&aaci->irq_lock); + if (!aaci->users++) { + ret = request_irq(aaci->dev->irq[0], aaci_irq, + IRQF_SHARED | IRQF_DISABLED, DRIVER_NAME, aaci); + if (ret != 0) + aaci->users--; + } + mutex_unlock(&aaci->irq_lock); - out: return ret; } @@ -414,7 +415,11 @@ static int aaci_pcm_close(struct snd_pcm_substream *substream) WARN_ON(aacirun->cr & CR_EN); aacirun->substream = NULL; - free_irq(aaci->dev->irq[0], aaci); + + mutex_lock(&aaci->irq_lock); + if (!--aaci->users) + free_irq(aaci->dev->irq[0], aaci); + mutex_unlock(&aaci->irq_lock); return 0; } @@ -943,6 +948,7 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) aaci = card->private_data; mutex_init(&aaci->ac97_sem); + mutex_init(&aaci->irq_lock); aaci->card = card; aaci->dev = dev; diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h index 6a4a2eebdda..04c4568413f 100644 --- a/sound/arm/aaci.h +++ b/sound/arm/aaci.h @@ -226,6 +226,8 @@ struct aaci { struct snd_card *card; void __iomem *base; unsigned int fifosize; + unsigned int users; + struct mutex irq_lock; /* AC'97 */ struct mutex ac97_sem; |