Merge tag 'asoc-fix-v5.3-rc3' of https://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-rpi.git] / sound / soc / soc-dapm.c
index 55f8278..2790c00 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,
@@ -2155,23 +2156,25 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
 {
        struct dentry *d;
 
-       if (!parent)
+       if (!parent || IS_ERR(parent))
                return;
 
        dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
 
-       if (!dapm->debugfs_dapm) {
+       if (IS_ERR(dapm->debugfs_dapm)) {
                dev_warn(dapm->dev,
-                      "ASoC: Failed to create DAPM debugfs directory\n");
+                        "ASoC: Failed to create DAPM debugfs directory %ld\n",
+                        PTR_ERR(dapm->debugfs_dapm));
                return;
        }
 
        d = debugfs_create_file("bias_level", 0444,
                                dapm->debugfs_dapm, dapm,
                                &dapm_bias_fops);
-       if (!d)
+       if (IS_ERR(d))
                dev_warn(dapm->dev,
-                        "ASoC: Failed to create bias level debugfs file\n");
+                        "ASoC: Failed to create bias level debugfs file: %ld\n",
+                        PTR_ERR(d));
 }
 
 static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
@@ -2185,10 +2188,10 @@ static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
        d = debugfs_create_file(w->name, 0444,
                                dapm->debugfs_dapm, w,
                                &dapm_widget_power_fops);
-       if (!d)
+       if (IS_ERR(d))
                dev_warn(w->dapm->dev,
-                       "ASoC: Failed to create %s debugfs file\n",
-                       w->name);
+                        "ASoC: Failed to create %s debugfs file: %ld\n",
+                        w->name, PTR_ERR(d));
 }
 
 static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
@@ -2248,7 +2251,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;
@@ -3703,6 +3706,8 @@ request_failed:
                dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
                        w->name, ret);
 
+       kfree_const(w->sname);
+       kfree(w);
        return ERR_PTR(ret);
 }