diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-09-09 17:17:20 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-09-15 15:52:03 +0200 |
commit | db0a5214b8d6cc7a90ce3336d24a85b90cbb4e67 (patch) | |
tree | fdfcfaee149e83613d9854a763bbe3fe95f60292 /sound/drivers/vx/vx_pcm.c | |
parent | e7e69265b6269763799a5de9c263fbbce32cd3a3 (diff) | |
download | linux-db0a5214b8d6cc7a90ce3336d24a85b90cbb4e67.tar.bz2 |
ALSA: vx: Use nonatomic PCM ops
Rewrite VXpocket and VX222 drivers to use the new PCM nonatomic ops.
The former irq tasklet is replaced with a threaded irq handler, and
the tasklet for the PCM delayed start is simply merged into the normal
PCM trigger, as well as the replacement of spinlock with mutex.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/drivers/vx/vx_pcm.c')
-rw-r--r-- | sound/drivers/vx/vx_pcm.c | 68 |
1 files changed, 23 insertions, 45 deletions
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index deed5efff33c..11467272089e 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c @@ -229,7 +229,7 @@ static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *st vx_init_rmh(&rmh, CMD_PIPE_STATE); vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); - err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + err = vx_send_msg(chip, &rmh); if (! err) *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0; return err; @@ -280,7 +280,7 @@ static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe) vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); rmh.Cmd[0] |= 1; - err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + err = vx_send_msg(chip, &rmh); if (! err) { if (rmh.Stat[0]) err = 1; @@ -300,7 +300,7 @@ static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe) if (pipe->is_capture) rmh.Cmd[0] |= COMMAND_RECORD_MASK; rmh.Cmd[1] = 1 << pipe->number; - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } /* @@ -311,7 +311,7 @@ static int vx_send_irqa(struct vx_core *chip) struct vx_rmh rmh; vx_init_rmh(&rmh, CMD_SEND_IRQA); - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } @@ -389,7 +389,7 @@ static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe) struct vx_rmh rmh; vx_init_rmh(&rmh, CMD_STOP_PIPE); vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } @@ -477,7 +477,7 @@ static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe) vx_init_rmh(&rmh, CMD_START_ONE_STREAM); vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); vx_set_differed_time(chip, &rmh, pipe); - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } @@ -492,7 +492,7 @@ static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe) vx_init_rmh(&rmh, CMD_STOP_STREAM); vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } @@ -520,8 +520,6 @@ static struct snd_pcm_hardware vx_pcm_playback_hw = { }; -static void vx_pcm_delayed_start(unsigned long arg); - /* * vx_pcm_playback_open - open callback for playback */ @@ -553,7 +551,6 @@ static int vx_pcm_playback_open(struct snd_pcm_substream *subs) pipe->references++; pipe->substream = subs; - tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs); chip->playback_pipes[audio] = pipe; runtime->hw = vx_pcm_playback_hw; @@ -646,12 +643,12 @@ static int vx_pcm_playback_transfer_chunk(struct vx_core *chip, /* we don't need irqsave here, because this function * is called from either trigger callback or irq handler */ - spin_lock(&chip->lock); + mutex_lock(&chip->lock); vx_pseudo_dma_write(chip, runtime, pipe, size); err = vx_notify_end_of_buffer(chip, pipe); /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); - spin_unlock(&chip->lock); + mutex_unlock(&chip->lock); return err; } @@ -728,31 +725,6 @@ static void vx_pcm_playback_update(struct vx_core *chip, } /* - * start the stream and pipe. - * this function is called from tasklet, which is invoked by the trigger - * START callback. - */ -static void vx_pcm_delayed_start(unsigned long arg) -{ - struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg; - struct vx_core *chip = subs->pcm->private_data; - struct vx_pipe *pipe = subs->runtime->private_data; - int err; - - /* printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/ - - if ((err = vx_start_stream(chip, pipe)) < 0) { - snd_printk(KERN_ERR "vx: cannot start stream\n"); - return; - } - if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) { - snd_printk(KERN_ERR "vx: cannot start pipe\n"); - return; - } - /* printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/ -} - -/* * vx_pcm_playback_trigger - trigger callback for playback */ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd) @@ -769,11 +741,17 @@ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd) case SNDRV_PCM_TRIGGER_RESUME: if (! pipe->is_capture) vx_pcm_playback_transfer(chip, subs, pipe, 2); - /* FIXME: - * we trigger the pipe using tasklet, so that the interrupts are - * issued surely after the trigger is completed. - */ - tasklet_schedule(&pipe->start_tq); + err = vx_start_stream(chip, pipe); + if (err < 0) { + pr_debug("vx: cannot start stream\n"); + return err; + } + err = vx_toggle_pipe(chip, pipe, 1); + if (err < 0) { + pr_debug("vx: cannot start pipe\n"); + vx_stop_stream(chip, pipe); + return err; + } chip->pcm_running++; pipe->running = 1; break; @@ -955,7 +933,6 @@ static int vx_pcm_capture_open(struct snd_pcm_substream *subs) if (err < 0) return err; pipe->substream = subs; - tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs); chip->capture_pipes[audio] = pipe; /* check if monitoring is needed */ @@ -1082,7 +1059,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream count -= 3; } /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ - vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); + vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT); /* read the last pending 6 bytes */ count = DMA_READ_ALIGN; while (count > 0) { @@ -1099,7 +1076,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream _error: /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ - vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); + vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT); return; } @@ -1275,6 +1252,7 @@ int snd_vx_pcm_new(struct vx_core *chip) pcm->private_data = chip; pcm->private_free = snd_vx_pcm_free; pcm->info_flags = 0; + pcm->nonatomic = true; strcpy(pcm->name, chip->card->shortname); chip->pcm[i] = pcm; } |