ASoC: topology: Fixes

Merge series from Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>:

Following series performs few cleanups in topology code.

First patch reduces number of prints we get from failure.
Second allos TLV controls to be either read or write which should be
possible as evidenced by further code in function.
Last one cleanups after refactoring of memory handling.

v2:
 - Add missing Fixes tag on second patch
 - Add Reviewed-by tag from Pierre

Amadeusz Sławiński (3):
  ASoC: topology: Remove superfluous error prints
  ASoC: topology: Allow TLV control to be either read or write
  ASoC: topology: Optimize soc_tplg_dapm_graph_elems_load behavior

 sound/soc/soc-topology.c | 103 ++++++++++-----------------------------
 1 file changed, 27 insertions(+), 76 deletions(-)

--
2.25.1
This commit is contained in:
Mark Brown 2022-01-25 02:36:20 +00:00
commit cef982dc48
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0

View file

@ -512,7 +512,8 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr,
if (le32_to_cpu(hdr->ops.info) == SND_SOC_TPLG_CTL_BYTES
&& k->iface & SNDRV_CTL_ELEM_IFACE_MIXER
&& k->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE
&& (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ
|| k->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
&& k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
struct soc_bytes_ext *sbe;
struct snd_soc_tplg_bytes_control *be;
@ -685,12 +686,9 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count,
int err = 0;
if (soc_tplg_check_elem_count(tplg,
sizeof(struct snd_soc_tplg_bytes_control), count,
size, "mixer bytes")) {
dev_err(tplg->dev, "ASoC: Invalid count %d for byte control\n",
count);
sizeof(struct snd_soc_tplg_bytes_control),
count, size, "mixer bytes"))
return -EINVAL;
}
for (i = 0; i < count; i++) {
be = (struct snd_soc_tplg_bytes_control *)tplg->pos;
@ -763,13 +761,9 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
int err = 0;
if (soc_tplg_check_elem_count(tplg,
sizeof(struct snd_soc_tplg_mixer_control),
count, size, "mixers")) {
dev_err(tplg->dev, "ASoC: invalid count %d for controls\n",
count);
sizeof(struct snd_soc_tplg_mixer_control),
count, size, "mixers"))
return -EINVAL;
}
for (i = 0; i < count; i++) {
mc = (struct snd_soc_tplg_mixer_control *)tplg->pos;
@ -927,13 +921,9 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count,
int err = 0;
if (soc_tplg_check_elem_count(tplg,
sizeof(struct snd_soc_tplg_enum_control),
count, size, "enums")) {
dev_err(tplg->dev, "ASoC: invalid count %d for enum controls\n",
count);
sizeof(struct snd_soc_tplg_enum_control),
count, size, "enums"))
return -EINVAL;
}
for (i = 0; i < count; i++) {
ec = (struct snd_soc_tplg_enum_control *)tplg->pos;
@ -1104,42 +1094,24 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
{
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_route *route;
int count, i;
int ret = 0;
count = le32_to_cpu(hdr->count);
if (soc_tplg_check_elem_count(tplg,
sizeof(struct snd_soc_tplg_dapm_graph_elem),
count, le32_to_cpu(hdr->payload_size), "graph")) {
dev_err(tplg->dev, "ASoC: invalid count %d for DAPM routes\n",
count);
sizeof(struct snd_soc_tplg_dapm_graph_elem),
count, le32_to_cpu(hdr->payload_size), "graph"))
return -EINVAL;
}
dev_dbg(tplg->dev, "ASoC: adding %d DAPM routes for index %d\n", count,
hdr->index);
/* allocate memory for pointer to array of dapm routes */
routes = kcalloc(count, sizeof(struct snd_soc_dapm_route *),
GFP_KERNEL);
if (!routes)
return -ENOMEM;
/*
* allocate memory for each dapm route in the array.
* This needs to be done individually so that
* each route can be freed when it is removed in remove_route().
*/
for (i = 0; i < count; i++) {
routes[i] = devm_kzalloc(tplg->dev, sizeof(*routes[i]), GFP_KERNEL);
if (!routes[i])
route = devm_kzalloc(tplg->dev, sizeof(*route), GFP_KERNEL);
if (!route)
return -ENOMEM;
}
for (i = 0; i < count; i++) {
elem = (struct snd_soc_tplg_dapm_graph_elem *)tplg->pos;
tplg->pos += sizeof(struct snd_soc_tplg_dapm_graph_elem);
@ -1160,46 +1132,32 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
break;
}
routes[i]->source = elem->source;
routes[i]->sink = elem->sink;
route->source = elem->source;
route->sink = elem->sink;
/* set to NULL atm for tplg users */
routes[i]->connected = NULL;
route->connected = NULL;
if (strnlen(elem->control, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 0)
routes[i]->control = NULL;
route->control = NULL;
else
routes[i]->control = elem->control;
route->control = elem->control;
/* add route dobj to dobj_list */
routes[i]->dobj.type = SND_SOC_DOBJ_GRAPH;
routes[i]->dobj.ops = tplg->ops;
routes[i]->dobj.index = tplg->index;
list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list);
route->dobj.type = SND_SOC_DOBJ_GRAPH;
route->dobj.ops = tplg->ops;
route->dobj.index = tplg->index;
list_add(&route->dobj.list, &tplg->comp->dobj_list);
ret = soc_tplg_add_route(tplg, routes[i]);
ret = soc_tplg_add_route(tplg, route);
if (ret < 0) {
dev_err(tplg->dev, "ASoC: topology: add_route failed: %d\n", ret);
/*
* this route was added to the list, it will
* be freed in remove_route() so increment the
* counter to skip it in the error handling
* below.
*/
i++;
break;
}
/* add route, but keep going if some fail */
snd_soc_dapm_add_routes(dapm, routes[i], 1);
snd_soc_dapm_add_routes(dapm, route, 1);
}
/*
* 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().
*/
kfree(routes);
return ret;
}
@ -1965,11 +1923,8 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
if (soc_tplg_check_elem_count(tplg,
size, count,
le32_to_cpu(hdr->payload_size),
"PCM DAI")) {
dev_err(tplg->dev, "ASoC: invalid count %d for PCM DAI elems\n",
count);
"PCM DAI"))
return -EINVAL;
}
for (i = 0; i < count; i++) {
pcm = (struct snd_soc_tplg_pcm *)tplg->pos;
@ -2243,14 +2198,10 @@ static int soc_tplg_link_elems_load(struct soc_tplg *tplg,
return -EINVAL;
}
if (soc_tplg_check_elem_count(tplg,
size, count,
if (soc_tplg_check_elem_count(tplg, size, count,
le32_to_cpu(hdr->payload_size),
"physical link config")) {
dev_err(tplg->dev, "ASoC: invalid count %d for physical link elems\n",
count);
"physical link config"))
return -EINVAL;
}
/* config physical DAI links */
for (i = 0; i < count; i++) {