Re: [RFC PATCH] ALSA: hda - hdmi begin to support dynamic PCM assignment

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 13 Nov 2015 09:56:30 +0100,
libin.yang@xxxxxxxxxxxxxxx wrote:
> 
> From: Libin Yang <libin.yang@xxxxxxxxxxxxxxx>
> 
> Begin to support dynamic PCM assignment to pin in
> hdmi audio driver.
> 
> This means PCM will not be statically bound with pin.
> When there is a monitor connected, the corresponding pin
> will try to find a proper PCM to bind. When the monitor
> is disconnected, the corresponding pin will unbind
> the PCM. This helps to reduce the PCM number when there
> are many pins (device entries in DP MST mode) and only
> a few of them work at the same time.
> 
> This patch adds the pcm member in struct hdmi_spec_per_pin.
> When PCM is dynamically bound to the pin, the member pcm
> will pointer to the corresponding pcm_rec[] in hdmi_spec,
> which means the hda_pcm is bound to the pin.
> 
> Signed-off-by: Libin Yang <libin.yang@xxxxxxxxxxxxxxx>
> ---
>  sound/pci/hda/patch_hdmi.c | 26 +++++++++++++++++++++-----
>  1 file changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> index f503a88..f3363b8 100644
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -82,6 +82,7 @@ struct hdmi_spec_per_pin {
>  	struct mutex lock;
>  	struct delayed_work work;
>  	struct snd_kcontrol *eld_ctl;
> +	struct hda_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
>  	int repoll_count;
>  	bool setup; /* the stream has been set up by prepare callback */
>  	int channels; /* current number of channels */
> @@ -140,7 +141,8 @@ struct hdmi_spec {
>  	struct hdmi_ops ops;
>  
>  	bool dyn_pin_out;
> -
> +	bool dyn_pcm_assign;
> +	struct mutex pcm_lock;
>  	/*
>  	 * Non-generic VIA/NVIDIA specific
>  	 */
> @@ -378,13 +380,26 @@ static int hinfo_to_pin_index(struct hda_codec *codec,
>  			      struct hda_pcm_stream *hinfo)
>  {
>  	struct hdmi_spec *spec = codec->spec;
> +	struct hdmi_spec_per_pin *per_pin;
>  	int pin_idx;
>  
> -	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
> -		if (get_pcm_rec(spec, pin_idx)->stream == hinfo)
> -			return pin_idx;
> +	if (!spec->dyn_pcm_assign) {
> +		for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
> +			if (get_pcm_rec(spec, pin_idx)->stream == hinfo)
> +				return pin_idx;
> +	} else {
> +		mutex_lock(&spec->pcm_lock);
> +		for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
> +			per_pin = get_pin(spec, pin_idx);
> +			if (per_pin->pcm && per_pin->pcm->stream == hinfo) {
> +				mutex_unlock(&spec->pcm_lock);
> +				return pin_idx;
> +			}
> +		}
> +		mutex_unlock(&spec->pcm_lock);

You can assign per_pin->pcm statically at init time when
dyn_pcm_assign=false.  Then the same code is used in the above.

The need of spec->pcm_lock isn't clear at this moment.  I guess you're
trying to avoid the race of dynamic pin assignment and release.  But
then the code above doesn't protect anything because you return the
pin_idx as an available value after the unlock.  Then the pin release
can happen after this point while you're accessing with the pin_idx.

So, better to consider the implementation of lock or other mechanism
once when the whole picture is ready.


Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel



[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux