--- /dev/null
+From b5a236c175b0d984552a5f7c9d35141024c2b261 Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Tue, 19 Mar 2019 09:28:44 +0800
+Subject: ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec
+
+From: Hui Wang <hui.wang@canonical.com>
+
+commit b5a236c175b0d984552a5f7c9d35141024c2b261 upstream.
+
+Recently we found the audio jack detection stop working after suspend
+on many machines with Realtek codec. Sometimes the audio selection
+dialogue didn't show up after users plugged headhphone/headset into
+the headset jack, sometimes after uses plugged headphone/headset, then
+click the sound icon on the upper-right corner of gnome-desktop, it
+also showed the speaker rather than the headphone.
+
+The root cause is that before suspend, the codec already call the
+runtime_suspend since this codec is not used by any apps, then in
+resume, it will not call runtime_resume for this codec. But for some
+realtek codec (so far, alc236, alc255 and alc891) with the specific
+BIOS, if it doesn't run runtime_resume after suspend, all codec
+functions including jack detection stop working anymore.
+
+This problem existed for a long time, but it was not exposed, that is
+because when problem happens, if users play sound or open
+sound-setting to check audio device, this will trigger calling to
+runtime_resume (via snd_hda_power_up), then the codec starts working
+again before users notice this problem.
+
+Since we don't know how many codec and BIOS combinations have this
+problem, to fix it, let the driver call runtime_resume for all codecs
+in pm_resume, maybe for some codecs, this is not needed, but it is
+harmless. After a codec is runtime resumed, if it is not used by any
+apps, it will be runtime suspended soon and furthermore we don't run
+suspend frequently, this change will not add much power consumption.
+
+Fixes: cc72da7d4d06 ("ALSA: hda - Use standard runtime PM for codec power-save control")
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_codec.c | 20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -2944,6 +2944,20 @@ static int hda_codec_runtime_resume(stru
+ #endif /* CONFIG_PM */
+
+ #ifdef CONFIG_PM_SLEEP
++static int hda_codec_force_resume(struct device *dev)
++{
++ int ret;
++
++ /* The get/put pair below enforces the runtime resume even if the
++ * device hasn't been used at suspend time. This trick is needed to
++ * update the jack state change during the sleep.
++ */
++ pm_runtime_get_noresume(dev);
++ ret = pm_runtime_force_resume(dev);
++ pm_runtime_put(dev);
++ return ret;
++}
++
+ static int hda_codec_pm_suspend(struct device *dev)
+ {
+ dev->power.power_state = PMSG_SUSPEND;
+@@ -2953,7 +2967,7 @@ static int hda_codec_pm_suspend(struct d
+ static int hda_codec_pm_resume(struct device *dev)
+ {
+ dev->power.power_state = PMSG_RESUME;
+- return pm_runtime_force_resume(dev);
++ return hda_codec_force_resume(dev);
+ }
+
+ static int hda_codec_pm_freeze(struct device *dev)
+@@ -2965,13 +2979,13 @@ static int hda_codec_pm_freeze(struct de
+ static int hda_codec_pm_thaw(struct device *dev)
+ {
+ dev->power.power_state = PMSG_THAW;
+- return pm_runtime_force_resume(dev);
++ return hda_codec_force_resume(dev);
+ }
+
+ static int hda_codec_pm_restore(struct device *dev)
+ {
+ dev->power.power_state = PMSG_RESTORE;
+- return pm_runtime_force_resume(dev);
++ return hda_codec_force_resume(dev);
+ }
+ #endif /* CONFIG_PM_SLEEP */
+
--- /dev/null
+From 98081ca62cbac31fb0f7efaf90b2e7384ce22257 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 29 Jan 2019 14:03:33 +0100
+Subject: ALSA: hda - Record the current power state before suspend/resume calls
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 98081ca62cbac31fb0f7efaf90b2e7384ce22257 upstream.
+
+Currently we deal with single codec and suspend codec callbacks for
+all S3, S4 and runtime PM handling. But it turned out that we want
+distinguish the call patterns sometimes, e.g. for applying some init
+sequence only at probing and restoring from hibernate.
+
+This patch slightly modifies the common PM callbacks for HD-audio
+codec and stores the currently processed PM event in power_state of
+the codec's device.power field, which is currently unused. The codec
+callback can take a look at this event value and judges which purpose
+it's being called.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_codec.c | 43 +++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 41 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -2909,6 +2909,7 @@ static void hda_call_codec_resume(struct
+ hda_jackpoll_work(&codec->jackpoll_work.work);
+ else
+ snd_hda_jack_report_sync(codec);
++ codec->core.dev.power.power_state = PMSG_ON;
+ snd_hdac_leave_pm(&codec->core);
+ }
+
+@@ -2942,10 +2943,48 @@ static int hda_codec_runtime_resume(stru
+ }
+ #endif /* CONFIG_PM */
+
++#ifdef CONFIG_PM_SLEEP
++static int hda_codec_pm_suspend(struct device *dev)
++{
++ dev->power.power_state = PMSG_SUSPEND;
++ return pm_runtime_force_suspend(dev);
++}
++
++static int hda_codec_pm_resume(struct device *dev)
++{
++ dev->power.power_state = PMSG_RESUME;
++ return pm_runtime_force_resume(dev);
++}
++
++static int hda_codec_pm_freeze(struct device *dev)
++{
++ dev->power.power_state = PMSG_FREEZE;
++ return pm_runtime_force_suspend(dev);
++}
++
++static int hda_codec_pm_thaw(struct device *dev)
++{
++ dev->power.power_state = PMSG_THAW;
++ return pm_runtime_force_resume(dev);
++}
++
++static int hda_codec_pm_restore(struct device *dev)
++{
++ dev->power.power_state = PMSG_RESTORE;
++ return pm_runtime_force_resume(dev);
++}
++#endif /* CONFIG_PM_SLEEP */
++
+ /* referred in hda_bind.c */
+ const struct dev_pm_ops hda_codec_driver_pm = {
+- SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+- pm_runtime_force_resume)
++#ifdef CONFIG_PM_SLEEP
++ .suspend = hda_codec_pm_suspend,
++ .resume = hda_codec_pm_resume,
++ .freeze = hda_codec_pm_freeze,
++ .thaw = hda_codec_pm_thaw,
++ .poweroff = hda_codec_pm_suspend,
++ .restore = hda_codec_pm_restore,
++#endif /* CONFIG_PM_SLEEP */
+ SET_RUNTIME_PM_OPS(hda_codec_runtime_suspend, hda_codec_runtime_resume,
+ NULL)
+ };