Merge tag 'net-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / sound / core / pcm_native.c
index c4aac70..17a85f4 100644 (file)
@@ -209,13 +209,13 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
        info->device = pcm->device;
        info->stream = substream->stream;
        info->subdevice = substream->number;
-       strlcpy(info->id, pcm->id, sizeof(info->id));
-       strlcpy(info->name, pcm->name, sizeof(info->name));
+       strscpy(info->id, pcm->id, sizeof(info->id));
+       strscpy(info->name, pcm->name, sizeof(info->name));
        info->dev_class = pcm->dev_class;
        info->dev_subclass = pcm->dev_subclass;
        info->subdevices_count = pstr->substream_count;
        info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
-       strlcpy(info->subname, substream->name, sizeof(info->subname));
+       strscpy(info->subname, substream->name, sizeof(info->subname));
 
        return 0;
 }
@@ -583,13 +583,13 @@ static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream,
 #endif
 }
 
-static void snd_pcm_sync_stop(struct snd_pcm_substream *substream)
+void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq)
 {
-       if (substream->runtime->stop_operating) {
+       if (substream->runtime && substream->runtime->stop_operating) {
                substream->runtime->stop_operating = false;
-               if (substream->ops->sync_stop)
+               if (substream->ops && substream->ops->sync_stop)
                        substream->ops->sync_stop(substream);
-               else if (substream->pcm->card->sync_irq > 0)
+               else if (sync_irq && substream->pcm->card->sync_irq > 0)
                        synchronize_irq(substream->pcm->card->sync_irq);
        }
 }
@@ -686,7 +686,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
                if (atomic_read(&substream->mmap_count))
                        return -EBADFD;
 
-       snd_pcm_sync_stop(substream);
+       snd_pcm_sync_stop(substream, true);
 
        params->rmask = ~0U;
        err = snd_pcm_hw_refine(substream, params);
@@ -809,7 +809,7 @@ static int do_hw_free(struct snd_pcm_substream *substream)
 {
        int result = 0;
 
-       snd_pcm_sync_stop(substream);
+       snd_pcm_sync_stop(substream, true);
        if (substream->ops->hw_free)
                result = substream->ops->hw_free(substream);
        if (substream->managed_buffer_alloc)
@@ -1421,8 +1421,10 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream,
                           snd_pcm_state_t state)
 {
        if (substream->runtime->trigger_master == substream &&
-           snd_pcm_running(substream))
+           snd_pcm_running(substream)) {
                substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
+               substream->runtime->stop_operating = true;
+       }
        return 0; /* unconditonally stop all substreams */
 }
 
@@ -1435,7 +1437,6 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
                runtime->status->state = state;
                snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);
        }
-       runtime->stop_operating = true;
        wake_up(&runtime->sleep);
        wake_up(&runtime->tsleep);
 }
@@ -1615,6 +1616,7 @@ static int snd_pcm_do_suspend(struct snd_pcm_substream *substream,
        if (! snd_pcm_running(substream))
                return 0;
        substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
+       runtime->stop_operating = true;
        return 0; /* suspend unconditionally */
 }
 
@@ -1672,25 +1674,26 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
        if (! pcm)
                return 0;
 
-       for (stream = 0; stream < 2; stream++) {
-               for (substream = pcm->streams[stream].substream;
-                    substream; substream = substream->next) {
-                       /* FIXME: the open/close code should lock this as well */
-                       if (substream->runtime == NULL)
-                               continue;
+       for_each_pcm_substream(pcm, stream, substream) {
+               /* FIXME: the open/close code should lock this as well */
+               if (!substream->runtime)
+                       continue;
 
-                       /*
-                        * Skip BE dai link PCM's that are internal and may
-                        * not have their substream ops set.
-                        */
-                       if (!substream->ops)
-                               continue;
+               /*
+                * Skip BE dai link PCM's that are internal and may
+                * not have their substream ops set.
+                */
+               if (!substream->ops)
+                       continue;
 
-                       err = snd_pcm_suspend(substream);
-                       if (err < 0 && err != -EBUSY)
-                               return err;
-               }
+               err = snd_pcm_suspend(substream);
+               if (err < 0 && err != -EBUSY)
+                       return err;
        }
+
+       for_each_pcm_substream(pcm, stream, substream)
+               snd_pcm_sync_stop(substream, false);
+
        return 0;
 }
 EXPORT_SYMBOL(snd_pcm_suspend_all);
@@ -1736,7 +1739,6 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream,
        snd_pcm_trigger_tstamp(substream);
        runtime->status->state = runtime->status->suspended_state;
        snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
-       snd_pcm_sync_stop(substream);
 }
 
 static const struct action_ops snd_pcm_action_resume = {
@@ -1866,7 +1868,7 @@ static int snd_pcm_do_prepare(struct snd_pcm_substream *substream,
                              snd_pcm_state_t state)
 {
        int err;
-       snd_pcm_sync_stop(substream);
+       snd_pcm_sync_stop(substream, true);
        err = substream->ops->prepare(substream);
        if (err < 0)
                return err;