[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