[alsa-devel] [PATCH] ALSA: hda - repoll jack presence state on resume

Takashi Iwai tiwai at suse.de
Fri Aug 12 16:03:00 CEST 2016


On Fri, 12 Aug 2016 15:52:04 +0200,
Jaroslav Kysela wrote:
> 
> The jack detection on resume might fail on some hardware
> (Lenovo T430s, T440s and X1 Carbon 2016). The codec registers
> reports that the jack is not used and the unsolicited event
> is not sent on change (or perhaps, it's lost?).
> 
> This patch will repoll the jack presence state after
> 100ms again.

Does this happen with the runtime PM, too?  If the runtime PM doesn't
suffer, such a delay can be skipped for runtime resume, at least.
100ms isn't so short for the runtime PM, after all.

> Because the jack status is updated from two workqueues now,
> create a new codec->jack_mutex to protect the concurrent
> access.

IMO, it's better to move mutex_lock call in hda_jack.c.

And the similar situation may happen with the jackpoll option, could
you split this mutex protection change as a separate fix?


thanks,

Takashi


> Signed-off-by: Jaroslav Kysela <perex at perex.cz>
> ---
>  sound/pci/hda/hda_bind.c  | 2 ++
>  sound/pci/hda/hda_codec.c | 9 ++++++++-
>  sound/pci/hda/hda_codec.h | 1 +
>  3 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
> index 6efadbf..81a9284 100644
> --- a/sound/pci/hda/hda_bind.c
> +++ b/sound/pci/hda/hda_bind.c
> @@ -42,8 +42,10 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
>  {
>  	struct hda_codec *codec = container_of(dev, struct hda_codec, core);
>  
> +	mutex_lock(&codec->jack_mutex);
>  	if (codec->patch_ops.unsol_event)
>  		codec->patch_ops.unsol_event(codec, ev);
> +	mutex_unlock(&codec->jack_mutex);
>  }
>  
>  /**
> diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
> index 9913be8..4339e98 100644
> --- a/sound/pci/hda/hda_codec.c
> +++ b/sound/pci/hda/hda_codec.c
> @@ -592,8 +592,10 @@ static void hda_jackpoll_work(struct work_struct *work)
>  	struct hda_codec *codec =
>  		container_of(work, struct hda_codec, jackpoll_work.work);
>  
> +	mutex_lock(&codec->jack_mutex);
>  	snd_hda_jack_set_dirty_all(codec);
>  	snd_hda_jack_poll_all(codec);
> +	mutex_unlock(&codec->jack_mutex);
>  
>  	if (!codec->jackpoll_interval)
>  		return;
> @@ -837,6 +839,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
>  	codec->addr = codec_addr;
>  	mutex_init(&codec->spdif_mutex);
>  	mutex_init(&codec->control_mutex);
> +	mutex_init(&codec->jack_mutex);
>  	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
>  	snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
>  	snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
> @@ -3002,8 +3005,12 @@ static void hda_call_codec_resume(struct hda_codec *codec)
>  
>  	if (codec->jackpoll_interval)
>  		hda_jackpoll_work(&codec->jackpoll_work.work);
> -	else
> +	else {
>  		snd_hda_jack_report_sync(codec);
> +		/* Some hw requires a little time to settle things */
> +		schedule_delayed_work(&codec->jackpoll_work,
> +					msecs_to_jiffies(100));
> +	}
>  	atomic_dec(&codec->core.in_pm);
>  }
>  
> diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
> index 373fcad..6a4a631 100644
> --- a/sound/pci/hda/hda_codec.h
> +++ b/sound/pci/hda/hda_codec.h
> @@ -213,6 +213,7 @@ struct hda_codec {
>  
>  	struct mutex spdif_mutex;
>  	struct mutex control_mutex;
> +	struct mutex jack_mutex;
>  	struct snd_array spdif_out;
>  	unsigned int spdif_in_enable;	/* SPDIF input enable? */
>  	const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
> -- 
> 2.5.5
> 


More information about the Alsa-devel mailing list