Commit 53f74053 authored by Jaroslav Kysela's avatar Jaroslav Kysela

[ALSA] Fix spinlock

au88x0 driver
Fixed possible spin deadlocks.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 469fb049
...@@ -2108,7 +2108,6 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) ...@@ -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))) || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
return -EBUSY; return -EBUSY;
spin_lock(&vortex->lock);
if (dma >= 0) { if (dma >= 0) {
en = 0; en = 0;
vortex_adb_checkinout(vortex, vortex_adb_checkinout(vortex,
...@@ -2304,7 +2303,6 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) ...@@ -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; vortex->dma_adb[dma].nr_ch = nr_ch;
spin_unlock(&vortex->lock);
#if 0 #if 0
/* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */ /* 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) ...@@ -2433,22 +2431,28 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} }
if (source & IRQ_PCMOUT) { if (source & IRQ_PCMOUT) {
/* ALSA period acknowledge. */ /* ALSA period acknowledge. */
spin_lock(&vortex->lock);
for (i = 0; i < NR_ADB; i++) { for (i = 0; i < NR_ADB; i++) {
if (vortex->dma_adb[i].fifo_status == FIFO_START) { if (vortex->dma_adb[i].fifo_status == FIFO_START) {
if (vortex_adbdma_bufshift(vortex, i)) ; if (vortex_adbdma_bufshift(vortex, i)) ;
spin_unlock(&vortex->lock);
snd_pcm_period_elapsed(vortex->dma_adb[i]. snd_pcm_period_elapsed(vortex->dma_adb[i].
substream); substream);
spin_lock(&vortex->lock);
} }
} }
#ifndef CHIP_AU8810 #ifndef CHIP_AU8810
for (i = 0; i < NR_WT; i++) { for (i = 0; i < NR_WT; i++) {
if (vortex->dma_wt[i].fifo_status == FIFO_START) { if (vortex->dma_wt[i].fifo_status == FIFO_START) {
if (vortex_wtdma_bufshift(vortex, i)) ; if (vortex_wtdma_bufshift(vortex, i)) ;
spin_unlock(&vortex->lock);
snd_pcm_period_elapsed(vortex->dma_wt[i]. snd_pcm_period_elapsed(vortex->dma_wt[i].
substream); substream);
spin_lock(&vortex->lock);
} }
} }
#endif #endif
spin_unlock(&vortex->lock);
handled = 1; handled = 1;
} }
//Acknowledge the Timer interrupt //Acknowledge the Timer interrupt
......
...@@ -206,6 +206,7 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream, ...@@ -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), 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)); params_period_bytes(hw_params), params_channels(hw_params));
*/ */
spin_lock_irq(&chip->lock);
// Make audio routes and config buffer DMA. // Make audio routes and config buffer DMA.
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
int dma, type = VORTEX_PCM_TYPE(substream->pcm); int dma, type = VORTEX_PCM_TYPE(substream->pcm);
...@@ -243,6 +244,7 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream, ...@@ -243,6 +244,7 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
params_periods(hw_params)); params_periods(hw_params));
} }
#endif #endif
spin_unlock_irq(&chip->lock);
return 0; return 0;
} }
...@@ -252,6 +254,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream) ...@@ -252,6 +254,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream)
vortex_t *chip = snd_pcm_substream_chip(substream); vortex_t *chip = snd_pcm_substream_chip(substream);
stream_t *stream = (stream_t *) (substream->runtime->private_data); stream_t *stream = (stream_t *) (substream->runtime->private_data);
spin_lock_irq(&chip->lock);
// Delete audio routes. // Delete audio routes.
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
if (stream != NULL) if (stream != NULL)
...@@ -266,6 +269,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream) ...@@ -266,6 +269,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream)
} }
#endif #endif
substream->runtime->private_data = NULL; substream->runtime->private_data = NULL;
spin_unlock_irq(&chip->lock);
return snd_pcm_lib_free_pages(substream); return snd_pcm_lib_free_pages(substream);
} }
...@@ -284,6 +288,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream) ...@@ -284,6 +288,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream)
else else
dir = 0; dir = 0;
fmt = vortex_alsafmt_aspfmt(runtime->format); fmt = vortex_alsafmt_aspfmt(runtime->format);
spin_lock_irq(&chip->lock);
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ , vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ ,
0); 0);
...@@ -298,6 +303,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream) ...@@ -298,6 +303,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream)
vortex_wtdma_setstartbuffer(chip, dma, 0); vortex_wtdma_setstartbuffer(chip, dma, 0);
} }
#endif #endif
spin_unlock_irq(&chip->lock);
return 0; return 0;
} }
...@@ -308,6 +314,7 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd) ...@@ -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; stream_t *stream = (stream_t *) substream->runtime->private_data;
int dma = stream->dma; int dma = stream->dma;
spin_lock(&chip->lock);
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
// do something to start the PCM engine // do something to start the PCM engine
...@@ -357,8 +364,10 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd) ...@@ -357,8 +364,10 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
#endif #endif
break; break;
default: default:
spin_unlock(&chip->lock);
return -EINVAL; return -EINVAL;
} }
spin_unlock(&chip->lock);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment