|
@@ -33,6 +33,7 @@
|
|
|
#include <linux/delay.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/module.h>
|
|
|
+#include <linux/pm_runtime.h>
|
|
|
#include <sound/core.h>
|
|
|
#include <sound/jack.h>
|
|
|
#include <sound/asoundef.h>
|
|
@@ -764,8 +765,10 @@ static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid,
|
|
|
|
|
|
if (pin_idx < 0)
|
|
|
return;
|
|
|
+ mutex_lock(&spec->pcm_lock);
|
|
|
if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
|
|
|
snd_hda_jack_report_sync(codec);
|
|
|
+ mutex_unlock(&spec->pcm_lock);
|
|
|
}
|
|
|
|
|
|
static void jack_callback(struct hda_codec *codec,
|
|
@@ -1628,21 +1631,23 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
|
|
|
static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
|
|
|
{
|
|
|
struct hda_codec *codec = per_pin->codec;
|
|
|
- struct hdmi_spec *spec = codec->spec;
|
|
|
int ret;
|
|
|
|
|
|
/* no temporary power up/down needed for component notifier */
|
|
|
- if (!codec_has_acomp(codec))
|
|
|
- snd_hda_power_up_pm(codec);
|
|
|
+ if (!codec_has_acomp(codec)) {
|
|
|
+ ret = snd_hda_power_up_pm(codec);
|
|
|
+ if (ret < 0 && pm_runtime_suspended(hda_codec_dev(codec))) {
|
|
|
+ snd_hda_power_down_pm(codec);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- mutex_lock(&spec->pcm_lock);
|
|
|
if (codec_has_acomp(codec)) {
|
|
|
sync_eld_via_acomp(codec, per_pin);
|
|
|
ret = false; /* don't call snd_hda_jack_report_sync() */
|
|
|
} else {
|
|
|
ret = hdmi_present_sense_via_verbs(per_pin, repoll);
|
|
|
}
|
|
|
- mutex_unlock(&spec->pcm_lock);
|
|
|
|
|
|
if (!codec_has_acomp(codec))
|
|
|
snd_hda_power_down_pm(codec);
|
|
@@ -1654,12 +1659,16 @@ static void hdmi_repoll_eld(struct work_struct *work)
|
|
|
{
|
|
|
struct hdmi_spec_per_pin *per_pin =
|
|
|
container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work);
|
|
|
+ struct hda_codec *codec = per_pin->codec;
|
|
|
+ struct hdmi_spec *spec = codec->spec;
|
|
|
|
|
|
if (per_pin->repoll_count++ > 6)
|
|
|
per_pin->repoll_count = 0;
|
|
|
|
|
|
+ mutex_lock(&spec->pcm_lock);
|
|
|
if (hdmi_present_sense(per_pin, per_pin->repoll_count))
|
|
|
snd_hda_jack_report_sync(per_pin->codec);
|
|
|
+ mutex_unlock(&spec->pcm_lock);
|
|
|
}
|
|
|
|
|
|
static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
|