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; |
