Commit bc3955c9 authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: topology: Change to resource managed memory" from Amadeusz...

Merge series "ASoC: topology: Change to resource managed memory" from Amadeusz Sławiński<amadeuszx.slawinski@linux.intel.com>:

Almost all other allocations in ASoC API are resource managed, the only
exception is soc-topology.c.

This patchset clean ups few unnecessary functions in preparation for
change and then changes to devm_ functions for allocation.

Amadeusz Sławiński (6):
  ASoC: topology: Remove unused functions from topology API
  ASoC: topology: Remove multistep topology loading
  ASoC: topology: Unify all device references
  ASoC: topology: Change allocations to resource managed
  ASoC: topology: Remove empty functions
  ASoC: topology: Simplify remove_widget function

 include/sound/soc-topology.h           |  13 +-
 sound/soc/intel/skylake/skl-topology.c |   9 +-
 sound/soc/soc-topology.c               | 302 +++++--------------------
 sound/soc/sof/pcm.c                    |   2 +-
 sound/soc/sof/topology.c               |   4 +-
 5 files changed, 57 insertions(+), 273 deletions(-)

--
2.25.1
parents 860bfa6d 8d456654
...@@ -31,9 +31,6 @@ struct snd_soc_dai_driver; ...@@ -31,9 +31,6 @@ struct snd_soc_dai_driver;
struct snd_soc_dai; struct snd_soc_dai;
struct snd_soc_dapm_route; struct snd_soc_dapm_route;
/* object scan be loaded and unloaded in groups with identfying indexes */
#define SND_SOC_TPLG_INDEX_ALL 0 /* ID that matches all FW objects */
/* dynamic object type */ /* dynamic object type */
enum snd_soc_dobj_type { enum snd_soc_dobj_type {
SND_SOC_DOBJ_NONE = 0, /* object is not dynamic */ SND_SOC_DOBJ_NONE = 0, /* object is not dynamic */
...@@ -181,14 +178,8 @@ static inline const void *snd_soc_tplg_get_data(struct snd_soc_tplg_hdr *hdr) ...@@ -181,14 +178,8 @@ static inline const void *snd_soc_tplg_get_data(struct snd_soc_tplg_hdr *hdr)
/* Dynamic Object loading and removal for component drivers */ /* Dynamic Object loading and removal for component drivers */
int snd_soc_tplg_component_load(struct snd_soc_component *comp, int snd_soc_tplg_component_load(struct snd_soc_component *comp,
struct snd_soc_tplg_ops *ops, const struct firmware *fw, struct snd_soc_tplg_ops *ops, const struct firmware *fw);
u32 index); int snd_soc_tplg_component_remove(struct snd_soc_component *comp);
int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index);
/* Widget removal - widgets also removed wth component API */
void snd_soc_tplg_widget_remove(struct snd_soc_dapm_widget *w);
void snd_soc_tplg_widget_remove_all(struct snd_soc_dapm_context *dapm,
u32 index);
/* Binds event handlers to dynamic widgets */ /* Binds event handlers to dynamic widgets */
int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w, int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w,
......
...@@ -3742,12 +3742,7 @@ int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus) ...@@ -3742,12 +3742,7 @@ int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus)
} }
component_load: component_load:
ret = snd_soc_tplg_component_load(component, &skl_tplg_ops, fw);
/*
* The complete tplg for SKL is loaded as index 0, we don't use
* any other index
*/
ret = snd_soc_tplg_component_load(component, &skl_tplg_ops, fw, 0);
if (ret < 0) { if (ret < 0) {
dev_err(bus->dev, "tplg component load failed%d\n", ret); dev_err(bus->dev, "tplg component load failed%d\n", ret);
goto err; goto err;
...@@ -3777,5 +3772,5 @@ void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus) ...@@ -3777,5 +3772,5 @@ void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus)
list_del(&ppl->node); list_del(&ppl->node);
/* clean up topology */ /* clean up topology */
snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); snd_soc_tplg_component_remove(component);
} }
...@@ -64,7 +64,6 @@ struct soc_tplg { ...@@ -64,7 +64,6 @@ struct soc_tplg {
struct device *dev; struct device *dev;
struct snd_soc_component *comp; struct snd_soc_component *comp;
u32 index; /* current block index */ u32 index; /* current block index */
u32 req_index; /* required index, only loaded/free matching blocks */
/* vendor specific kcontrol operations */ /* vendor specific kcontrol operations */
const struct snd_soc_tplg_kcontrol_ops *io_ops; const struct snd_soc_tplg_kcontrol_ops *io_ops;
...@@ -80,8 +79,6 @@ struct soc_tplg { ...@@ -80,8 +79,6 @@ struct soc_tplg {
static int soc_tplg_process_headers(struct soc_tplg *tplg); static int soc_tplg_process_headers(struct soc_tplg *tplg);
static void soc_tplg_complete(struct soc_tplg *tplg); static void soc_tplg_complete(struct soc_tplg *tplg);
static void soc_tplg_denum_remove_texts(struct soc_enum *se);
static void soc_tplg_denum_remove_values(struct soc_enum *se);
/* check we dont overflow the data for this control chunk */ /* check we dont overflow the data for this control chunk */
static int soc_tplg_check_elem_count(struct soc_tplg *tplg, size_t elem_size, static int soc_tplg_check_elem_count(struct soc_tplg *tplg, size_t elem_size,
...@@ -360,9 +357,6 @@ static void remove_mixer(struct snd_soc_component *comp, ...@@ -360,9 +357,6 @@ static void remove_mixer(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass) struct snd_soc_dobj *dobj, int pass)
{ {
struct snd_card *card = comp->card->snd_card; struct snd_card *card = comp->card->snd_card;
struct soc_mixer_control *sm =
container_of(dobj, struct soc_mixer_control, dobj);
const unsigned int *p = NULL;
if (pass != SOC_TPLG_PASS_MIXER) if (pass != SOC_TPLG_PASS_MIXER)
return; return;
...@@ -370,12 +364,8 @@ static void remove_mixer(struct snd_soc_component *comp, ...@@ -370,12 +364,8 @@ static void remove_mixer(struct snd_soc_component *comp,
if (dobj->ops && dobj->ops->control_unload) if (dobj->ops && dobj->ops->control_unload)
dobj->ops->control_unload(comp, dobj); dobj->ops->control_unload(comp, dobj);
if (dobj->control.kcontrol->tlv.p)
p = dobj->control.kcontrol->tlv.p;
snd_ctl_remove(card, dobj->control.kcontrol); snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list); list_del(&dobj->list);
kfree(sm);
kfree(p);
} }
/* remove an enum kcontrol */ /* remove an enum kcontrol */
...@@ -383,7 +373,6 @@ static void remove_enum(struct snd_soc_component *comp, ...@@ -383,7 +373,6 @@ static void remove_enum(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass) struct snd_soc_dobj *dobj, int pass)
{ {
struct snd_card *card = comp->card->snd_card; struct snd_card *card = comp->card->snd_card;
struct soc_enum *se = container_of(dobj, struct soc_enum, dobj);
if (pass != SOC_TPLG_PASS_MIXER) if (pass != SOC_TPLG_PASS_MIXER)
return; return;
...@@ -393,10 +382,6 @@ static void remove_enum(struct snd_soc_component *comp, ...@@ -393,10 +382,6 @@ static void remove_enum(struct snd_soc_component *comp,
snd_ctl_remove(card, dobj->control.kcontrol); snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list); list_del(&dobj->list);
soc_tplg_denum_remove_values(se);
soc_tplg_denum_remove_texts(se);
kfree(se);
} }
/* remove a byte kcontrol */ /* remove a byte kcontrol */
...@@ -404,8 +389,6 @@ static void remove_bytes(struct snd_soc_component *comp, ...@@ -404,8 +389,6 @@ static void remove_bytes(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass) struct snd_soc_dobj *dobj, int pass)
{ {
struct snd_card *card = comp->card->snd_card; struct snd_card *card = comp->card->snd_card;
struct soc_bytes_ext *sb =
container_of(dobj, struct soc_bytes_ext, dobj);
if (pass != SOC_TPLG_PASS_MIXER) if (pass != SOC_TPLG_PASS_MIXER)
return; return;
...@@ -415,16 +398,12 @@ static void remove_bytes(struct snd_soc_component *comp, ...@@ -415,16 +398,12 @@ static void remove_bytes(struct snd_soc_component *comp,
snd_ctl_remove(card, dobj->control.kcontrol); snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list); list_del(&dobj->list);
kfree(sb);
} }
/* remove a route */ /* remove a route */
static void remove_route(struct snd_soc_component *comp, static void remove_route(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass) struct snd_soc_dobj *dobj, int pass)
{ {
struct snd_soc_dapm_route *route =
container_of(dobj, struct snd_soc_dapm_route, dobj);
if (pass != SOC_TPLG_PASS_GRAPH) if (pass != SOC_TPLG_PASS_GRAPH)
return; return;
...@@ -432,7 +411,6 @@ static void remove_route(struct snd_soc_component *comp, ...@@ -432,7 +411,6 @@ static void remove_route(struct snd_soc_component *comp,
dobj->ops->dapm_route_unload(comp, dobj); dobj->ops->dapm_route_unload(comp, dobj);
list_del(&dobj->list); list_del(&dobj->list);
kfree(route);
} }
/* remove a widget and it's kcontrols - routes must be removed first */ /* remove a widget and it's kcontrols - routes must be removed first */
...@@ -453,47 +431,10 @@ static void remove_widget(struct snd_soc_component *comp, ...@@ -453,47 +431,10 @@ static void remove_widget(struct snd_soc_component *comp,
if (!w->kcontrols) if (!w->kcontrols)
goto free_news; goto free_news;
/* for (i = 0; w->kcontrols && i < w->num_kcontrols; i++)
* Dynamic Widgets either have 1..N enum kcontrols or mixers. snd_ctl_remove(card, w->kcontrols[i]);
* The enum may either have an array of values or strings.
*/
if (dobj->widget.kcontrol_type == SND_SOC_TPLG_TYPE_ENUM) {
/* enumerated widget mixer */
for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) {
struct snd_kcontrol *kcontrol = w->kcontrols[i];
struct soc_enum *se =
(struct soc_enum *)kcontrol->private_value;
snd_ctl_remove(card, kcontrol);
/* free enum kcontrol's dvalues and dtexts */
soc_tplg_denum_remove_values(se);
soc_tplg_denum_remove_texts(se);
kfree(se);
kfree(w->kcontrol_news[i].name);
}
} else {
/* volume mixer or bytes controls */
for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) {
struct snd_kcontrol *kcontrol = w->kcontrols[i];
if (dobj->widget.kcontrol_type
== SND_SOC_TPLG_TYPE_MIXER)
kfree(kcontrol->tlv.p);
/* Private value is used as struct soc_mixer_control
* for volume mixers or soc_bytes_ext for bytes
* controls.
*/
kfree((void *)kcontrol->private_value);
snd_ctl_remove(card, kcontrol);
kfree(w->kcontrol_news[i].name);
}
}
free_news: free_news:
kfree(w->kcontrol_news);
list_del(&dobj->list); list_del(&dobj->list);
...@@ -518,11 +459,7 @@ static void remove_dai(struct snd_soc_component *comp, ...@@ -518,11 +459,7 @@ static void remove_dai(struct snd_soc_component *comp,
if (dai->driver == dai_drv) if (dai->driver == dai_drv)
dai->driver = NULL; dai->driver = NULL;
kfree(dai_drv->playback.stream_name);
kfree(dai_drv->capture.stream_name);
kfree(dai_drv->name);
list_del(&dobj->list); list_del(&dobj->list);
kfree(dai_drv);
} }
/* remove link configurations */ /* remove link configurations */
...@@ -541,11 +478,6 @@ static void remove_link(struct snd_soc_component *comp, ...@@ -541,11 +478,6 @@ static void remove_link(struct snd_soc_component *comp,
list_del(&dobj->list); list_del(&dobj->list);
snd_soc_remove_pcm_runtime(comp->card, snd_soc_remove_pcm_runtime(comp->card,
snd_soc_get_pcm_runtime(comp->card, link)); snd_soc_get_pcm_runtime(comp->card, link));
kfree(link->name);
kfree(link->stream_name);
kfree(link->cpus->dai_name);
kfree(link);
} }
/* unload dai link */ /* unload dai link */
...@@ -700,7 +632,7 @@ static int soc_tplg_create_tlv_db_scale(struct soc_tplg *tplg, ...@@ -700,7 +632,7 @@ static int soc_tplg_create_tlv_db_scale(struct soc_tplg *tplg,
unsigned int item_len = 2 * sizeof(unsigned int); unsigned int item_len = 2 * sizeof(unsigned int);
unsigned int *p; unsigned int *p;
p = kzalloc(item_len + 2 * sizeof(unsigned int), GFP_KERNEL); p = devm_kzalloc(tplg->dev, item_len + 2 * sizeof(unsigned int), GFP_KERNEL);
if (!p) if (!p)
return -ENOMEM; return -ENOMEM;
...@@ -741,12 +673,6 @@ static int soc_tplg_create_tlv(struct soc_tplg *tplg, ...@@ -741,12 +673,6 @@ static int soc_tplg_create_tlv(struct soc_tplg *tplg,
return 0; return 0;
} }
static inline void soc_tplg_free_tlv(struct soc_tplg *tplg,
struct snd_kcontrol_new *kc)
{
kfree(kc->tlv.p);
}
static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count, static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count,
size_t size) size_t size)
{ {
...@@ -772,7 +698,7 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count, ...@@ -772,7 +698,7 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count,
SNDRV_CTL_ELEM_ID_NAME_MAXLEN) SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL; return -EINVAL;
sbe = kzalloc(sizeof(*sbe), GFP_KERNEL); sbe = devm_kzalloc(tplg->dev, sizeof(*sbe), GFP_KERNEL);
if (sbe == NULL) if (sbe == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -798,7 +724,6 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count, ...@@ -798,7 +724,6 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count,
err = soc_tplg_kcontrol_bind_io(&be->hdr, &kc, tplg); err = soc_tplg_kcontrol_bind_io(&be->hdr, &kc, tplg);
if (err) { if (err) {
soc_control_err(tplg, &be->hdr, be->hdr.name); soc_control_err(tplg, &be->hdr, be->hdr.name);
kfree(sbe);
break; break;
} }
...@@ -808,7 +733,6 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count, ...@@ -808,7 +733,6 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count,
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to init %s\n", dev_err(tplg->dev, "ASoC: failed to init %s\n",
be->hdr.name); be->hdr.name);
kfree(sbe);
break; break;
} }
...@@ -818,7 +742,6 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count, ...@@ -818,7 +742,6 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count,
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to add %s\n", dev_err(tplg->dev, "ASoC: failed to add %s\n",
be->hdr.name); be->hdr.name);
kfree(sbe);
break; break;
} }
...@@ -854,7 +777,7 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, ...@@ -854,7 +777,7 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
SNDRV_CTL_ELEM_ID_NAME_MAXLEN) SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL; return -EINVAL;
sm = kzalloc(sizeof(*sm), GFP_KERNEL); sm = devm_kzalloc(tplg->dev, sizeof(*sm), GFP_KERNEL);
if (sm == NULL) if (sm == NULL)
return -ENOMEM; return -ENOMEM;
tplg->pos += (sizeof(struct snd_soc_tplg_mixer_control) + tplg->pos += (sizeof(struct snd_soc_tplg_mixer_control) +
...@@ -893,7 +816,6 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, ...@@ -893,7 +816,6 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
err = soc_tplg_kcontrol_bind_io(&mc->hdr, &kc, tplg); err = soc_tplg_kcontrol_bind_io(&mc->hdr, &kc, tplg);
if (err) { if (err) {
soc_control_err(tplg, &mc->hdr, mc->hdr.name); soc_control_err(tplg, &mc->hdr, mc->hdr.name);
kfree(sm);
break; break;
} }
...@@ -902,7 +824,6 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, ...@@ -902,7 +824,6 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to create TLV %s\n", dev_err(tplg->dev, "ASoC: failed to create TLV %s\n",
mc->hdr.name); mc->hdr.name);
kfree(sm);
break; break;
} }
...@@ -912,8 +833,6 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, ...@@ -912,8 +833,6 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to init %s\n", dev_err(tplg->dev, "ASoC: failed to init %s\n",
mc->hdr.name); mc->hdr.name);
soc_tplg_free_tlv(tplg, &kc);
kfree(sm);
break; break;
} }
...@@ -923,8 +842,6 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, ...@@ -923,8 +842,6 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to add %s\n", dev_err(tplg->dev, "ASoC: failed to add %s\n",
mc->hdr.name); mc->hdr.name);
soc_tplg_free_tlv(tplg, &kc);
kfree(sm);
break; break;
} }
...@@ -934,13 +851,13 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, ...@@ -934,13 +851,13 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
return err; return err;
} }
static int soc_tplg_denum_create_texts(struct soc_enum *se, static int soc_tplg_denum_create_texts(struct soc_tplg *tplg, struct soc_enum *se,
struct snd_soc_tplg_enum_control *ec) struct snd_soc_tplg_enum_control *ec)
{ {
int i, ret; int i, ret;
se->dobj.control.dtexts = se->dobj.control.dtexts =
kcalloc(le32_to_cpu(ec->items), sizeof(char *), GFP_KERNEL); devm_kcalloc(tplg->dev, le32_to_cpu(ec->items), sizeof(char *), GFP_KERNEL);
if (se->dobj.control.dtexts == NULL) if (se->dobj.control.dtexts == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -952,7 +869,7 @@ static int soc_tplg_denum_create_texts(struct soc_enum *se, ...@@ -952,7 +869,7 @@ static int soc_tplg_denum_create_texts(struct soc_enum *se,
goto err; goto err;
} }
se->dobj.control.dtexts[i] = kstrdup(ec->texts[i], GFP_KERNEL); se->dobj.control.dtexts[i] = devm_kstrdup(tplg->dev, ec->texts[i], GFP_KERNEL);
if (!se->dobj.control.dtexts[i]) { if (!se->dobj.control.dtexts[i]) {
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err;
...@@ -964,21 +881,10 @@ static int soc_tplg_denum_create_texts(struct soc_enum *se, ...@@ -964,21 +881,10 @@ static int soc_tplg_denum_create_texts(struct soc_enum *se,
return 0; return 0;
err: err:
se->items = i;
soc_tplg_denum_remove_texts(se);
return ret; return ret;
} }
static inline void soc_tplg_denum_remove_texts(struct soc_enum *se) static int soc_tplg_denum_create_values(struct soc_tplg *tplg, struct soc_enum *se,
{
int i = se->items;
for (--i; i >= 0; i--)
kfree(se->dobj.control.dtexts[i]);
kfree(se->dobj.control.dtexts);
}
static int soc_tplg_denum_create_values(struct soc_enum *se,
struct snd_soc_tplg_enum_control *ec) struct snd_soc_tplg_enum_control *ec)
{ {
int i; int i;
...@@ -986,7 +892,7 @@ static int soc_tplg_denum_create_values(struct soc_enum *se, ...@@ -986,7 +892,7 @@ static int soc_tplg_denum_create_values(struct soc_enum *se,
if (le32_to_cpu(ec->items) > sizeof(*ec->values)) if (le32_to_cpu(ec->items) > sizeof(*ec->values))
return -EINVAL; return -EINVAL;
se->dobj.control.dvalues = kzalloc(le32_to_cpu(ec->items) * se->dobj.control.dvalues = devm_kzalloc(tplg->dev, le32_to_cpu(ec->items) *
sizeof(u32), sizeof(u32),
GFP_KERNEL); GFP_KERNEL);
if (!se->dobj.control.dvalues) if (!se->dobj.control.dvalues)
...@@ -1000,11 +906,6 @@ static int soc_tplg_denum_create_values(struct soc_enum *se, ...@@ -1000,11 +906,6 @@ static int soc_tplg_denum_create_values(struct soc_enum *se,
return 0; return 0;
} }
static inline void soc_tplg_denum_remove_values(struct soc_enum *se)
{
kfree(se->dobj.control.dvalues);
}
static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count, static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count,
size_t size) size_t size)
{ {
...@@ -1031,7 +932,7 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count, ...@@ -1031,7 +932,7 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count,
SNDRV_CTL_ELEM_ID_NAME_MAXLEN) SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL; return -EINVAL;
se = kzalloc((sizeof(*se)), GFP_KERNEL); se = devm_kzalloc(tplg->dev, (sizeof(*se)), GFP_KERNEL);
if (se == NULL) if (se == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -1062,7 +963,7 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count, ...@@ -1062,7 +963,7 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count,
switch (le32_to_cpu(ec->hdr.ops.info)) { switch (le32_to_cpu(ec->hdr.ops.info)) {
case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
case SND_SOC_TPLG_CTL_ENUM_VALUE: case SND_SOC_TPLG_CTL_ENUM_VALUE:
err = soc_tplg_denum_create_values(se, ec); err = soc_tplg_denum_create_values(tplg, se, ec);
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, dev_err(tplg->dev,
"ASoC: could not create values for %s\n", "ASoC: could not create values for %s\n",
...@@ -1073,7 +974,7 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count, ...@@ -1073,7 +974,7 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count,
case SND_SOC_TPLG_CTL_ENUM: case SND_SOC_TPLG_CTL_ENUM:
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
err = soc_tplg_denum_create_texts(se, ec); err = soc_tplg_denum_create_texts(tplg, se, ec);
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, dev_err(tplg->dev,
"ASoC: could not create texts for %s\n", "ASoC: could not create texts for %s\n",
...@@ -1119,7 +1020,6 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count, ...@@ -1119,7 +1020,6 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count,
return 0; return 0;
err_denum: err_denum:
kfree(se);
return err; return err;
} }
...@@ -1196,7 +1096,7 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, ...@@ -1196,7 +1096,7 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
struct snd_soc_dapm_context *dapm = &tplg->comp->dapm; struct snd_soc_dapm_context *dapm = &tplg->comp->dapm;
struct snd_soc_tplg_dapm_graph_elem *elem; struct snd_soc_tplg_dapm_graph_elem *elem;
struct snd_soc_dapm_route **routes; struct snd_soc_dapm_route **routes;
int count, i, j; int count, i;
int ret = 0; int ret = 0;
count = le32_to_cpu(hdr->count); count = le32_to_cpu(hdr->count);
...@@ -1225,16 +1125,10 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, ...@@ -1225,16 +1125,10 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
* each route can be freed when it is removed in remove_route(). * each route can be freed when it is removed in remove_route().
*/ */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
routes[i] = kzalloc(sizeof(*routes[i]), GFP_KERNEL); routes[i] = devm_kzalloc(tplg->dev, sizeof(*routes[i]), GFP_KERNEL);
if (!routes[i]) { if (!routes[i])
/* free previously allocated memory */
for (j = 0; j < i; j++)
kfree(routes[j]);
kfree(routes);
return -ENOMEM; return -ENOMEM;
} }
}
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
elem = (struct snd_soc_tplg_dapm_graph_elem *)tplg->pos; elem = (struct snd_soc_tplg_dapm_graph_elem *)tplg->pos;
...@@ -1290,15 +1184,6 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, ...@@ -1290,15 +1184,6 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
snd_soc_dapm_add_routes(dapm, routes[i], 1); snd_soc_dapm_add_routes(dapm, routes[i], 1);
} }
/*
* free memory allocated for all dapm routes not added to the
* list in case of error
*/
if (ret < 0) {
while (i < count)
kfree(routes[i++]);
}
/* /*
* free pointer to array of dapm routes as this is no longer needed. * free pointer to array of dapm routes as this is no longer needed.
* The memory allocated for each dapm route will be freed * The memory allocated for each dapm route will be freed
...@@ -1317,7 +1202,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( ...@@ -1317,7 +1202,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
struct snd_soc_tplg_mixer_control *mc; struct snd_soc_tplg_mixer_control *mc;
int i, err; int i, err;
kc = kcalloc(num_kcontrols, sizeof(*kc), GFP_KERNEL); kc = devm_kcalloc(tplg->dev, num_kcontrols, sizeof(*kc), GFP_KERNEL);
if (kc == NULL) if (kc == NULL)
return NULL; return NULL;
...@@ -1329,7 +1214,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( ...@@ -1329,7 +1214,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
SNDRV_CTL_ELEM_ID_NAME_MAXLEN) SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_sm; goto err_sm;
sm = kzalloc(sizeof(*sm), GFP_KERNEL); sm = devm_kzalloc(tplg->dev, sizeof(*sm), GFP_KERNEL);
if (sm == NULL) if (sm == NULL)
goto err_sm; goto err_sm;
...@@ -1340,7 +1225,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( ...@@ -1340,7 +1225,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
mc->hdr.name, i); mc->hdr.name, i);
kc[i].private_value = (long)sm; kc[i].private_value = (long)sm;
kc[i].name = kstrdup(mc->hdr.name, GFP_KERNEL); kc[i].name = devm_kstrdup(tplg->dev, mc->hdr.name, GFP_KERNEL);
if (kc[i].name == NULL) if (kc[i].name == NULL)
goto err_sm; goto err_sm;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
...@@ -1390,14 +1275,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( ...@@ -1390,14 +1275,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
return kc; return kc;
err_sm: err_sm:
for (; i >= 0; i--) {
soc_tplg_free_tlv(tplg, &kc[i]);
sm = (struct soc_mixer_control *)kc[i].private_value;
kfree(sm);
kfree(kc[i].name);
}
kfree(kc);
return NULL; return NULL;
} }
...@@ -1409,7 +1286,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( ...@@ -1409,7 +1286,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
struct soc_enum *se; struct soc_enum *se;
int i, err; int i, err;
kc = kcalloc(num_kcontrols, sizeof(*kc), GFP_KERNEL); kc = devm_kcalloc(tplg->dev, num_kcontrols, sizeof(*kc), GFP_KERNEL);
if (kc == NULL) if (kc == NULL)
return NULL; return NULL;
...@@ -1420,7 +1297,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( ...@@ -1420,7 +1297,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
SNDRV_CTL_ELEM_ID_NAME_MAXLEN) SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_se; goto err_se;
se = kzalloc(sizeof(*se), GFP_KERNEL); se = devm_kzalloc(tplg->dev, sizeof(*se), GFP_KERNEL);
if (se == NULL) if (se == NULL)
goto err_se; goto err_se;
...@@ -1431,7 +1308,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( ...@@ -1431,7 +1308,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
ec->hdr.name); ec->hdr.name);
kc[i].private_value = (long)se; kc[i].private_value = (long)se;
kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL); kc[i].name = devm_kstrdup(tplg->dev, ec->hdr.name, GFP_KERNEL);
if (kc[i].name == NULL) if (kc[i].name == NULL)
goto err_se; goto err_se;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
...@@ -1451,7 +1328,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( ...@@ -1451,7 +1328,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
switch (le32_to_cpu(ec->hdr.ops.info)) { switch (le32_to_cpu(ec->hdr.ops.info)) {
case SND_SOC_TPLG_CTL_ENUM_VALUE: case SND_SOC_TPLG_CTL_ENUM_VALUE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
err = soc_tplg_denum_create_values(se, ec); err = soc_tplg_denum_create_values(tplg, se, ec);
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, "ASoC: could not create values for %s\n", dev_err(tplg->dev, "ASoC: could not create values for %s\n",
ec->hdr.name); ec->hdr.name);
...@@ -1461,7 +1338,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( ...@@ -1461,7 +1338,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
case SND_SOC_TPLG_CTL_ENUM: case SND_SOC_TPLG_CTL_ENUM:
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
err = soc_tplg_denum_create_texts(se, ec); err = soc_tplg_denum_create_texts(tplg, se, ec);
if (err < 0) { if (err < 0) {
dev_err(tplg->dev, "ASoC: could not create texts for %s\n", dev_err(tplg->dev, "ASoC: could not create texts for %s\n",
ec->hdr.name); ec->hdr.name);
...@@ -1494,20 +1371,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( ...@@ -1494,20 +1371,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
return kc; return kc;
err_se: err_se:
for (; i >= 0; i--) {
/* free values and texts */
se = (struct soc_enum *)kc[i].private_value;
if (se) {
soc_tplg_denum_remove_values(se);
soc_tplg_denum_remove_texts(se);
}
kfree(se);
kfree(kc[i].name);
}
kfree(kc);
return NULL; return NULL;
} }
...@@ -1519,7 +1382,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create( ...@@ -1519,7 +1382,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
struct snd_kcontrol_new *kc; struct snd_kcontrol_new *kc;
int i, err; int i, err;
kc = kcalloc(num_kcontrols, sizeof(*kc), GFP_KERNEL); kc = devm_kcalloc(tplg->dev, num_kcontrols, sizeof(*kc), GFP_KERNEL);
if (!kc) if (!kc)
return NULL; return NULL;
...@@ -1531,7 +1394,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create( ...@@ -1531,7 +1394,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
SNDRV_CTL_ELEM_ID_NAME_MAXLEN) SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_sbe; goto err_sbe;
sbe = kzalloc(sizeof(*sbe), GFP_KERNEL); sbe = devm_kzalloc(tplg->dev, sizeof(*sbe), GFP_KERNEL);
if (sbe == NULL) if (sbe == NULL)
goto err_sbe; goto err_sbe;
...@@ -1543,7 +1406,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create( ...@@ -1543,7 +1406,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
be->hdr.name, be->hdr.access); be->hdr.name, be->hdr.access);
kc[i].private_value = (long)sbe; kc[i].private_value = (long)sbe;
kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL); kc[i].name = devm_kstrdup(tplg->dev, be->hdr.name, GFP_KERNEL);
if (kc[i].name == NULL) if (kc[i].name == NULL)
goto err_sbe; goto err_sbe;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
...@@ -1572,12 +1435,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create( ...@@ -1572,12 +1435,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
return kc; return kc;
err_sbe: err_sbe:
for (; i >= 0; i--) {
sbe = (struct soc_bytes_ext *)kc[i].private_value;
kfree(sbe);
kfree(kc[i].name);
}
kfree(kc);
return NULL; return NULL;
} }
...@@ -1725,7 +1582,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1725,7 +1582,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
return 0; return 0;
ready_err: ready_err:
snd_soc_tplg_widget_remove(widget); remove_widget(widget->dapm->component, &widget->dobj, SOC_TPLG_PASS_WIDGET);
snd_soc_dapm_free_widget(widget); snd_soc_dapm_free_widget(widget);
hdr_err: hdr_err:
kfree(template.sname); kfree(template.sname);
...@@ -1784,10 +1641,10 @@ static int soc_tplg_dapm_complete(struct soc_tplg *tplg) ...@@ -1784,10 +1641,10 @@ static int soc_tplg_dapm_complete(struct soc_tplg *tplg)
return 0; return 0;
} }
static int set_stream_info(struct snd_soc_pcm_stream *stream, static int set_stream_info(struct soc_tplg *tplg, struct snd_soc_pcm_stream *stream,
struct snd_soc_tplg_stream_caps *caps) struct snd_soc_tplg_stream_caps *caps)
{ {
stream->stream_name = kstrdup(caps->name, GFP_KERNEL); stream->stream_name = devm_kstrdup(tplg->dev, caps->name, GFP_KERNEL);
if (!stream->stream_name) if (!stream->stream_name)
return -ENOMEM; return -ENOMEM;
...@@ -1831,12 +1688,12 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, ...@@ -1831,12 +1688,12 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
snd_soc_component_get_dapm(tplg->comp); snd_soc_component_get_dapm(tplg->comp);
int ret; int ret;
dai_drv = kzalloc(sizeof(struct snd_soc_dai_driver), GFP_KERNEL); dai_drv = devm_kzalloc(tplg->dev, sizeof(struct snd_soc_dai_driver), GFP_KERNEL);
if (dai_drv == NULL) if (dai_drv == NULL)
return -ENOMEM; return -ENOMEM;
if (strlen(pcm->dai_name)) { if (strlen(pcm->dai_name)) {
dai_drv->name = kstrdup(pcm->dai_name, GFP_KERNEL); dai_drv->name = devm_kstrdup(tplg->dev, pcm->dai_name, GFP_KERNEL);
if (!dai_drv->name) { if (!dai_drv->name) {
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err;
...@@ -1847,7 +1704,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, ...@@ -1847,7 +1704,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
if (pcm->playback) { if (pcm->playback) {
stream = &dai_drv->playback; stream = &dai_drv->playback;
caps = &pcm->caps[SND_SOC_TPLG_STREAM_PLAYBACK]; caps = &pcm->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
ret = set_stream_info(stream, caps); ret = set_stream_info(tplg, stream, caps);
if (ret < 0) if (ret < 0)
goto err; goto err;
} }
...@@ -1855,7 +1712,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, ...@@ -1855,7 +1712,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
if (pcm->capture) { if (pcm->capture) {
stream = &dai_drv->capture; stream = &dai_drv->capture;
caps = &pcm->caps[SND_SOC_TPLG_STREAM_CAPTURE]; caps = &pcm->caps[SND_SOC_TPLG_STREAM_CAPTURE];
ret = set_stream_info(stream, caps); ret = set_stream_info(tplg, stream, caps);
if (ret < 0) if (ret < 0)
goto err; goto err;
} }
...@@ -1866,7 +1723,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, ...@@ -1866,7 +1723,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
/* pass control to component driver for optional further init */ /* pass control to component driver for optional further init */
ret = soc_tplg_dai_load(tplg, dai_drv, pcm, NULL); ret = soc_tplg_dai_load(tplg, dai_drv, pcm, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n"); dev_err(tplg->dev, "ASoC: DAI loading failed\n");
goto err; goto err;
} }
...@@ -1876,7 +1733,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, ...@@ -1876,7 +1733,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
list_add(&dai_drv->dobj.list, &tplg->comp->dobj_list); list_add(&dai_drv->dobj.list, &tplg->comp->dobj_list);
/* register the DAI to the component */ /* register the DAI to the component */
dai = devm_snd_soc_register_dai(tplg->comp->dev, tplg->comp, dai_drv, false); dai = devm_snd_soc_register_dai(tplg->dev, tplg->comp, dai_drv, false);
if (!dai) if (!dai)
return -ENOMEM; return -ENOMEM;
...@@ -1890,11 +1747,6 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, ...@@ -1890,11 +1747,6 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
return 0; return 0;
err: err:
kfree(dai_drv->playback.stream_name);
kfree(dai_drv->capture.stream_name);
kfree(dai_drv->name);
kfree(dai_drv);
return ret; return ret;
} }
...@@ -1930,7 +1782,7 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg, ...@@ -1930,7 +1782,7 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
int ret; int ret;
/* link + cpu + codec + platform */ /* link + cpu + codec + platform */
link = kzalloc(sizeof(*link) + (3 * sizeof(*dlc)), GFP_KERNEL); link = devm_kzalloc(tplg->dev, sizeof(*link) + (3 * sizeof(*dlc)), GFP_KERNEL);
if (link == NULL) if (link == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -1949,8 +1801,8 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg, ...@@ -1949,8 +1801,8 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
link->dobj.type = SND_SOC_DOBJ_DAI_LINK; link->dobj.type = SND_SOC_DOBJ_DAI_LINK;
if (strlen(pcm->pcm_name)) { if (strlen(pcm->pcm_name)) {
link->name = kstrdup(pcm->pcm_name, GFP_KERNEL); link->name = devm_kstrdup(tplg->dev, pcm->pcm_name, GFP_KERNEL);
link->stream_name = kstrdup(pcm->pcm_name, GFP_KERNEL); link->stream_name = devm_kstrdup(tplg->dev, pcm->pcm_name, GFP_KERNEL);
if (!link->name || !link->stream_name) { if (!link->name || !link->stream_name) {
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err;
...@@ -1959,7 +1811,7 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg, ...@@ -1959,7 +1811,7 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
link->id = le32_to_cpu(pcm->pcm_id); link->id = le32_to_cpu(pcm->pcm_id);
if (strlen(pcm->dai_name)) { if (strlen(pcm->dai_name)) {
link->cpus->dai_name = kstrdup(pcm->dai_name, GFP_KERNEL); link->cpus->dai_name = devm_kstrdup(tplg->dev, pcm->dai_name, GFP_KERNEL);
if (!link->cpus->dai_name) { if (!link->cpus->dai_name) {
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err;
...@@ -1983,13 +1835,13 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg, ...@@ -1983,13 +1835,13 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
/* pass control to component driver for optional further init */ /* pass control to component driver for optional further init */
ret = soc_tplg_dai_link_load(tplg, link, NULL); ret = soc_tplg_dai_link_load(tplg, link, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->comp->dev, "ASoC: FE link loading failed\n"); dev_err(tplg->dev, "ASoC: FE link loading failed\n");
goto err; goto err;
} }
ret = snd_soc_add_pcm_runtime(tplg->comp->card, link); ret = snd_soc_add_pcm_runtime(tplg->comp->card, link);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->comp->dev, "ASoC: adding FE link failed\n"); dev_err(tplg->dev, "ASoC: adding FE link failed\n");
goto err; goto err;
} }
...@@ -1997,10 +1849,6 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg, ...@@ -1997,10 +1849,6 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
return 0; return 0;
err: err:
kfree(link->name);
kfree(link->stream_name);
kfree(link->cpus->dai_name);
kfree(link);
return ret; return ret;
} }
...@@ -2473,7 +2321,7 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg, ...@@ -2473,7 +2321,7 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
if (d->playback) { if (d->playback) {
stream = &dai_drv->playback; stream = &dai_drv->playback;
caps = &d->caps[SND_SOC_TPLG_STREAM_PLAYBACK]; caps = &d->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
ret = set_stream_info(stream, caps); ret = set_stream_info(tplg, stream, caps);
if (ret < 0) if (ret < 0)
goto err; goto err;
} }
...@@ -2481,7 +2329,7 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg, ...@@ -2481,7 +2329,7 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
if (d->capture) { if (d->capture) {
stream = &dai_drv->capture; stream = &dai_drv->capture;
caps = &d->caps[SND_SOC_TPLG_STREAM_CAPTURE]; caps = &d->caps[SND_SOC_TPLG_STREAM_CAPTURE];
ret = set_stream_info(stream, caps); ret = set_stream_info(tplg, stream, caps);
if (ret < 0) if (ret < 0)
goto err; goto err;
} }
...@@ -2494,15 +2342,13 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg, ...@@ -2494,15 +2342,13 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
/* pass control to component driver for optional further init */ /* pass control to component driver for optional further init */
ret = soc_tplg_dai_load(tplg, dai_drv, NULL, dai); ret = soc_tplg_dai_load(tplg, dai_drv, NULL, dai);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n"); dev_err(tplg->dev, "ASoC: DAI loading failed\n");
goto err; goto err;
} }
return 0; return 0;
err: err:
kfree(dai_drv->playback.stream_name);
kfree(dai_drv->capture.stream_name);
return ret; return ret;
} }
...@@ -2680,11 +2526,6 @@ static int soc_tplg_load_header(struct soc_tplg *tplg, ...@@ -2680,11 +2526,6 @@ static int soc_tplg_load_header(struct soc_tplg *tplg,
tplg->pos = tplg->hdr_pos + sizeof(struct snd_soc_tplg_hdr); tplg->pos = tplg->hdr_pos + sizeof(struct snd_soc_tplg_hdr);
/* check for matching ID */
if (le32_to_cpu(hdr->index) != tplg->req_index &&
tplg->req_index != SND_SOC_TPLG_INDEX_ALL)
return 0;
tplg->index = le32_to_cpu(hdr->index); tplg->index = le32_to_cpu(hdr->index);
switch (le32_to_cpu(hdr->type)) { switch (le32_to_cpu(hdr->type)) {
...@@ -2804,7 +2645,7 @@ static int soc_tplg_load(struct soc_tplg *tplg) ...@@ -2804,7 +2645,7 @@ static int soc_tplg_load(struct soc_tplg *tplg)
/* load audio component topology from "firmware" file */ /* load audio component topology from "firmware" file */
int snd_soc_tplg_component_load(struct snd_soc_component *comp, int snd_soc_tplg_component_load(struct snd_soc_component *comp,
struct snd_soc_tplg_ops *ops, const struct firmware *fw, u32 id) struct snd_soc_tplg_ops *ops, const struct firmware *fw)
{ {
struct soc_tplg tplg; struct soc_tplg tplg;
int ret; int ret;
...@@ -2819,7 +2660,6 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp, ...@@ -2819,7 +2660,6 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp,
tplg.dev = comp->dev; tplg.dev = comp->dev;
tplg.comp = comp; tplg.comp = comp;
tplg.ops = ops; tplg.ops = ops;
tplg.req_index = id;
tplg.io_ops = ops->io_ops; tplg.io_ops = ops->io_ops;
tplg.io_ops_count = ops->io_ops_count; tplg.io_ops_count = ops->io_ops_count;
tplg.bytes_ext_ops = ops->bytes_ext_ops; tplg.bytes_ext_ops = ops->bytes_ext_ops;
...@@ -2828,49 +2668,14 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp, ...@@ -2828,49 +2668,14 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp,
ret = soc_tplg_load(&tplg); ret = soc_tplg_load(&tplg);
/* free the created components if fail to load topology */ /* free the created components if fail to load topology */
if (ret) if (ret)
snd_soc_tplg_component_remove(comp, SND_SOC_TPLG_INDEX_ALL); snd_soc_tplg_component_remove(comp);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(snd_soc_tplg_component_load); EXPORT_SYMBOL_GPL(snd_soc_tplg_component_load);
/* remove this dynamic widget */
void snd_soc_tplg_widget_remove(struct snd_soc_dapm_widget *w)
{
/* make sure we are a widget */
if (w->dobj.type != SND_SOC_DOBJ_WIDGET)
return;
remove_widget(w->dapm->component, &w->dobj, SOC_TPLG_PASS_WIDGET);
}
EXPORT_SYMBOL_GPL(snd_soc_tplg_widget_remove);
/* remove all dynamic widgets from this DAPM context */
void snd_soc_tplg_widget_remove_all(struct snd_soc_dapm_context *dapm,
u32 index)
{
struct snd_soc_dapm_widget *w, *next_w;
for_each_card_widgets_safe(dapm->card, w, next_w) {
/* make sure we are a widget with correct context */
if (w->dobj.type != SND_SOC_DOBJ_WIDGET || w->dapm != dapm)
continue;
/* match ID */
if (w->dobj.index != index &&
w->dobj.index != SND_SOC_TPLG_INDEX_ALL)
continue;
/* check and free and dynamic widget kcontrols */
snd_soc_tplg_widget_remove(w);
snd_soc_dapm_free_widget(w);
}
snd_soc_dapm_reset_cache(dapm);
}
EXPORT_SYMBOL_GPL(snd_soc_tplg_widget_remove_all);
/* remove dynamic controls from the component driver */ /* remove dynamic controls from the component driver */
int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index) int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
{ {
struct snd_soc_dobj *dobj, *next_dobj; struct snd_soc_dobj *dobj, *next_dobj;
int pass = SOC_TPLG_PASS_END; int pass = SOC_TPLG_PASS_END;
...@@ -2882,11 +2687,6 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index) ...@@ -2882,11 +2687,6 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index)
list_for_each_entry_safe(dobj, next_dobj, &comp->dobj_list, list_for_each_entry_safe(dobj, next_dobj, &comp->dobj_list,
list) { list) {
/* match index */
if (dobj->index != index &&
index != SND_SOC_TPLG_INDEX_ALL)
continue;
switch (dobj->type) { switch (dobj->type) {
case SND_SOC_DOBJ_MIXER: case SND_SOC_DOBJ_MIXER:
remove_mixer(comp, dobj, pass); remove_mixer(comp, dobj, pass);
......
...@@ -780,7 +780,7 @@ static int sof_pcm_probe(struct snd_soc_component *component) ...@@ -780,7 +780,7 @@ static int sof_pcm_probe(struct snd_soc_component *component)
static void sof_pcm_remove(struct snd_soc_component *component) static void sof_pcm_remove(struct snd_soc_component *component)
{ {
/* remove topology */ /* remove topology */
snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); snd_soc_tplg_component_remove(component);
} }
void snd_sof_new_platform_drv(struct snd_sof_dev *sdev) void snd_sof_new_platform_drv(struct snd_sof_dev *sdev)
......
...@@ -3734,9 +3734,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) ...@@ -3734,9 +3734,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
return ret; return ret;
} }
ret = snd_soc_tplg_component_load(scomp, ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
&sof_tplg_ops, fw,
SND_SOC_TPLG_INDEX_ALL);
if (ret < 0) { if (ret < 0) {
dev_err(scomp->dev, "error: tplg component load failed %d\n", dev_err(scomp->dev, "error: tplg component load failed %d\n",
ret); ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment