Merge tag 'iwlwifi-for-john-2014-10-23' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / sound / drivers / vx / vx_pcm.c
index deed5ef..1146727 100644 (file)
@@ -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;
 }
 
@@ -727,31 +724,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
  */
@@ -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;
        }