diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-25 10:52:33 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-25 16:20:22 -0500 |
commit | b60fb519d7977e606621af85585c3677fc290ef8 (patch) | |
tree | c585e8f2e08717547a7d570ef84fbf2e8a6b874e | |
parent | 250c7a61c35a258e2422b3d55c61bfbad33326be (diff) |
ALSA: AACI: fix multiple IRQ claiming
Claiming the IRQ each time a playback or capture interface is opened
is wasteful; the second copy of the registered handler is identical to
the first and just wastes resources. Track the number of opens and
only register the handler when necessary.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-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 24d3013c0231..65685afd8f77 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -370,7 +370,7 @@ static int __aaci_pcm_open(struct aaci *aaci, | |||
370 | struct aaci_runtime *aacirun) | 370 | struct aaci_runtime *aacirun) |
371 | { | 371 | { |
372 | struct snd_pcm_runtime *runtime = substream->runtime; | 372 | struct snd_pcm_runtime *runtime = substream->runtime; |
373 | int ret; | 373 | int ret = 0; |
374 | 374 | ||
375 | aacirun->substream = substream; | 375 | aacirun->substream = substream; |
376 | runtime->private_data = aacirun; | 376 | runtime->private_data = aacirun; |
@@ -391,14 +391,15 @@ static int __aaci_pcm_open(struct aaci *aaci, | |||
391 | */ | 391 | */ |
392 | runtime->hw.fifo_size = aaci->fifosize * 2; | 392 | runtime->hw.fifo_size = aaci->fifosize * 2; |
393 | 393 | ||
394 | ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED, | 394 | mutex_lock(&aaci->irq_lock); |
395 | DRIVER_NAME, aaci); | 395 | if (!aaci->users++) { |
396 | if (ret) | 396 | ret = request_irq(aaci->dev->irq[0], aaci_irq, |
397 | goto out; | 397 | IRQF_SHARED | IRQF_DISABLED, DRIVER_NAME, aaci); |
398 | 398 | if (ret != 0) | |
399 | return 0; | 399 | aaci->users--; |
400 | } | ||
401 | mutex_unlock(&aaci->irq_lock); | ||
400 | 402 | ||
401 | out: | ||
402 | return ret; | 403 | return ret; |
403 | } | 404 | } |
404 | 405 | ||
@@ -414,7 +415,11 @@ static int aaci_pcm_close(struct snd_pcm_substream *substream) | |||
414 | WARN_ON(aacirun->cr & CR_EN); | 415 | WARN_ON(aacirun->cr & CR_EN); |
415 | 416 | ||
416 | aacirun->substream = NULL; | 417 | aacirun->substream = NULL; |
417 | free_irq(aaci->dev->irq[0], aaci); | 418 | |
419 | mutex_lock(&aaci->irq_lock); | ||
420 | if (!--aaci->users) | ||
421 | free_irq(aaci->dev->irq[0], aaci); | ||
422 | mutex_unlock(&aaci->irq_lock); | ||
418 | 423 | ||
419 | return 0; | 424 | return 0; |
420 | } | 425 | } |
@@ -943,6 +948,7 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) | |||
943 | 948 | ||
944 | aaci = card->private_data; | 949 | aaci = card->private_data; |
945 | mutex_init(&aaci->ac97_sem); | 950 | mutex_init(&aaci->ac97_sem); |
951 | mutex_init(&aaci->irq_lock); | ||
946 | aaci->card = card; | 952 | aaci->card = card; |
947 | aaci->dev = dev; | 953 | aaci->dev = dev; |
948 | 954 | ||
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h index 6a4a2eebdda1..04c4568413f4 100644 --- a/sound/arm/aaci.h +++ b/sound/arm/aaci.h | |||
@@ -226,6 +226,8 @@ struct aaci { | |||
226 | struct snd_card *card; | 226 | struct snd_card *card; |
227 | void __iomem *base; | 227 | void __iomem *base; |
228 | unsigned int fifosize; | 228 | unsigned int fifosize; |
229 | unsigned int users; | ||
230 | struct mutex irq_lock; | ||
229 | 231 | ||
230 | /* AC'97 */ | 232 | /* AC'97 */ |
231 | struct mutex ac97_sem; | 233 | struct mutex ac97_sem; |