Merge tag 'fsnotify_for_v5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / sound / soc / soc-pcm.c
index c46ad0f..4878d22 100644 (file)
@@ -446,6 +446,42 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
        hw->rate_max = min_not_zero(hw->rate_max, rate_max);
 }
 
+static int soc_pcm_components_open(struct snd_pcm_substream *substream,
+                                  struct snd_soc_component **last)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_rtdcom_list *rtdcom;
+       struct snd_soc_component *component;
+       int ret = 0;
+
+       for_each_rtdcom(rtd, rtdcom) {
+               component = rtdcom->component;
+               *last = component;
+
+               if (component->driver->module_get_upon_open &&
+                   !try_module_get(component->dev->driver->owner)) {
+                       dev_err(component->dev,
+                               "ASoC: can't get module %s\n",
+                               component->name);
+                       return -ENODEV;
+               }
+
+               if (!component->driver->ops ||
+                   !component->driver->ops->open)
+                       continue;
+
+               ret = component->driver->ops->open(substream);
+               if (ret < 0) {
+                       dev_err(component->dev,
+                               "ASoC: can't open component %s: %d\n",
+                               component->name, ret);
+                       return ret;
+               }
+       }
+       *last = NULL;
+       return 0;
+}
+
 static int soc_pcm_components_close(struct snd_pcm_substream *substream,
                                    struct snd_soc_component *last)
 {
@@ -459,11 +495,9 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream,
                if (component == last)
                        break;
 
-               if (!component->driver->ops ||
-                   !component->driver->ops->close)
-                       continue;
-
-               component->driver->ops->close(substream);
+               if (component->driver->ops &&
+                   component->driver->ops->close)
+                       component->driver->ops->close(substream);
 
                if (component->driver->module_get_upon_open)
                        module_put(component->dev->driver->owner);
@@ -510,28 +544,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
                }
        }
 
-       for_each_rtdcom(rtd, rtdcom) {
-               component = rtdcom->component;
-
-               if (!component->driver->ops ||
-                   !component->driver->ops->open)
-                       continue;
-
-               if (component->driver->module_get_upon_open &&
-                   !try_module_get(component->dev->driver->owner)) {
-                       ret = -ENODEV;
-                       goto module_err;
-               }
-
-               ret = component->driver->ops->open(substream);
-               if (ret < 0) {
-                       dev_err(component->dev,
-                               "ASoC: can't open component %s: %d\n",
-                               component->name, ret);
-                       goto component_err;
-               }
-       }
-       component = NULL;
+       ret = soc_pcm_components_open(substream, &component);
+       if (ret < 0)
+               goto component_err;
 
        for_each_rtd_codec_dai(rtd, i, codec_dai) {
                if (codec_dai->driver->ops->startup) {
@@ -638,7 +653,7 @@ codec_dai_err:
 
 component_err:
        soc_pcm_components_close(substream, component);
-module_err:
+
        if (cpu_dai->driver->ops->shutdown)
                cpu_dai->driver->ops->shutdown(substream, cpu_dai);
 out:
@@ -990,6 +1005,14 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                goto interface_err;
 
+       /* store the parameters for each DAIs */
+       cpu_dai->rate = params_rate(params);
+       cpu_dai->channels = params_channels(params);
+       cpu_dai->sample_bits =
+               snd_pcm_format_physical_width(params_format(params));
+
+       snd_soc_dapm_update_dai(substream, params, cpu_dai);
+
        for_each_rtdcom(rtd, rtdcom) {
                component = rtdcom->component;
 
@@ -1007,14 +1030,6 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
        }
        component = NULL;
 
-       /* store the parameters for each DAIs */
-       cpu_dai->rate = params_rate(params);
-       cpu_dai->channels = params_channels(params);
-       cpu_dai->sample_bits =
-               snd_pcm_format_physical_width(params_format(params));
-
-       snd_soc_dapm_update_dai(substream, params, cpu_dai);
-
        ret = soc_pcm_params_symmetry(substream, params);
         if (ret)
                goto component_err;
@@ -1027,6 +1042,7 @@ component_err:
 
        if (cpu_dai->driver->ops->hw_free)
                cpu_dai->driver->ops->hw_free(substream, cpu_dai);
+       cpu_dai->rate = 0;
 
 interface_err:
        i = rtd->num_codecs;