Commit 67aa59af authored by Mark Brown's avatar Mark Brown

ASoC: topology: Fixes and cleanups

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

Following is series of fixes and cleanups for core topology code. Few
patches fixing various problems all around and few fixing function
names.
parents 7f27be23 31e92739
...@@ -62,7 +62,7 @@ struct snd_soc_dobj { ...@@ -62,7 +62,7 @@ struct snd_soc_dobj {
enum snd_soc_dobj_type type; enum snd_soc_dobj_type type;
unsigned int index; /* objects can belong in different groups */ unsigned int index; /* objects can belong in different groups */
struct list_head list; struct list_head list;
struct snd_soc_tplg_ops *ops; int (*unload)(struct snd_soc_component *comp, struct snd_soc_dobj *dobj);
union { union {
struct snd_soc_dobj_control control; struct snd_soc_dobj_control control;
struct snd_soc_dobj_widget widget; struct snd_soc_dobj_widget widget;
......
...@@ -44,9 +44,8 @@ ...@@ -44,9 +44,8 @@
#define SOC_TPLG_PASS_WIDGET 3 #define SOC_TPLG_PASS_WIDGET 3
#define SOC_TPLG_PASS_PCM_DAI 4 #define SOC_TPLG_PASS_PCM_DAI 4
#define SOC_TPLG_PASS_GRAPH 5 #define SOC_TPLG_PASS_GRAPH 5
#define SOC_TPLG_PASS_PINS 6 #define SOC_TPLG_PASS_BE_DAI 6
#define SOC_TPLG_PASS_BE_DAI 7 #define SOC_TPLG_PASS_LINK 7
#define SOC_TPLG_PASS_LINK 8
#define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST #define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST
#define SOC_TPLG_PASS_END SOC_TPLG_PASS_LINK #define SOC_TPLG_PASS_END SOC_TPLG_PASS_LINK
...@@ -77,9 +76,6 @@ struct soc_tplg { ...@@ -77,9 +76,6 @@ struct soc_tplg {
struct snd_soc_tplg_ops *ops; struct snd_soc_tplg_ops *ops;
}; };
static int soc_tplg_process_headers(struct soc_tplg *tplg);
static int soc_tplg_complete(struct soc_tplg *tplg);
/* 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,
unsigned int count, size_t bytes, const char *elem_type) unsigned int count, size_t bytes, const char *elem_type)
...@@ -186,7 +182,7 @@ static const struct soc_tplg_map dapm_map[] = { ...@@ -186,7 +182,7 @@ static const struct soc_tplg_map dapm_map[] = {
{SND_SOC_TPLG_DAPM_DECODER, snd_soc_dapm_decoder}, {SND_SOC_TPLG_DAPM_DECODER, snd_soc_dapm_decoder},
}; };
static int tplc_chan_get_reg(struct soc_tplg *tplg, static int tplg_chan_get_reg(struct soc_tplg *tplg,
struct snd_soc_tplg_channel *chan, int map) struct snd_soc_tplg_channel *chan, int map)
{ {
int i; int i;
...@@ -199,7 +195,7 @@ static int tplc_chan_get_reg(struct soc_tplg *tplg, ...@@ -199,7 +195,7 @@ static int tplc_chan_get_reg(struct soc_tplg *tplg,
return -EINVAL; return -EINVAL;
} }
static int tplc_chan_get_shift(struct soc_tplg *tplg, static int tplg_chan_get_shift(struct soc_tplg *tplg,
struct snd_soc_tplg_channel *chan, int map) struct snd_soc_tplg_channel *chan, int map)
{ {
int i; int i;
...@@ -354,69 +350,37 @@ static int soc_tplg_add_kcontrol(struct soc_tplg *tplg, ...@@ -354,69 +350,37 @@ static int soc_tplg_add_kcontrol(struct soc_tplg *tplg,
tplg->dev, k, comp->name_prefix, comp, kcontrol); tplg->dev, k, comp->name_prefix, comp, kcontrol);
} }
/* remove a mixer kcontrol */ /* remove kcontrol */
static void remove_mixer(struct snd_soc_component *comp, static void soc_tplg_remove_kcontrol(struct snd_soc_component *comp, struct snd_soc_dobj *dobj,
struct snd_soc_dobj *dobj, int pass) int pass)
{
struct snd_card *card = comp->card->snd_card;
if (pass != SOC_TPLG_PASS_CONTROL)
return;
if (dobj->ops && dobj->ops->control_unload)
dobj->ops->control_unload(comp, dobj);
snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list);
}
/* remove an enum kcontrol */
static void remove_enum(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass)
{
struct snd_card *card = comp->card->snd_card;
if (pass != SOC_TPLG_PASS_CONTROL)
return;
if (dobj->ops && dobj->ops->control_unload)
dobj->ops->control_unload(comp, dobj);
snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list);
}
/* remove a byte kcontrol */
static void remove_bytes(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass)
{ {
struct snd_card *card = comp->card->snd_card; struct snd_card *card = comp->card->snd_card;
if (pass != SOC_TPLG_PASS_CONTROL) if (pass != SOC_TPLG_PASS_CONTROL)
return; return;
if (dobj->ops && dobj->ops->control_unload) if (dobj->unload)
dobj->ops->control_unload(comp, dobj); dobj->unload(comp, dobj);
snd_ctl_remove(card, dobj->control.kcontrol); snd_ctl_remove(card, dobj->control.kcontrol);
list_del(&dobj->list); list_del(&dobj->list);
} }
/* remove a route */ /* remove a route */
static void remove_route(struct snd_soc_component *comp, static void soc_tplg_remove_route(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass) struct snd_soc_dobj *dobj, int pass)
{ {
if (pass != SOC_TPLG_PASS_GRAPH) if (pass != SOC_TPLG_PASS_GRAPH)
return; return;
if (dobj->ops && dobj->ops->dapm_route_unload) if (dobj->unload)
dobj->ops->dapm_route_unload(comp, dobj); dobj->unload(comp, dobj);
list_del(&dobj->list); 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 */
static void remove_widget(struct snd_soc_component *comp, static void soc_tplg_remove_widget(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;
...@@ -427,8 +391,8 @@ static void remove_widget(struct snd_soc_component *comp, ...@@ -427,8 +391,8 @@ static void remove_widget(struct snd_soc_component *comp,
if (pass != SOC_TPLG_PASS_WIDGET) if (pass != SOC_TPLG_PASS_WIDGET)
return; return;
if (dobj->ops && dobj->ops->widget_unload) if (dobj->unload)
dobj->ops->widget_unload(comp, dobj); dobj->unload(comp, dobj);
if (!w->kcontrols) if (!w->kcontrols)
goto free_news; goto free_news;
...@@ -444,7 +408,7 @@ static void remove_widget(struct snd_soc_component *comp, ...@@ -444,7 +408,7 @@ static void remove_widget(struct snd_soc_component *comp,
} }
/* remove DAI configurations */ /* remove DAI configurations */
static void remove_dai(struct snd_soc_component *comp, static void soc_tplg_remove_dai(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass) struct snd_soc_dobj *dobj, int pass)
{ {
struct snd_soc_dai_driver *dai_drv = struct snd_soc_dai_driver *dai_drv =
...@@ -454,8 +418,8 @@ static void remove_dai(struct snd_soc_component *comp, ...@@ -454,8 +418,8 @@ static void remove_dai(struct snd_soc_component *comp,
if (pass != SOC_TPLG_PASS_PCM_DAI) if (pass != SOC_TPLG_PASS_PCM_DAI)
return; return;
if (dobj->ops && dobj->ops->dai_unload) if (dobj->unload)
dobj->ops->dai_unload(comp, dobj); dobj->unload(comp, dobj);
for_each_component_dais_safe(comp, dai, _dai) for_each_component_dais_safe(comp, dai, _dai)
if (dai->driver == dai_drv) if (dai->driver == dai_drv)
...@@ -465,7 +429,7 @@ static void remove_dai(struct snd_soc_component *comp, ...@@ -465,7 +429,7 @@ static void remove_dai(struct snd_soc_component *comp,
} }
/* remove link configurations */ /* remove link configurations */
static void remove_link(struct snd_soc_component *comp, static void soc_tplg_remove_link(struct snd_soc_component *comp,
struct snd_soc_dobj *dobj, int pass) struct snd_soc_dobj *dobj, int pass)
{ {
struct snd_soc_dai_link *link = struct snd_soc_dai_link *link =
...@@ -474,8 +438,8 @@ static void remove_link(struct snd_soc_component *comp, ...@@ -474,8 +438,8 @@ static void remove_link(struct snd_soc_component *comp,
if (pass != SOC_TPLG_PASS_PCM_DAI) if (pass != SOC_TPLG_PASS_PCM_DAI)
return; return;
if (dobj->ops && dobj->ops->link_unload) if (dobj->unload)
dobj->ops->link_unload(comp, dobj); dobj->unload(comp, dobj);
list_del(&dobj->list); list_del(&dobj->list);
snd_soc_remove_pcm_runtime(comp->card, snd_soc_remove_pcm_runtime(comp->card,
...@@ -489,11 +453,11 @@ static void remove_backend_link(struct snd_soc_component *comp, ...@@ -489,11 +453,11 @@ static void remove_backend_link(struct snd_soc_component *comp,
if (pass != SOC_TPLG_PASS_LINK) if (pass != SOC_TPLG_PASS_LINK)
return; return;
if (dobj->ops && dobj->ops->link_unload) if (dobj->unload)
dobj->ops->link_unload(comp, dobj); dobj->unload(comp, dobj);
/* /*
* We don't free the link here as what remove_link() do since BE * We don't free the link here as what soc_tplg_remove_link() do since BE
* links are not allocated by topology. * links are not allocated by topology.
* We however need to reset the dobj type to its initial values * We however need to reset the dobj type to its initial values
*/ */
...@@ -714,7 +678,8 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, size_t size) ...@@ -714,7 +678,8 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, size_t size)
sbe->max = le32_to_cpu(be->max); sbe->max = le32_to_cpu(be->max);
sbe->dobj.type = SND_SOC_DOBJ_BYTES; sbe->dobj.type = SND_SOC_DOBJ_BYTES;
sbe->dobj.ops = tplg->ops; if (tplg->ops)
sbe->dobj.unload = tplg->ops->control_unload;
INIT_LIST_HEAD(&sbe->dobj.list); INIT_LIST_HEAD(&sbe->dobj.list);
/* map io handlers */ /* map io handlers */
...@@ -725,7 +690,7 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, size_t size) ...@@ -725,7 +690,7 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, size_t size)
} }
/* pass control to driver for optional further init */ /* pass control to driver for optional further init */
ret = soc_tplg_control_load(tplg, &kc, (struct snd_soc_tplg_ctl_hdr *)be); ret = soc_tplg_control_load(tplg, &kc, &be->hdr);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->dev, "ASoC: failed to init %s\n", be->hdr.name); dev_err(tplg->dev, "ASoC: failed to init %s\n", be->hdr.name);
goto err; goto err;
...@@ -780,18 +745,19 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, size_t size) ...@@ -780,18 +745,19 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, size_t size)
kc.access = le32_to_cpu(mc->hdr.access); kc.access = le32_to_cpu(mc->hdr.access);
/* we only support FL/FR channel mapping atm */ /* we only support FL/FR channel mapping atm */
sm->reg = tplc_chan_get_reg(tplg, mc->channel, SNDRV_CHMAP_FL); sm->reg = tplg_chan_get_reg(tplg, mc->channel, SNDRV_CHMAP_FL);
sm->rreg = tplc_chan_get_reg(tplg, mc->channel, SNDRV_CHMAP_FR); sm->rreg = tplg_chan_get_reg(tplg, mc->channel, SNDRV_CHMAP_FR);
sm->shift = tplc_chan_get_shift(tplg, mc->channel, SNDRV_CHMAP_FL); sm->shift = tplg_chan_get_shift(tplg, mc->channel, SNDRV_CHMAP_FL);
sm->rshift = tplc_chan_get_shift(tplg, mc->channel, SNDRV_CHMAP_FR); sm->rshift = tplg_chan_get_shift(tplg, mc->channel, SNDRV_CHMAP_FR);
sm->max = le32_to_cpu(mc->max); sm->max = le32_to_cpu(mc->max);
sm->min = le32_to_cpu(mc->min); sm->min = le32_to_cpu(mc->min);
sm->invert = le32_to_cpu(mc->invert); sm->invert = le32_to_cpu(mc->invert);
sm->platform_max = le32_to_cpu(mc->platform_max); sm->platform_max = le32_to_cpu(mc->platform_max);
sm->dobj.index = tplg->index; sm->dobj.index = tplg->index;
sm->dobj.ops = tplg->ops;
sm->dobj.type = SND_SOC_DOBJ_MIXER; sm->dobj.type = SND_SOC_DOBJ_MIXER;
if (tplg->ops)
sm->dobj.unload = tplg->ops->control_unload;
INIT_LIST_HEAD(&sm->dobj.list); INIT_LIST_HEAD(&sm->dobj.list);
/* map io handlers */ /* map io handlers */
...@@ -809,7 +775,7 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, size_t size) ...@@ -809,7 +775,7 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, size_t size)
} }
/* pass control to driver for optional further init */ /* pass control to driver for optional further init */
ret = soc_tplg_control_load(tplg, &kc, (struct snd_soc_tplg_ctl_hdr *)mc); ret = soc_tplg_control_load(tplg, &kc, &mc->hdr);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->dev, "ASoC: failed to init %s\n", mc->hdr.name); dev_err(tplg->dev, "ASoC: failed to init %s\n", mc->hdr.name);
goto err; goto err;
...@@ -927,16 +893,17 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, size_t size) ...@@ -927,16 +893,17 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, size_t size)
kc.iface = SNDRV_CTL_ELEM_IFACE_MIXER; kc.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
kc.access = le32_to_cpu(ec->hdr.access); kc.access = le32_to_cpu(ec->hdr.access);
se->reg = tplc_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL); se->reg = tplg_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL);
se->shift_l = tplc_chan_get_shift(tplg, ec->channel, se->shift_l = tplg_chan_get_shift(tplg, ec->channel,
SNDRV_CHMAP_FL); SNDRV_CHMAP_FL);
se->shift_r = tplc_chan_get_shift(tplg, ec->channel, se->shift_r = tplg_chan_get_shift(tplg, ec->channel,
SNDRV_CHMAP_FL); SNDRV_CHMAP_FL);
se->mask = le32_to_cpu(ec->mask); se->mask = le32_to_cpu(ec->mask);
se->dobj.index = tplg->index; se->dobj.index = tplg->index;
se->dobj.type = SND_SOC_DOBJ_ENUM; se->dobj.type = SND_SOC_DOBJ_ENUM;
se->dobj.ops = tplg->ops; if (tplg->ops)
se->dobj.unload = tplg->ops->control_unload;
INIT_LIST_HEAD(&se->dobj.list); INIT_LIST_HEAD(&se->dobj.list);
switch (le32_to_cpu(ec->hdr.ops.info)) { switch (le32_to_cpu(ec->hdr.ops.info)) {
...@@ -977,7 +944,7 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, size_t size) ...@@ -977,7 +944,7 @@ static int soc_tplg_denum_create(struct soc_tplg *tplg, size_t size)
} }
/* pass control to driver for optional further init */ /* pass control to driver for optional further init */
ret = soc_tplg_control_load(tplg, &kc, (struct snd_soc_tplg_ctl_hdr *)ec); ret = soc_tplg_control_load(tplg, &kc, &ec->hdr);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->dev, "ASoC: failed to init %s\n", ec->hdr.name); dev_err(tplg->dev, "ASoC: failed to init %s\n", ec->hdr.name);
goto err; goto err;
...@@ -1113,7 +1080,8 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, ...@@ -1113,7 +1080,8 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
/* add route dobj to dobj_list */ /* add route dobj to dobj_list */
route->dobj.type = SND_SOC_DOBJ_GRAPH; route->dobj.type = SND_SOC_DOBJ_GRAPH;
route->dobj.ops = tplg->ops; if (tplg->ops)
route->dobj.unload = tplg->ops->control_unload;
route->dobj.index = tplg->index; route->dobj.index = tplg->index;
list_add(&route->dobj.list, &tplg->comp->dobj_list); list_add(&route->dobj.list, &tplg->comp->dobj_list);
...@@ -1161,13 +1129,13 @@ static int soc_tplg_dapm_widget_dmixer_create(struct soc_tplg *tplg, struct snd_ ...@@ -1161,13 +1129,13 @@ static int soc_tplg_dapm_widget_dmixer_create(struct soc_tplg *tplg, struct snd_
kc->access = le32_to_cpu(mc->hdr.access); kc->access = le32_to_cpu(mc->hdr.access);
/* we only support FL/FR channel mapping atm */ /* we only support FL/FR channel mapping atm */
sm->reg = tplc_chan_get_reg(tplg, mc->channel, sm->reg = tplg_chan_get_reg(tplg, mc->channel,
SNDRV_CHMAP_FL); SNDRV_CHMAP_FL);
sm->rreg = tplc_chan_get_reg(tplg, mc->channel, sm->rreg = tplg_chan_get_reg(tplg, mc->channel,
SNDRV_CHMAP_FR); SNDRV_CHMAP_FR);
sm->shift = tplc_chan_get_shift(tplg, mc->channel, sm->shift = tplg_chan_get_shift(tplg, mc->channel,
SNDRV_CHMAP_FL); SNDRV_CHMAP_FL);
sm->rshift = tplc_chan_get_shift(tplg, mc->channel, sm->rshift = tplg_chan_get_shift(tplg, mc->channel,
SNDRV_CHMAP_FR); SNDRV_CHMAP_FR);
sm->max = le32_to_cpu(mc->max); sm->max = le32_to_cpu(mc->max);
...@@ -1193,7 +1161,7 @@ static int soc_tplg_dapm_widget_dmixer_create(struct soc_tplg *tplg, struct snd_ ...@@ -1193,7 +1161,7 @@ static int soc_tplg_dapm_widget_dmixer_create(struct soc_tplg *tplg, struct snd_
} }
/* pass control to driver for optional further init */ /* pass control to driver for optional further init */
err = soc_tplg_control_load(tplg, kc, (struct snd_soc_tplg_ctl_hdr *)mc); err = soc_tplg_control_load(tplg, kc, &mc->hdr);
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);
...@@ -1233,10 +1201,10 @@ static int soc_tplg_dapm_widget_denum_create(struct soc_tplg *tplg, struct snd_k ...@@ -1233,10 +1201,10 @@ static int soc_tplg_dapm_widget_denum_create(struct soc_tplg *tplg, struct snd_k
kc->access = le32_to_cpu(ec->hdr.access); kc->access = le32_to_cpu(ec->hdr.access);
/* we only support FL/FR channel mapping atm */ /* we only support FL/FR channel mapping atm */
se->reg = tplc_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL); se->reg = tplg_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL);
se->shift_l = tplc_chan_get_shift(tplg, ec->channel, se->shift_l = tplg_chan_get_shift(tplg, ec->channel,
SNDRV_CHMAP_FL); SNDRV_CHMAP_FL);
se->shift_r = tplc_chan_get_shift(tplg, ec->channel, se->shift_r = tplg_chan_get_shift(tplg, ec->channel,
SNDRV_CHMAP_FR); SNDRV_CHMAP_FR);
se->items = le32_to_cpu(ec->items); se->items = le32_to_cpu(ec->items);
...@@ -1277,7 +1245,7 @@ static int soc_tplg_dapm_widget_denum_create(struct soc_tplg *tplg, struct snd_k ...@@ -1277,7 +1245,7 @@ static int soc_tplg_dapm_widget_denum_create(struct soc_tplg *tplg, struct snd_k
} }
/* pass control to driver for optional further init */ /* pass control to driver for optional further init */
err = soc_tplg_control_load(tplg, kc, (struct snd_soc_tplg_ctl_hdr *)ec); err = soc_tplg_control_load(tplg, kc, &ec->hdr);
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",
ec->hdr.name); ec->hdr.name);
...@@ -1329,7 +1297,7 @@ static int soc_tplg_dapm_widget_dbytes_create(struct soc_tplg *tplg, struct snd_ ...@@ -1329,7 +1297,7 @@ static int soc_tplg_dapm_widget_dbytes_create(struct soc_tplg *tplg, struct snd_
} }
/* pass control to driver for optional further init */ /* pass control to driver for optional further init */
err = soc_tplg_control_load(tplg, kc, (struct snd_soc_tplg_ctl_hdr *)be); err = soc_tplg_control_load(tplg, kc, &be->hdr);
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);
...@@ -1479,7 +1447,8 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1479,7 +1447,8 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
widget->dobj.type = SND_SOC_DOBJ_WIDGET; widget->dobj.type = SND_SOC_DOBJ_WIDGET;
widget->dobj.widget.kcontrol_type = kcontrol_type; widget->dobj.widget.kcontrol_type = kcontrol_type;
widget->dobj.ops = tplg->ops; if (tplg->ops)
widget->dobj.unload = tplg->ops->widget_unload;
widget->dobj.index = tplg->index; widget->dobj.index = tplg->index;
list_add(&widget->dobj.list, &tplg->comp->dobj_list); list_add(&widget->dobj.list, &tplg->comp->dobj_list);
...@@ -1493,7 +1462,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, ...@@ -1493,7 +1462,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
return 0; return 0;
ready_err: ready_err:
remove_widget(widget->dapm->component, &widget->dobj, SOC_TPLG_PASS_WIDGET); soc_tplg_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);
...@@ -1567,7 +1536,7 @@ static int soc_tplg_dapm_complete(struct soc_tplg *tplg) ...@@ -1567,7 +1536,7 @@ static int soc_tplg_dapm_complete(struct soc_tplg *tplg)
dev_err(tplg->dev, "ASoC: failed to create new widgets %d\n", dev_err(tplg->dev, "ASoC: failed to create new widgets %d\n",
ret); ret);
return 0; return ret;
} }
static int set_stream_info(struct soc_tplg *tplg, struct snd_soc_pcm_stream *stream, static int set_stream_info(struct soc_tplg *tplg, struct snd_soc_pcm_stream *stream,
...@@ -1657,8 +1626,9 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, ...@@ -1657,8 +1626,9 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
} }
dai_drv->dobj.index = tplg->index; dai_drv->dobj.index = tplg->index;
dai_drv->dobj.ops = tplg->ops;
dai_drv->dobj.type = SND_SOC_DOBJ_PCM; dai_drv->dobj.type = SND_SOC_DOBJ_PCM;
if (tplg->ops)
dai_drv->dobj.unload = tplg->ops->dai_unload;
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 */
...@@ -1727,8 +1697,9 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg, ...@@ -1727,8 +1697,9 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
link->num_platforms = 1; link->num_platforms = 1;
link->dobj.index = tplg->index; link->dobj.index = tplg->index;
link->dobj.ops = tplg->ops;
link->dobj.type = SND_SOC_DOBJ_DAI_LINK; link->dobj.type = SND_SOC_DOBJ_DAI_LINK;
if (tplg->ops)
link->dobj.unload = tplg->ops->link_unload;
if (strlen(pcm->pcm_name)) { if (strlen(pcm->pcm_name)) {
link->name = devm_kstrdup(tplg->dev, pcm->pcm_name, GFP_KERNEL); link->name = devm_kstrdup(tplg->dev, pcm->pcm_name, GFP_KERNEL);
...@@ -2135,8 +2106,9 @@ static int soc_tplg_link_config(struct soc_tplg *tplg, ...@@ -2135,8 +2106,9 @@ static int soc_tplg_link_config(struct soc_tplg *tplg,
/* for unloading it in snd_soc_tplg_component_remove */ /* for unloading it in snd_soc_tplg_component_remove */
link->dobj.index = tplg->index; link->dobj.index = tplg->index;
link->dobj.ops = tplg->ops;
link->dobj.type = SND_SOC_DOBJ_BACKEND_LINK; link->dobj.type = SND_SOC_DOBJ_BACKEND_LINK;
if (tplg->ops)
link->dobj.unload = tplg->ops->link_unload;
list_add(&link->dobj.list, &tplg->comp->dobj_list); list_add(&link->dobj.list, &tplg->comp->dobj_list);
return 0; return 0;
...@@ -2390,12 +2362,9 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, ...@@ -2390,12 +2362,9 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg,
} }
/* validate header magic, size and type */ /* validate header magic, size and type */
static int soc_valid_header(struct soc_tplg *tplg, static int soc_tplg_valid_header(struct soc_tplg *tplg,
struct snd_soc_tplg_hdr *hdr) struct snd_soc_tplg_hdr *hdr)
{ {
if (soc_tplg_get_hdr_offset(tplg) >= tplg->fw->size)
return 0;
if (le32_to_cpu(hdr->size) != sizeof(*hdr)) { if (le32_to_cpu(hdr->size) != sizeof(*hdr)) {
dev_err(tplg->dev, dev_err(tplg->dev,
"ASoC: invalid header size for type %d at offset 0x%lx size 0x%zx.\n", "ASoC: invalid header size for type %d at offset 0x%lx size 0x%zx.\n",
...@@ -2404,7 +2373,7 @@ static int soc_valid_header(struct soc_tplg *tplg, ...@@ -2404,7 +2373,7 @@ static int soc_valid_header(struct soc_tplg *tplg,
return -EINVAL; return -EINVAL;
} }
if (soc_tplg_get_hdr_offset(tplg) + hdr->payload_size >= tplg->fw->size) { if (soc_tplg_get_hdr_offset(tplg) + le32_to_cpu(hdr->payload_size) >= tplg->fw->size) {
dev_err(tplg->dev, dev_err(tplg->dev,
"ASoC: invalid header of type %d at offset %ld payload_size %d\n", "ASoC: invalid header of type %d at offset %ld payload_size %d\n",
le32_to_cpu(hdr->type), soc_tplg_get_hdr_offset(tplg), le32_to_cpu(hdr->type), soc_tplg_get_hdr_offset(tplg),
...@@ -2446,7 +2415,7 @@ static int soc_valid_header(struct soc_tplg *tplg, ...@@ -2446,7 +2415,7 @@ static int soc_valid_header(struct soc_tplg *tplg,
return -EINVAL; return -EINVAL;
} }
return 1; return 0;
} }
/* check header type and call appropriate handler */ /* check header type and call appropriate handler */
...@@ -2527,13 +2496,11 @@ static int soc_tplg_process_headers(struct soc_tplg *tplg) ...@@ -2527,13 +2496,11 @@ static int soc_tplg_process_headers(struct soc_tplg *tplg)
while (!soc_tplg_is_eof(tplg)) { while (!soc_tplg_is_eof(tplg)) {
/* make sure header is valid before loading */ /* make sure header is valid before loading */
ret = soc_valid_header(tplg, hdr); ret = soc_tplg_valid_header(tplg, hdr);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->dev, dev_err(tplg->dev,
"ASoC: topology: invalid header: %d\n", ret); "ASoC: topology: invalid header: %d\n", ret);
return ret; return ret;
} else if (ret == 0) {
break;
} }
/* load the header object */ /* load the header object */
...@@ -2627,26 +2594,22 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp) ...@@ -2627,26 +2594,22 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
list) { list) {
switch (dobj->type) { switch (dobj->type) {
case SND_SOC_DOBJ_MIXER:
remove_mixer(comp, dobj, pass);
break;
case SND_SOC_DOBJ_ENUM:
remove_enum(comp, dobj, pass);
break;
case SND_SOC_DOBJ_BYTES: case SND_SOC_DOBJ_BYTES:
remove_bytes(comp, dobj, pass); case SND_SOC_DOBJ_ENUM:
case SND_SOC_DOBJ_MIXER:
soc_tplg_remove_kcontrol(comp, dobj, pass);
break; break;
case SND_SOC_DOBJ_GRAPH: case SND_SOC_DOBJ_GRAPH:
remove_route(comp, dobj, pass); soc_tplg_remove_route(comp, dobj, pass);
break; break;
case SND_SOC_DOBJ_WIDGET: case SND_SOC_DOBJ_WIDGET:
remove_widget(comp, dobj, pass); soc_tplg_remove_widget(comp, dobj, pass);
break; break;
case SND_SOC_DOBJ_PCM: case SND_SOC_DOBJ_PCM:
remove_dai(comp, dobj, pass); soc_tplg_remove_dai(comp, dobj, pass);
break; break;
case SND_SOC_DOBJ_DAI_LINK: case SND_SOC_DOBJ_DAI_LINK:
remove_link(comp, dobj, pass); soc_tplg_remove_link(comp, dobj, pass);
break; break;
case SND_SOC_DOBJ_BACKEND_LINK: case SND_SOC_DOBJ_BACKEND_LINK:
/* /*
......
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