Loading sound/soc/soc-dapm.c +90 −60 Original line number Diff line number Diff line Loading @@ -2884,7 +2884,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, { int i, r, ret = 0; mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); for (i = 0; i < num; i++) { r = snd_soc_dapm_add_route(dapm, route); if (r < 0) { Loading Loading @@ -2915,7 +2915,7 @@ int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm, { int i; mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); for (i = 0; i < num; i++) { snd_soc_dapm_del_route(dapm, route); route++; Loading Loading @@ -3778,18 +3778,27 @@ static int snd_soc_dapm_dai_link_put(struct snd_kcontrol *kcontrol, return 0; } int snd_soc_dapm_new_pcm(struct snd_soc_card *card, static void snd_soc_dapm_free_kcontrol(struct snd_soc_card *card, unsigned long *private_value, int num_params, const char **w_param_text) { int count; devm_kfree(card->dev, (void *)*private_value); for (count = 0 ; count < num_params; count++) devm_kfree(card->dev, (void *)w_param_text[count]); devm_kfree(card->dev, w_param_text); } static struct snd_kcontrol_new * snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card, char *link_name, const struct snd_soc_pcm_stream *params, unsigned int num_params, struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) int num_params, const char **w_param_text, unsigned long *private_value) { struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget *w; char *link_name; int ret, count; unsigned long private_value; const char **w_param_text; struct soc_enum w_param_enum[] = { SOC_ENUM_SINGLE(0, 0, 0, NULL), }; Loading @@ -3798,19 +3807,9 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, snd_soc_dapm_dai_link_get, snd_soc_dapm_dai_link_put), }; struct snd_kcontrol_new *kcontrol_news; const struct snd_soc_pcm_stream *config = params; w_param_text = devm_kcalloc(card->dev, num_params, sizeof(char *), GFP_KERNEL); if (!w_param_text) return -ENOMEM; link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s", source->name, sink->name); if (!link_name) { ret = -ENOMEM; goto outfree_w_param; } int count; for (count = 0 ; count < num_params; count++) { if (!config->stream_name) { Loading @@ -3821,57 +3820,94 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, devm_kasprintf(card->dev, GFP_KERNEL, "Anonymous Configuration %d", count); if (!w_param_text[count]) { ret = -ENOMEM; goto outfree_link_name; } } else { w_param_text[count] = devm_kmemdup(card->dev, config->stream_name, strlen(config->stream_name) + 1, GFP_KERNEL); if (!w_param_text[count]) { ret = -ENOMEM; goto outfree_link_name; } } if (!w_param_text[count]) goto outfree_w_param; config++; } w_param_enum[0].items = num_params; w_param_enum[0].texts = w_param_text; memset(&template, 0, sizeof(template)); template.reg = SND_SOC_NOPM; template.id = snd_soc_dapm_dai_link; template.name = link_name; template.event = snd_soc_dai_link_event; template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD; template.num_kcontrols = 1; /* duplicate w_param_enum on heap so that memory persists */ private_value = *private_value = (unsigned long) devm_kmemdup(card->dev, (void *)(kcontrol_dai_link[0].private_value), sizeof(struct soc_enum), GFP_KERNEL); if (!private_value) { if (!*private_value) { dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", link_name); ret = -ENOMEM; goto outfree_link_name; goto outfree_w_param; } kcontrol_dai_link[0].private_value = private_value; kcontrol_dai_link[0].private_value = *private_value; /* duplicate kcontrol_dai_link on heap so that memory persists */ template.kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0], kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0], sizeof(struct snd_kcontrol_new), GFP_KERNEL); if (!template.kcontrol_news) { if (!kcontrol_news) { dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", link_name); goto outfree_w_param; } return kcontrol_news; outfree_w_param: snd_soc_dapm_free_kcontrol(card, private_value, num_params, w_param_text); return NULL; } int snd_soc_dapm_new_pcm(struct snd_soc_card *card, const struct snd_soc_pcm_stream *params, unsigned int num_params, struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget *w; const char **w_param_text; unsigned long private_value; char *link_name; int ret; link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s", source->name, sink->name); if (!link_name) return -ENOMEM; memset(&template, 0, sizeof(template)); template.reg = SND_SOC_NOPM; template.id = snd_soc_dapm_dai_link; template.name = link_name; template.event = snd_soc_dai_link_event; template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD; template.kcontrol_news = NULL; /* allocate memory for control, only in case of multiple configs */ if (num_params > 1) { w_param_text = devm_kcalloc(card->dev, num_params, sizeof(char *), GFP_KERNEL); if (!w_param_text) { ret = -ENOMEM; goto outfree_private_value; goto param_fail; } template.num_kcontrols = 1; template.kcontrol_news = snd_soc_dapm_alloc_kcontrol(card, link_name, params, num_params, w_param_text, &private_value); if (!template.kcontrol_news) { ret = -ENOMEM; goto param_fail; } } else { w_param_text = NULL; } dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template); Loading Loading @@ -3903,15 +3939,9 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, devm_kfree(card->dev, w); outfree_kcontrol_news: devm_kfree(card->dev, (void *)template.kcontrol_news); outfree_private_value: devm_kfree(card->dev, (void *)private_value); outfree_link_name: snd_soc_dapm_free_kcontrol(card, &private_value, num_params, w_param_text); param_fail: devm_kfree(card->dev, link_name); outfree_w_param: for (count = 0 ; count < num_params; count++) devm_kfree(card->dev, (void *)w_param_text[count]); devm_kfree(card->dev, w_param_text); return ret; } Loading Loading
sound/soc/soc-dapm.c +90 −60 Original line number Diff line number Diff line Loading @@ -2884,7 +2884,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, { int i, r, ret = 0; mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); for (i = 0; i < num; i++) { r = snd_soc_dapm_add_route(dapm, route); if (r < 0) { Loading Loading @@ -2915,7 +2915,7 @@ int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm, { int i; mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); for (i = 0; i < num; i++) { snd_soc_dapm_del_route(dapm, route); route++; Loading Loading @@ -3778,18 +3778,27 @@ static int snd_soc_dapm_dai_link_put(struct snd_kcontrol *kcontrol, return 0; } int snd_soc_dapm_new_pcm(struct snd_soc_card *card, static void snd_soc_dapm_free_kcontrol(struct snd_soc_card *card, unsigned long *private_value, int num_params, const char **w_param_text) { int count; devm_kfree(card->dev, (void *)*private_value); for (count = 0 ; count < num_params; count++) devm_kfree(card->dev, (void *)w_param_text[count]); devm_kfree(card->dev, w_param_text); } static struct snd_kcontrol_new * snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card, char *link_name, const struct snd_soc_pcm_stream *params, unsigned int num_params, struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) int num_params, const char **w_param_text, unsigned long *private_value) { struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget *w; char *link_name; int ret, count; unsigned long private_value; const char **w_param_text; struct soc_enum w_param_enum[] = { SOC_ENUM_SINGLE(0, 0, 0, NULL), }; Loading @@ -3798,19 +3807,9 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, snd_soc_dapm_dai_link_get, snd_soc_dapm_dai_link_put), }; struct snd_kcontrol_new *kcontrol_news; const struct snd_soc_pcm_stream *config = params; w_param_text = devm_kcalloc(card->dev, num_params, sizeof(char *), GFP_KERNEL); if (!w_param_text) return -ENOMEM; link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s", source->name, sink->name); if (!link_name) { ret = -ENOMEM; goto outfree_w_param; } int count; for (count = 0 ; count < num_params; count++) { if (!config->stream_name) { Loading @@ -3821,57 +3820,94 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, devm_kasprintf(card->dev, GFP_KERNEL, "Anonymous Configuration %d", count); if (!w_param_text[count]) { ret = -ENOMEM; goto outfree_link_name; } } else { w_param_text[count] = devm_kmemdup(card->dev, config->stream_name, strlen(config->stream_name) + 1, GFP_KERNEL); if (!w_param_text[count]) { ret = -ENOMEM; goto outfree_link_name; } } if (!w_param_text[count]) goto outfree_w_param; config++; } w_param_enum[0].items = num_params; w_param_enum[0].texts = w_param_text; memset(&template, 0, sizeof(template)); template.reg = SND_SOC_NOPM; template.id = snd_soc_dapm_dai_link; template.name = link_name; template.event = snd_soc_dai_link_event; template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD; template.num_kcontrols = 1; /* duplicate w_param_enum on heap so that memory persists */ private_value = *private_value = (unsigned long) devm_kmemdup(card->dev, (void *)(kcontrol_dai_link[0].private_value), sizeof(struct soc_enum), GFP_KERNEL); if (!private_value) { if (!*private_value) { dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", link_name); ret = -ENOMEM; goto outfree_link_name; goto outfree_w_param; } kcontrol_dai_link[0].private_value = private_value; kcontrol_dai_link[0].private_value = *private_value; /* duplicate kcontrol_dai_link on heap so that memory persists */ template.kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0], kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0], sizeof(struct snd_kcontrol_new), GFP_KERNEL); if (!template.kcontrol_news) { if (!kcontrol_news) { dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", link_name); goto outfree_w_param; } return kcontrol_news; outfree_w_param: snd_soc_dapm_free_kcontrol(card, private_value, num_params, w_param_text); return NULL; } int snd_soc_dapm_new_pcm(struct snd_soc_card *card, const struct snd_soc_pcm_stream *params, unsigned int num_params, struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget *w; const char **w_param_text; unsigned long private_value; char *link_name; int ret; link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s", source->name, sink->name); if (!link_name) return -ENOMEM; memset(&template, 0, sizeof(template)); template.reg = SND_SOC_NOPM; template.id = snd_soc_dapm_dai_link; template.name = link_name; template.event = snd_soc_dai_link_event; template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD; template.kcontrol_news = NULL; /* allocate memory for control, only in case of multiple configs */ if (num_params > 1) { w_param_text = devm_kcalloc(card->dev, num_params, sizeof(char *), GFP_KERNEL); if (!w_param_text) { ret = -ENOMEM; goto outfree_private_value; goto param_fail; } template.num_kcontrols = 1; template.kcontrol_news = snd_soc_dapm_alloc_kcontrol(card, link_name, params, num_params, w_param_text, &private_value); if (!template.kcontrol_news) { ret = -ENOMEM; goto param_fail; } } else { w_param_text = NULL; } dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template); Loading Loading @@ -3903,15 +3939,9 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, devm_kfree(card->dev, w); outfree_kcontrol_news: devm_kfree(card->dev, (void *)template.kcontrol_news); outfree_private_value: devm_kfree(card->dev, (void *)private_value); outfree_link_name: snd_soc_dapm_free_kcontrol(card, &private_value, num_params, w_param_text); param_fail: devm_kfree(card->dev, link_name); outfree_w_param: for (count = 0 ; count < num_params; count++) devm_kfree(card->dev, (void *)w_param_text[count]); devm_kfree(card->dev, w_param_text); return ret; } Loading