aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@suse.cz>2005-01-03 16:17:36 +0100
committerJaroslav Kysela <perex@suse.cz>2005-01-03 16:17:36 +0100
commit53f740539cd816e04690b332624f4413e35b1cef (patch)
tree62dca0ef47b409d4249161af1e8e10104f39618c /sound
parent469fb049ff5b775153d600811928d0a44215edb5 (diff)
downloadhistory-53f740539cd816e04690b332624f4413e35b1cef.tar.gz
[ALSA] Fix spinlock
au88x0 driver Fixed possible spin deadlocks. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/au88x0/au88x0_core.c8
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c9
2 files changed, 15 insertions, 2 deletions
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index b7b17bbb5478c9..772bc612465031 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2108,7 +2108,6 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
|| ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
return -EBUSY;
- spin_lock(&vortex->lock);
if (dma >= 0) {
en = 0;
vortex_adb_checkinout(vortex,
@@ -2304,7 +2303,6 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
}
}
vortex->dma_adb[dma].nr_ch = nr_ch;
- spin_unlock(&vortex->lock);
#if 0
/* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */
@@ -2433,22 +2431,28 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
if (source & IRQ_PCMOUT) {
/* ALSA period acknowledge. */
+ spin_lock(&vortex->lock);
for (i = 0; i < NR_ADB; i++) {
if (vortex->dma_adb[i].fifo_status == FIFO_START) {
if (vortex_adbdma_bufshift(vortex, i)) ;
+ spin_unlock(&vortex->lock);
snd_pcm_period_elapsed(vortex->dma_adb[i].
substream);
+ spin_lock(&vortex->lock);
}
}
#ifndef CHIP_AU8810
for (i = 0; i < NR_WT; i++) {
if (vortex->dma_wt[i].fifo_status == FIFO_START) {
if (vortex_wtdma_bufshift(vortex, i)) ;
+ spin_unlock(&vortex->lock);
snd_pcm_period_elapsed(vortex->dma_wt[i].
substream);
+ spin_lock(&vortex->lock);
}
}
#endif
+ spin_unlock(&vortex->lock);
handled = 1;
}
//Acknowledge the Timer interrupt
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index c9dfc32cc3ea05..066e6c698a7217 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -206,6 +206,7 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
params_period_bytes(hw_params), params_channels(hw_params));
*/
+ spin_lock_irq(&chip->lock);
// Make audio routes and config buffer DMA.
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
int dma, type = VORTEX_PCM_TYPE(substream->pcm);
@@ -243,6 +244,7 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
params_periods(hw_params));
}
#endif
+ spin_unlock_irq(&chip->lock);
return 0;
}
@@ -252,6 +254,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream)
vortex_t *chip = snd_pcm_substream_chip(substream);
stream_t *stream = (stream_t *) (substream->runtime->private_data);
+ spin_lock_irq(&chip->lock);
// Delete audio routes.
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
if (stream != NULL)
@@ -266,6 +269,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream)
}
#endif
substream->runtime->private_data = NULL;
+ spin_unlock_irq(&chip->lock);
return snd_pcm_lib_free_pages(substream);
}
@@ -284,6 +288,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream)
else
dir = 0;
fmt = vortex_alsafmt_aspfmt(runtime->format);
+ spin_lock_irq(&chip->lock);
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ ,
0);
@@ -298,6 +303,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream)
vortex_wtdma_setstartbuffer(chip, dma, 0);
}
#endif
+ spin_unlock_irq(&chip->lock);
return 0;
}
@@ -308,6 +314,7 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
stream_t *stream = (stream_t *) substream->runtime->private_data;
int dma = stream->dma;
+ spin_lock(&chip->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
// do something to start the PCM engine
@@ -357,8 +364,10 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
#endif
break;
default:
+ spin_unlock(&chip->lock);
return -EINVAL;
}
+ spin_unlock(&chip->lock);
return 0;
}