In order for topology to be resource managed, change all allocations to
be resource managed:
k*alloc -> devm_k*alloc
kstrdup -> devm_kstrdup
Exceptions where non resource managed allocation is left is
soc_tplg_dapm_widget_create(), as it uses pointer to memory locally and
frees it up after use, as well as soc_tplg_dapm_graph_elems_load(),
which has temporary pointer to table of routes.
After conversion all redundant calls in error and clean up paths were
removed.
Also removed some variables which become unneeded when there is no calls
using them.
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20201030145427.3497990-5-amadeuszx.slawinski@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
struct snd_soc_dobj *dobj, int pass)
{
struct snd_card *card = comp->card->snd_card;
struct snd_soc_dobj *dobj, int pass)
{
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)
return;
if (pass != SOC_TPLG_PASS_MIXER)
return;
if (dobj->ops && dobj->ops->control_unload)
dobj->ops->control_unload(comp, dobj);
if (dobj->ops && dobj->ops->control_unload)
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);
list_del(&dobj->list);
snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list);
}
/* remove an enum kcontrol */
}
/* remove an enum kcontrol */
soc_tplg_denum_remove_values(se);
soc_tplg_denum_remove_texts(se);
soc_tplg_denum_remove_values(se);
soc_tplg_denum_remove_texts(se);
}
/* remove a byte kcontrol */
}
/* remove a byte kcontrol */
struct snd_soc_dobj *dobj, int pass)
{
struct snd_card *card = comp->card->snd_card;
struct snd_soc_dobj *dobj, int pass)
{
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)
return;
if (pass != SOC_TPLG_PASS_MIXER)
return;
snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list);
snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list);
}
/* remove a route */
static void remove_route(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass)
{
}
/* remove a route */
static void remove_route(struct snd_soc_component *comp,
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)
return;
if (pass != SOC_TPLG_PASS_GRAPH)
return;
dobj->ops->dapm_route_unload(comp, dobj);
list_del(&dobj->list);
dobj->ops->dapm_route_unload(comp, dobj);
list_del(&dobj->list);
}
/* remove a widget and it's kcontrols - routes must be removed first */
}
/* remove a widget and it's kcontrols - routes must be removed first */
soc_tplg_denum_remove_values(se);
soc_tplg_denum_remove_texts(se);
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];
}
} 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);
snd_ctl_remove(card, kcontrol);
- kfree(w->kcontrol_news[i].name);
- kfree(w->kcontrol_news);
if (dai->driver == dai_drv)
dai->driver = NULL;
if (dai->driver == dai_drv)
dai->driver = NULL;
- kfree(dai_drv->playback.stream_name);
- kfree(dai_drv->capture.stream_name);
- kfree(dai_drv->name);
}
/* remove link configurations */
}
/* remove link configurations */
list_del(&dobj->list);
snd_soc_remove_pcm_runtime(comp->card,
snd_soc_get_pcm_runtime(comp->card, link));
list_del(&dobj->list);
snd_soc_remove_pcm_runtime(comp->card,
snd_soc_get_pcm_runtime(comp->card, link));
-
- kfree(link->name);
- kfree(link->stream_name);
- kfree(link->cpus->dai_name);
- kfree(link);
unsigned int item_len = 2 * sizeof(unsigned int);
unsigned int *p;
unsigned int item_len = 2 * sizeof(unsigned int);
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);
static inline void soc_tplg_free_tlv(struct soc_tplg *tplg,
struct snd_kcontrol_new *kc)
{
static inline void soc_tplg_free_tlv(struct soc_tplg *tplg,
struct snd_kcontrol_new *kc)
{
}
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,
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL;
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL;
- sbe = kzalloc(sizeof(*sbe), GFP_KERNEL);
+ sbe = devm_kzalloc(tplg->dev, sizeof(*sbe), GFP_KERNEL);
if (sbe == NULL)
return -ENOMEM;
if (sbe == NULL)
return -ENOMEM;
err = soc_tplg_kcontrol_bind_io(&be->hdr, &kc, tplg);
if (err) {
soc_control_err(tplg, &be->hdr, be->hdr.name);
err = soc_tplg_kcontrol_bind_io(&be->hdr, &kc, tplg);
if (err) {
soc_control_err(tplg, &be->hdr, be->hdr.name);
if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to init %s\n",
be->hdr.name);
if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to init %s\n",
be->hdr.name);
if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to add %s\n",
be->hdr.name);
if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to add %s\n",
be->hdr.name);
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL;
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL;
- sm = kzalloc(sizeof(*sm), GFP_KERNEL);
+ sm = devm_kzalloc(tplg->dev, sizeof(*sm), GFP_KERNEL);
if (sm == NULL)
return -ENOMEM;
tplg->pos += (sizeof(struct snd_soc_tplg_mixer_control) +
if (sm == NULL)
return -ENOMEM;
tplg->pos += (sizeof(struct snd_soc_tplg_mixer_control) +
err = soc_tplg_kcontrol_bind_io(&mc->hdr, &kc, tplg);
if (err) {
soc_control_err(tplg, &mc->hdr, mc->hdr.name);
err = soc_tplg_kcontrol_bind_io(&mc->hdr, &kc, tplg);
if (err) {
soc_control_err(tplg, &mc->hdr, mc->hdr.name);
if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to create TLV %s\n",
mc->hdr.name);
if (err < 0) {
dev_err(tplg->dev, "ASoC: failed to create TLV %s\n",
mc->hdr.name);
dev_err(tplg->dev, "ASoC: failed to init %s\n",
mc->hdr.name);
soc_tplg_free_tlv(tplg, &kc);
dev_err(tplg->dev, "ASoC: failed to init %s\n",
mc->hdr.name);
soc_tplg_free_tlv(tplg, &kc);
dev_err(tplg->dev, "ASoC: failed to add %s\n",
mc->hdr.name);
soc_tplg_free_tlv(tplg, &kc);
dev_err(tplg->dev, "ASoC: failed to add %s\n",
mc->hdr.name);
soc_tplg_free_tlv(tplg, &kc);
-static int soc_tplg_denum_create_texts(struct soc_enum *se,
- struct snd_soc_tplg_enum_control *ec)
+static int soc_tplg_denum_create_texts(struct soc_tplg *tplg, struct soc_enum *se,
+ struct snd_soc_tplg_enum_control *ec)
{
int i, ret;
se->dobj.control.dtexts =
{
int i, ret;
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)
return -ENOMEM;
if (se->dobj.control.dtexts == NULL)
return -ENOMEM;
- 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]) {
ret = -ENOMEM;
goto err;
if (!se->dobj.control.dtexts[i]) {
ret = -ENOMEM;
goto err;
static inline void soc_tplg_denum_remove_texts(struct soc_enum *se)
{
static inline void soc_tplg_denum_remove_texts(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)
+static int soc_tplg_denum_create_values(struct soc_tplg *tplg, struct soc_enum *se,
+ struct snd_soc_tplg_enum_control *ec)
{
int i;
if (le32_to_cpu(ec->items) > sizeof(*ec->values))
return -EINVAL;
{
int i;
if (le32_to_cpu(ec->items) > sizeof(*ec->values))
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),
GFP_KERNEL);
if (!se->dobj.control.dvalues)
sizeof(u32),
GFP_KERNEL);
if (!se->dobj.control.dvalues)
static inline void soc_tplg_denum_remove_values(struct soc_enum *se)
{
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,
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL;
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return -EINVAL;
- se = kzalloc((sizeof(*se)), GFP_KERNEL);
+ se = devm_kzalloc(tplg->dev, (sizeof(*se)), GFP_KERNEL);
if (se == NULL)
return -ENOMEM;
if (se == NULL)
return -ENOMEM;
switch (le32_to_cpu(ec->hdr.ops.info)) {
case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
case SND_SOC_TPLG_CTL_ENUM_VALUE:
switch (le32_to_cpu(ec->hdr.ops.info)) {
case SND_SOC_TPLG_DAPM_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) {
dev_err(tplg->dev,
"ASoC: could not create values for %s\n",
if (err < 0) {
dev_err(tplg->dev,
"ASoC: could not create values for %s\n",
case SND_SOC_TPLG_CTL_ENUM:
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
case SND_SOC_TPLG_CTL_ENUM:
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
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) {
dev_err(tplg->dev,
"ASoC: could not create texts for %s\n",
if (err < 0) {
dev_err(tplg->dev,
"ASoC: could not create texts for %s\n",
struct snd_soc_dapm_context *dapm = &tplg->comp->dapm;
struct snd_soc_tplg_dapm_graph_elem *elem;
struct snd_soc_dapm_route **routes;
struct snd_soc_dapm_context *dapm = &tplg->comp->dapm;
struct snd_soc_tplg_dapm_graph_elem *elem;
struct snd_soc_dapm_route **routes;
int ret = 0;
count = le32_to_cpu(hdr->count);
int ret = 0;
count = le32_to_cpu(hdr->count);
* each route can be freed when it is removed in remove_route().
*/
for (i = 0; i < count; i++) {
* each route can be freed when it is removed in remove_route().
*/
for (i = 0; i < count; i++) {
- routes[i] = kzalloc(sizeof(*routes[i]), GFP_KERNEL);
- if (!routes[i]) {
- /* free previously allocated memory */
- for (j = 0; j < i; j++)
- kfree(routes[j]);
-
- kfree(routes);
+ routes[i] = devm_kzalloc(tplg->dev, sizeof(*routes[i]), GFP_KERNEL);
+ if (!routes[i])
}
for (i = 0; i < count; i++) {
}
for (i = 0; i < count; i++) {
- * 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.
* The memory allocated for each dapm route will be freed
* when it is removed in remove_route().
* free pointer to array of dapm routes as this is no longer needed.
* The memory allocated for each dapm route will be freed
* when it is removed in remove_route().
struct snd_soc_tplg_mixer_control *mc;
int i, err;
struct snd_soc_tplg_mixer_control *mc;
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)
return NULL;
if (kc == NULL)
return NULL;
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_sm;
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_sm;
- sm = kzalloc(sizeof(*sm), GFP_KERNEL);
+ sm = devm_kzalloc(tplg->dev, sizeof(*sm), GFP_KERNEL);
if (sm == NULL)
goto err_sm;
if (sm == NULL)
goto err_sm;
mc->hdr.name, i);
kc[i].private_value = (long)sm;
mc->hdr.name, i);
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)
goto err_sm;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
if (kc[i].name == NULL)
goto err_sm;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
err_sm:
for (; i >= 0; i--) {
soc_tplg_free_tlv(tplg, &kc[i]);
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);
struct soc_enum *se;
int i, err;
struct soc_enum *se;
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)
return NULL;
if (kc == NULL)
return NULL;
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_se;
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_se;
- se = kzalloc(sizeof(*se), GFP_KERNEL);
+ se = devm_kzalloc(tplg->dev, sizeof(*se), GFP_KERNEL);
if (se == NULL)
goto err_se;
if (se == NULL)
goto err_se;
ec->hdr.name);
kc[i].private_value = (long)se;
ec->hdr.name);
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)
goto err_se;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
if (kc[i].name == NULL)
goto err_se;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
switch (le32_to_cpu(ec->hdr.ops.info)) {
case SND_SOC_TPLG_CTL_ENUM_VALUE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
switch (le32_to_cpu(ec->hdr.ops.info)) {
case SND_SOC_TPLG_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) {
dev_err(tplg->dev, "ASoC: could not create values for %s\n",
ec->hdr.name);
if (err < 0) {
dev_err(tplg->dev, "ASoC: could not create values for %s\n",
ec->hdr.name);
case SND_SOC_TPLG_CTL_ENUM:
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
case SND_SOC_TPLG_CTL_ENUM:
case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
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) {
dev_err(tplg->dev, "ASoC: could not create texts for %s\n",
ec->hdr.name);
if (err < 0) {
dev_err(tplg->dev, "ASoC: could not create texts for %s\n",
ec->hdr.name);
soc_tplg_denum_remove_texts(se);
}
soc_tplg_denum_remove_texts(se);
}
- kfree(se);
- kfree(kc[i].name);
struct snd_kcontrol_new *kc;
int i, err;
struct snd_kcontrol_new *kc;
int i, err;
- kc = kcalloc(num_kcontrols, sizeof(*kc), GFP_KERNEL);
+ kc = devm_kcalloc(tplg->dev, num_kcontrols, sizeof(*kc), GFP_KERNEL);
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_sbe;
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
goto err_sbe;
- sbe = kzalloc(sizeof(*sbe), GFP_KERNEL);
+ sbe = devm_kzalloc(tplg->dev, sizeof(*sbe), GFP_KERNEL);
if (sbe == NULL)
goto err_sbe;
if (sbe == NULL)
goto err_sbe;
be->hdr.name, be->hdr.access);
kc[i].private_value = (long)sbe;
be->hdr.name, be->hdr.access);
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)
goto err_sbe;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
if (kc[i].name == NULL)
goto err_sbe;
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- for (; i >= 0; i--) {
- sbe = (struct soc_bytes_ext *)kc[i].private_value;
- kfree(sbe);
- kfree(kc[i].name);
- }
- kfree(kc);
-static int set_stream_info(struct snd_soc_pcm_stream *stream,
- struct snd_soc_tplg_stream_caps *caps)
+static int set_stream_info(struct soc_tplg *tplg, struct snd_soc_pcm_stream *stream,
+ 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)
return -ENOMEM;
if (!stream->stream_name)
return -ENOMEM;
snd_soc_component_get_dapm(tplg->comp);
int ret;
snd_soc_component_get_dapm(tplg->comp);
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)
return -ENOMEM;
if (strlen(pcm->dai_name)) {
if (dai_drv == NULL)
return -ENOMEM;
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) {
ret = -ENOMEM;
goto err;
if (!dai_drv->name) {
ret = -ENOMEM;
goto err;
if (pcm->playback) {
stream = &dai_drv->playback;
caps = &pcm->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
if (pcm->playback) {
stream = &dai_drv->playback;
caps = &pcm->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
- ret = set_stream_info(stream, caps);
+ ret = set_stream_info(tplg, stream, caps);
if (pcm->capture) {
stream = &dai_drv->capture;
caps = &pcm->caps[SND_SOC_TPLG_STREAM_CAPTURE];
if (pcm->capture) {
stream = &dai_drv->capture;
caps = &pcm->caps[SND_SOC_TPLG_STREAM_CAPTURE];
- ret = set_stream_info(stream, caps);
+ ret = set_stream_info(tplg, stream, caps);
- kfree(dai_drv->playback.stream_name);
- kfree(dai_drv->capture.stream_name);
- kfree(dai_drv->name);
- kfree(dai_drv);
-
int ret;
/* link + cpu + codec + platform */
int ret;
/* 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)
return -ENOMEM;
if (link == NULL)
return -ENOMEM;
link->dobj.type = SND_SOC_DOBJ_DAI_LINK;
if (strlen(pcm->pcm_name)) {
link->dobj.type = SND_SOC_DOBJ_DAI_LINK;
if (strlen(pcm->pcm_name)) {
- link->name = kstrdup(pcm->pcm_name, GFP_KERNEL);
- link->stream_name = kstrdup(pcm->pcm_name, GFP_KERNEL);
+ link->name = devm_kstrdup(tplg->dev, pcm->pcm_name, GFP_KERNEL);
+ link->stream_name = devm_kstrdup(tplg->dev, pcm->pcm_name, GFP_KERNEL);
if (!link->name || !link->stream_name) {
ret = -ENOMEM;
goto err;
if (!link->name || !link->stream_name) {
ret = -ENOMEM;
goto err;
link->id = le32_to_cpu(pcm->pcm_id);
if (strlen(pcm->dai_name)) {
link->id = le32_to_cpu(pcm->pcm_id);
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) {
ret = -ENOMEM;
goto err;
if (!link->cpus->dai_name) {
ret = -ENOMEM;
goto err;
- kfree(link->name);
- kfree(link->stream_name);
- kfree(link->cpus->dai_name);
- kfree(link);
if (d->playback) {
stream = &dai_drv->playback;
caps = &d->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
if (d->playback) {
stream = &dai_drv->playback;
caps = &d->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
- ret = set_stream_info(stream, caps);
+ ret = set_stream_info(tplg, stream, caps);
if (d->capture) {
stream = &dai_drv->capture;
caps = &d->caps[SND_SOC_TPLG_STREAM_CAPTURE];
if (d->capture) {
stream = &dai_drv->capture;
caps = &d->caps[SND_SOC_TPLG_STREAM_CAPTURE];
- ret = set_stream_info(stream, caps);
+ ret = set_stream_info(tplg, stream, caps);
- kfree(dai_drv->playback.stream_name);
- kfree(dai_drv->capture.stream_name);