Merge tag 'arm-defconfig-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / sound / usb / pcm.c
index c66831e..4e5031a 100644 (file)
@@ -611,6 +611,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
        subs->hwptr_done = 0;
        subs->transfer_done = 0;
        subs->last_frame_number = 0;
+       subs->period_elapsed_pending = 0;
        runtime->delay = 0;
 
  unlock:
@@ -1393,6 +1394,10 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
                subs->trigger_tstamp_pending_update = false;
        }
 
+       if (period_elapsed && !subs->running) {
+               subs->period_elapsed_pending = 1;
+               period_elapsed = 0;
+       }
        spin_unlock_irqrestore(&subs->lock, flags);
        urb->transfer_buffer_length = bytes;
        if (period_elapsed)
@@ -1408,6 +1413,7 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
 {
        unsigned long flags;
        struct snd_urb_ctx *ctx = urb->context;
+       bool period_elapsed = false;
 
        spin_lock_irqsave(&subs->lock, flags);
        if (ctx->queued) {
@@ -1418,7 +1424,13 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
        }
 
        subs->last_frame_number = usb_get_current_frame_number(subs->dev);
+       if (subs->running) {
+               period_elapsed = subs->period_elapsed_pending;
+               subs->period_elapsed_pending = 0;
+       }
        spin_unlock_irqrestore(&subs->lock, flags);
+       if (period_elapsed)
+               snd_pcm_period_elapsed(subs->pcm_substream);
 }
 
 static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream,