[alsa-devel] [PATCH v2 2/2] ASoC: topology: Only free TLV for volume mixers of a widget
Takashi Sakamoto
o-takashi at sakamocchi.jp
Mon Nov 28 04:32:13 CET 2016
Mendong Lin,
On 2016年11月28日 10:53, mengdong.lin at linux.intel.com wrote:
> From: Mengdong Lin <mengdong.lin at linux.intel.com>
>
> Replace flag 'kcontrol_enum' with a type value of embedded controls for
> a widget. So topology can check the type of its embedded controls when
> removing the widget, and only free the TLV of volume mixers. Bytes
> controls don't have TLV.
>
> And when removing a widget created by topology, just free the private
> value which is used as struct soc_mixer_control for volume mixers or
> soc_bytes_ext for bytes controls. No need to cast the private data to
> control-specific struct pointers before freeing it.
>
> Signed-off-by: Mengdong Lin <mengdong.lin at linux.intel.com>
>
> ---
> v2: fix lkp warning: 'kcontrol_type' may be used uninitialized in this
> function [-Wmaybe-uninitialized]
> widget->dobj.widget.kcontrol_type = kcontrol_type;
> ---
>
> diff --git a/include/sound/soc-topology.h b/include/sound/soc-topology.h
> index d318fe4..86c884a 100644
> --- a/include/sound/soc-topology.h
> +++ b/include/sound/soc-topology.h
> @@ -53,7 +53,7 @@ struct snd_soc_dobj_control {
>
> /* dynamic widget object */
> struct snd_soc_dobj_widget {
> - unsigned int kcontrol_enum:1; /* this widget is an enum kcontrol */
> + unsigned int kcontrol_type; /* kcontrol type: mixer, enum, bytes */
> };
If you have a plan to assign any values of 'snd_soc_dobj_type'
enumerator, it's better to use it as type of this member so that
developers can easily understand actual value for this member.
Then, I wonder the reason that 'struct snd_soc_dobj' includes two member
of the type; 'struct snd_soc_dobj.type' and 'struct
snd_soc_dobj.widget.kcontrol_tyoe'. Would I ask you explain about the
framework you work for in this point? Is it something for backward
compatibility?
> /* generic dynamic object - all dynamic objects belong to this struct */
> diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
> index 63e1a50..6f7c7a4 100644
> --- a/sound/soc/soc-topology.c
> +++ b/sound/soc/soc-topology.c
> @@ -489,7 +489,7 @@ static void remove_widget(struct snd_soc_component *comp,
> * Dynamic Widgets either have 1..N enum kcontrols or mixers.
> * The enum may either have an array of values or strings.
> */
> - if (dobj->widget.kcontrol_enum) {
> + if (dobj->widget.kcontrol_type == SND_SOC_TPLG_TYPE_ENUM) {
> /* enumerated widget mixer */
> for (i = 0; i < w->num_kcontrols; i++) {
> struct snd_kcontrol *kcontrol = w->kcontrols[i];
> @@ -506,16 +506,21 @@ static void remove_widget(struct snd_soc_component *comp,
> }
> kfree(w->kcontrol_news);
> } else {
> - /* non enumerated widget mixer */
> + /* volume mixer or bytes controls */
> for (i = 0; i < w->num_kcontrols; i++) {
> struct snd_kcontrol *kcontrol = w->kcontrols[i];
> - struct soc_mixer_control *sm =
> - (struct soc_mixer_control *) kcontrol->private_value;
>
> - kfree(w->kcontrols[i]->tlv.p);
> + if (dobj->widget.kcontrol_type
> + == SND_SOC_TPLG_TYPE_MIXER)
> + kfree(kcontrol->tlv.p);
>
> - snd_ctl_remove(card, w->kcontrols[i]);
> - kfree(sm);
> + snd_ctl_remove(card, kcontrol);
> +
> + /* Private value is used as struct soc_mixer_control
> + * for volume mixers or soc_bytes_ext for bytes
> + * controls.
> + */
> + kfree((void *)kcontrol->private_value);
> }
> kfree(w->kcontrol_news);
> }
> @@ -1439,6 +1444,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
> struct snd_soc_dapm_widget template, *widget;
> struct snd_soc_tplg_ctl_hdr *control_hdr;
> struct snd_soc_card *card = tplg->comp->card;
> + unsigned int kcontrol_type = SND_SOC_TPLG_TYPE_MIXER;
> int ret = 0;
>
> if (strnlen(w->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) ==
> @@ -1494,6 +1500,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
> case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
> case SND_SOC_TPLG_CTL_RANGE:
> case SND_SOC_TPLG_DAPM_CTL_VOLSW:
> + kcontrol_type = SND_SOC_TPLG_TYPE_MIXER; /* volume mixer */
> template.num_kcontrols = w->num_kcontrols;
> template.kcontrol_news =
> soc_tplg_dapm_widget_dmixer_create(tplg,
> @@ -1508,7 +1515,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
> case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
> case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
> case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
> - template.dobj.widget.kcontrol_enum = 1;
> + kcontrol_type = SND_SOC_TPLG_TYPE_ENUM; /* enumerated mixer */
> template.num_kcontrols = w->num_kcontrols;
> template.kcontrol_news =
> soc_tplg_dapm_widget_denum_create(tplg,
> @@ -1519,6 +1526,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
> }
> break;
> case SND_SOC_TPLG_CTL_BYTES:
> + kcontrol_type = SND_SOC_TPLG_TYPE_BYTES; /* bytes control */
> template.num_kcontrols = w->num_kcontrols;
> template.kcontrol_news =
> soc_tplg_dapm_widget_dbytes_create(tplg,
> @@ -1555,6 +1563,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
> }
>
> widget->dobj.type = SND_SOC_DOBJ_WIDGET;
> + widget->dobj.widget.kcontrol_type = kcontrol_type;
> widget->dobj.ops = tplg->ops;
> widget->dobj.index = tplg->index;
> kfree(template.sname);
Regards
Takashi Sakamoto
More information about the Alsa-devel
mailing list