ASoC: dapm: Fix handling of custom_stop_condition on DAPM graph walks
[sfrench/cifs-2.6.git] / sound / soc / soc-dapm.c
index 81a7a12196ffed084305126b14b31deca9f4be8e..9cd87e47ee8f8e9b3806faab5d2f9fdb626b2703 100644 (file)
@@ -487,7 +487,8 @@ static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol,
                n = 1;
 
        new_wlist = krealloc(data->wlist,
-                       sizeof(*new_wlist) + sizeof(widget) * n, GFP_KERNEL);
+                            struct_size(new_wlist, widgets, n),
+                            GFP_KERNEL);
        if (!new_wlist)
                return -ENOMEM;
 
@@ -1156,8 +1157,8 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
                list_add_tail(&widget->work_list, list);
 
        if (custom_stop_condition && custom_stop_condition(widget, dir)) {
-               widget->endpoints[dir] = 1;
-               return widget->endpoints[dir];
+               list = NULL;
+               custom_stop_condition = NULL;
        }
 
        if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) {
@@ -1194,8 +1195,8 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
  *
  * Optionally, can be supplied with a function acting as a stopping condition.
  * This function takes the dapm widget currently being examined and the walk
- * direction as an arguments, it should return true if the walk should be
- * stopped and false otherwise.
+ * direction as an arguments, it should return true if widgets from that point
+ * in the graph onwards should not be added to the widget list.
  */
 static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
        struct list_head *list,
@@ -2193,7 +2194,10 @@ static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
 
 static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
 {
+       if (!dapm->debugfs_dapm)
+               return;
        debugfs_remove_recursive(dapm->debugfs_dapm);
+       dapm->debugfs_dapm = NULL;
 }
 
 #else
@@ -2245,7 +2249,7 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card,
        dapm_kcontrol_for_each_path(path, kcontrol) {
                found = 1;
                /* we now need to match the string in the enum to the path */
-               if (!(strcmp(path->name, e->texts[mux])))
+               if (e && !(strcmp(path->name, e->texts[mux])))
                        connect = true;
                else
                        connect = false;
@@ -3831,8 +3835,8 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
                                                ret);
                                        goto out;
                                }
-                               source->active++;
                        }
+                       source->active++;
                        ret = soc_dai_hw_params(&substream, params, source);
                        if (ret < 0)
                                goto out;
@@ -3853,8 +3857,8 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
                                                ret);
                                        goto out;
                                }
-                               sink->active++;
                        }
+                       sink->active++;
                        ret = soc_dai_hw_params(&substream, params, sink);
                        if (ret < 0)
                                goto out;