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@xxxxxxxx> > --- > 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 > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel