[RESEND] [SRU] [F/G/Unstable/OEM-5.6] [PATCH 0/3] Fix broken MSI interrupt after HDA controller was suspended

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[RESEND] [SRU] [F/G/Unstable/OEM-5.6] [PATCH 0/3] Fix broken MSI interrupt after HDA controller was suspended

Kai-Heng Feng
BugLink: https://bugs.launchpad.net/bugs/1899586

[Impact]
After HDA controller gets suspended and resumed, no MSI interrupt raised
when plugging headset to the audio jack.

[Fix]
Power up the Realtek codec when HDA controller runtime resumes.

[Test]
1) Make sure both codec and HDA controller are runtime suspended.
2) Runtime resume the HDA controller without runtime resume the codec.
3) Plug a headset and see if the system can detect anything.

With the fix applied, we can see azx_interrupt() is working again by
using ftrace.

[Regression Potential]
If there's any system that is not affected by this issue, runtime-resume
the HDA controller will take a slightly longer time. It's rather
unlikely, since _all_ systems with Realtek codec we tested have this
issue, regardless of AMD or Intel.

Kai Vehmanen (1):
  UBUNTU: SAUCE: ALSA: hda: fix jack detection with Realtek codecs when
    in D3

Takashi Iwai (2):
  ALSA: hda: Skip controller resume if not needed
  ALSA: hda: Always use jackpoll helper for jack update after resume

 include/sound/hda_codec.h     |  6 ++++++
 sound/pci/hda/hda_codec.c     | 28 +++++++++++++++-----------
 sound/pci/hda/hda_intel.c     | 37 ++++++++++++++++++++---------------
 sound/pci/hda/patch_realtek.c |  1 +
 4 files changed, 45 insertions(+), 27 deletions(-)

--
2.17.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[F/OEM-5.6] [PATCH 1/3] ALSA: hda: Skip controller resume if not needed

Kai-Heng Feng
From: Takashi Iwai <[hidden email]>

BugLink: https://bugs.launchpad.net/bugs/1899586

The HD-audio controller does system-suspend and resume operations by
directly calling its helpers __azx_runtime_suspend() and
__azx_runtime_resume().  However, in general, we don't have to resume
always the device fully at the system resume; typically, if a device
has been runtime-suspended, we can leave it to runtime resume.

Usually for achieving this, the driver would call
pm_runtime_force_suspend() and pm_runtime_force_resume() pairs in the
system suspend and resume ops.  Unfortunately, this doesn't work for
the resume path in our case.  For handling the jack detection at the
system resume, a child codec device may need the (literally) forcibly
resume even if it's been runtime-suspended, and for that, the
controller device must be also resumed even if it's been suspended.

This patch is an attempt to improve the situation.  It replaces the
direct __azx_runtime_suspend()/_resume() calls with with
pm_runtime_force_suspend() and pm_runtime_force_resume() with a slight
trick as we've done for the codec side.  More exactly:

- azx_has_pm_runtime() check is dropped from azx_runtime_suspend() and
  azx_runtime_resume(), so that it can be properly executed from the
  system-suspend/resume path

- The WAKEEN handling depends on the card's power state now; it's set
  and cleared only for the runtime-suspend

- azx_resume() checks whether any codec may need the forcible resume
  beforehand.  If the forcible resume is required, it does temporary
  PM refcount up/down for actually triggering the runtime resume.

- A new helper function, hda_codec_need_resume(), is introduced for
  checking whether the codec needs a forcible runtime-resume, and the
  existing code is rewritten with that.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-6-tiwai@...
Signed-off-by: Takashi Iwai <[hidden email]>
(cherry picked from commit c4c8dd6ef807663e42a5f04ea77cd62029eb99fa)
Signed-off-by: Kai-Heng Feng <[hidden email]>
---
 include/sound/hda_codec.h |  5 +++++
 sound/pci/hda/hda_codec.c |  2 +-
 sound/pci/hda/hda_intel.c | 38 +++++++++++++++++++++++++++-----------
 3 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
index 3ee8036f5436..225154a4f2ed 100644
--- a/include/sound/hda_codec.h
+++ b/include/sound/hda_codec.h
@@ -494,6 +494,11 @@ void snd_hda_update_power_acct(struct hda_codec *codec);
 static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
 #endif
 
+static inline bool hda_codec_need_resume(struct hda_codec *codec)
+{
+ return !codec->relaxed_resume && codec->jacktbl.used;
+}
+
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 /*
  * patch firmware
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 53e7732ef752..aed1f8188e66 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2951,7 +2951,7 @@ static int hda_codec_runtime_resume(struct device *dev)
 static int hda_codec_force_resume(struct device *dev)
 {
  struct hda_codec *codec = dev_to_hda_codec(dev);
- bool forced_resume = !codec->relaxed_resume && codec->jacktbl.used;
+ bool forced_resume = hda_codec_need_resume(codec);
  int ret;
 
  /* The get/put pair below enforces the runtime resume even if the
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index a14dff82b6d5..c07d4e8c5d7f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1027,7 +1027,7 @@ static int azx_suspend(struct device *dev)
  chip = card->private_data;
  bus = azx_bus(chip);
  snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- __azx_runtime_suspend(chip);
+ pm_runtime_force_suspend(dev);
  if (bus->irq >= 0) {
  free_irq(bus->irq, chip);
  bus->irq = -1;
@@ -1044,7 +1044,9 @@ static int azx_suspend(struct device *dev)
 static int azx_resume(struct device *dev)
 {
  struct snd_card *card = dev_get_drvdata(dev);
+ struct hda_codec *codec;
  struct azx *chip;
+ bool forced_resume = false;
 
  if (!azx_is_pm_ready(card))
  return 0;
@@ -1055,7 +1057,20 @@ static int azx_resume(struct device *dev)
  chip->msi = 0;
  if (azx_acquire_irq(chip, 1) < 0)
  return -EIO;
- __azx_runtime_resume(chip, false);
+
+ /* check for the forced resume */
+ list_for_each_codec(codec, &chip->bus) {
+ if (hda_codec_need_resume(codec)) {
+ forced_resume = true;
+ break;
+ }
+ }
+
+ if (forced_resume)
+ pm_runtime_get_noresume(dev);
+ pm_runtime_force_resume(dev);
+ if (forced_resume)
+ pm_runtime_put(dev);
  snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 
  trace_azx_resume(chip);
@@ -1102,12 +1117,12 @@ static int azx_runtime_suspend(struct device *dev)
  if (!azx_is_pm_ready(card))
  return 0;
  chip = card->private_data;
- if (!azx_has_pm_runtime(chip))
- return 0;
 
  /* enable controller wake up event */
- azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
-  STATESTS_INT_MASK);
+ if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0) {
+ azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
+   STATESTS_INT_MASK);
+ }
 
  __azx_runtime_suspend(chip);
  trace_azx_runtime_suspend(chip);
@@ -1118,17 +1133,18 @@ static int azx_runtime_resume(struct device *dev)
 {
  struct snd_card *card = dev_get_drvdata(dev);
  struct azx *chip;
+ bool from_rt = snd_power_get_state(card) == SNDRV_CTL_POWER_D0;
 
  if (!azx_is_pm_ready(card))
  return 0;
  chip = card->private_data;
- if (!azx_has_pm_runtime(chip))
- return 0;
- __azx_runtime_resume(chip, true);
+ __azx_runtime_resume(chip, from_rt);
 
  /* disable controller Wake Up event*/
- azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
- ~STATESTS_INT_MASK);
+ if (from_rt) {
+ azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
+   ~STATESTS_INT_MASK);
+ }
 
  trace_azx_runtime_resume(chip);
  return 0;
--
2.17.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[F/OEM-5.6] [PATCH 2/3] ALSA: hda: Always use jackpoll helper for jack update after resume

Kai-Heng Feng
In reply to this post by Kai-Heng Feng
From: Takashi Iwai <[hidden email]>

BugLink: https://bugs.launchpad.net/bugs/1899586

HD-audio codec driver applies a tricky procedure to forcibly perform
the runtime resume by mimicking the usage count even if the device has
been runtime-suspended beforehand.  This was needed to assure to
trigger the jack detection update after the system resume.

And recently we also applied the similar logic to the HD-audio
controller side.  However this seems leading to some inconsistency,
and eventually PCI controller gets screwed up.

This patch is an attempt to fix and clean up those behavior: instead
of the tricky runtime resume procedure, the existing jackpoll work is
scheduled when such a forced codec resume is required.  The jackpoll
work will power up the codec, and this alone should suffice for the
jack status update in usual cases.  If the extra polling is requested
(by checking codec->jackpoll_interval), the manual update is invoked
after that, and the codec is powered down again.

Also, we filter the spurious wake up of the codec from the controller
runtime resume by checking codec->relaxed_resume flag.  If this flag
is set, basically we don't need to wake up explicitly, but it's
supposed to be done via the audio component notifier.

Fixes: c4c8dd6ef807 ("ALSA: hda: Skip controller resume if not needed")
Link: https://lore.kernel.org/r/20200422203744.26299-1-tiwai@...
Signed-off-by: Takashi Iwai <[hidden email]>
(cherry picked from commit 8d6762af302d69f76fa788a277a56a9d9cd275d5)
Signed-off-by: Kai-Heng Feng <[hidden email]>
---
 sound/pci/hda/hda_codec.c | 28 +++++++++++++++++-----------
 sound/pci/hda/hda_intel.c | 17 ++---------------
 2 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index aed1f8188e66..0491dc1b6f3f 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -641,8 +641,18 @@ static void hda_jackpoll_work(struct work_struct *work)
  struct hda_codec *codec =
  container_of(work, struct hda_codec, jackpoll_work.work);
 
- snd_hda_jack_set_dirty_all(codec);
- snd_hda_jack_poll_all(codec);
+ /* for non-polling trigger: we need nothing if already powered on */
+ if (!codec->jackpoll_interval && snd_hdac_is_power_on(&codec->core))
+ return;
+
+ /* the power-up/down sequence triggers the runtime resume */
+ snd_hda_power_up_pm(codec);
+ /* update jacks manually if polling is required, too */
+ if (codec->jackpoll_interval) {
+ snd_hda_jack_set_dirty_all(codec);
+ snd_hda_jack_poll_all(codec);
+ }
+ snd_hda_power_down_pm(codec);
 
  if (!codec->jackpoll_interval)
  return;
@@ -2951,18 +2961,14 @@ static int hda_codec_runtime_resume(struct device *dev)
 static int hda_codec_force_resume(struct device *dev)
 {
  struct hda_codec *codec = dev_to_hda_codec(dev);
- bool forced_resume = hda_codec_need_resume(codec);
  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.
- */
- if (forced_resume)
- pm_runtime_get_noresume(dev);
  ret = pm_runtime_force_resume(dev);
- if (forced_resume)
- pm_runtime_put(dev);
+ /* schedule jackpoll work for jack detection update */
+ if (codec->jackpoll_interval ||
+    (pm_runtime_suspended(dev) && hda_codec_need_resume(codec)))
+ schedule_delayed_work(&codec->jackpoll_work,
+      codec->jackpoll_interval);
  return ret;
 }
 
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c07d4e8c5d7f..35c7d5bad1bc 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1004,7 +1004,8 @@ static void __azx_runtime_resume(struct azx *chip, bool from_rt)
 
  if (status && from_rt) {
  list_for_each_codec(codec, &chip->bus)
- if (status & (1 << codec->addr))
+ if (!codec->relaxed_resume &&
+    (status & (1 << codec->addr)))
  schedule_delayed_work(&codec->jackpoll_work,
       codec->jackpoll_interval);
  }
@@ -1044,9 +1045,7 @@ static int azx_suspend(struct device *dev)
 static int azx_resume(struct device *dev)
 {
  struct snd_card *card = dev_get_drvdata(dev);
- struct hda_codec *codec;
  struct azx *chip;
- bool forced_resume = false;
 
  if (!azx_is_pm_ready(card))
  return 0;
@@ -1058,19 +1057,7 @@ static int azx_resume(struct device *dev)
  if (azx_acquire_irq(chip, 1) < 0)
  return -EIO;
 
- /* check for the forced resume */
- list_for_each_codec(codec, &chip->bus) {
- if (hda_codec_need_resume(codec)) {
- forced_resume = true;
- break;
- }
- }
-
- if (forced_resume)
- pm_runtime_get_noresume(dev);
  pm_runtime_force_resume(dev);
- if (forced_resume)
- pm_runtime_put(dev);
  snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 
  trace_azx_resume(chip);
--
2.17.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[F/G/Unstable/OEM-5.6] [PATCH 3/3] UBUNTU: SAUCE: ALSA: hda: fix jack detection with Realtek codecs when in D3

Kai-Heng Feng
In reply to this post by Kai-Heng Feng
From: Kai Vehmanen <[hidden email]>

BugLink: https://bugs.launchpad.net/bugs/1899586

In case HDA controller becomes active, but codec is runtime suspended,
jack detection is not successful and no interrupt is raised. This has
been observed with multiple Realtek codecs and HDA controllers from
different vendors. Bug does not occur if both codec and controller are
active, or both are in suspend. Bug can be easily hit on desktop systems
with no built-in speaker.

The problem can be fixed by powering up the codec once after every
controller runtime resume. Even if codec goes back to suspend later, the
jack detection will continue to work. Add a flag to 'hda_codec' to
describe codecs that require this flow from the controller driver.
Modify __azx_runtime_resume() to use pm_request_resume() to make the
intent clearer.

Mark all Realtek codecs with the new forced_resume flag.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=209379
Cc: Kailang Yang <[hidden email]>
Co-developed-by: Kai-Heng Feng <[hidden email]>
Signed-off-by: Kai-Heng Feng <[hidden email]>
Signed-off-by: Kai Vehmanen <[hidden email]>
Cc: <[hidden email]>
Link: https://lore.kernel.org/r/20201012102704.794423-1-kai.vehmanen@...
Signed-off-by: Takashi Iwai <[hidden email]>
(cherry picked from commit a6e7d0a4bdb02a7a3ffe0b44aaa8842b7efdd056 git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git master)
Signed-off-by: Kai-Heng Feng <[hidden email]>
---
 include/sound/hda_codec.h     |  1 +
 sound/pci/hda/hda_intel.c     | 14 ++++++++------
 sound/pci/hda/patch_realtek.c |  1 +
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
index 225154a4f2ed..b4d112e40ae7 100644
--- a/include/sound/hda_codec.h
+++ b/include/sound/hda_codec.h
@@ -253,6 +253,7 @@ struct hda_codec {
  unsigned int force_pin_prefix:1; /* Add location prefix */
  unsigned int link_down_at_suspend:1; /* link down at runtime suspend */
  unsigned int relaxed_resume:1; /* don't resume forcibly for jack */
+ unsigned int forced_resume:1; /* forced resume for jack */
  unsigned int mst_no_extra_pcms:1; /* no backup PCMs for DP-MST */
 
 #ifdef CONFIG_PM
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 35c7d5bad1bc..16c66aa4d381 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1002,12 +1002,14 @@ static void __azx_runtime_resume(struct azx *chip, bool from_rt)
  azx_init_pci(chip);
  hda_intel_init_chip(chip, true);
 
- if (status && from_rt) {
- list_for_each_codec(codec, &chip->bus)
- if (!codec->relaxed_resume &&
-    (status & (1 << codec->addr)))
- schedule_delayed_work(&codec->jackpoll_work,
-      codec->jackpoll_interval);
+ if (from_rt) {
+ list_for_each_codec(codec, &chip->bus) {
+ if (codec->relaxed_resume)
+ continue;
+
+ if (codec->forced_resume || (status & (1 << codec->addr)))
+ pm_request_resume(hda_codec_dev(codec));
+ }
  }
 
  /* power down again for link-controlled chips */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b44219859d82..9b635ae01b6c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1150,6 +1150,7 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
  codec->single_adc_amp = 1;
  /* FIXME: do we need this for all Realtek codec models? */
  codec->spdif_status_reset = 1;
+ codec->forced_resume = 1;
  codec->patch_ops = alc_patch_ops;
 
  err = alc_codec_rename_from_preset(codec);
--
2.17.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

ACK: [RESEND] [SRU] [F/G/Unstable/OEM-5.6] [PATCH 0/3] Fix broken MSI interrupt after HDA controller was suspended

Stefan Bader-2
In reply to this post by Kai-Heng Feng
On 13.10.20 09:53, Kai-Heng Feng wrote:

> BugLink: https://bugs.launchpad.net/bugs/1899586
>
> [Impact]
> After HDA controller gets suspended and resumed, no MSI interrupt raised
> when plugging headset to the audio jack.
>
> [Fix]
> Power up the Realtek codec when HDA controller runtime resumes.
>
> [Test]
> 1) Make sure both codec and HDA controller are runtime suspended.
> 2) Runtime resume the HDA controller without runtime resume the codec.
> 3) Plug a headset and see if the system can detect anything.
>
> With the fix applied, we can see azx_interrupt() is working again by
> using ftrace.
>
> [Regression Potential]
> If there's any system that is not affected by this issue, runtime-resume
> the HDA controller will take a slightly longer time. It's rather
> unlikely, since _all_ systems with Realtek codec we tested have this
> issue, regardless of AMD or Intel.
>
> Kai Vehmanen (1):
>   UBUNTU: SAUCE: ALSA: hda: fix jack detection with Realtek codecs when
>     in D3
>
> Takashi Iwai (2):
>   ALSA: hda: Skip controller resume if not needed
>   ALSA: hda: Always use jackpoll helper for jack update after resume
>
>  include/sound/hda_codec.h     |  6 ++++++
>  sound/pci/hda/hda_codec.c     | 28 +++++++++++++++-----------
>  sound/pci/hda/hda_intel.c     | 37 ++++++++++++++++++++---------------
>  sound/pci/hda/patch_realtek.c |  1 +
>  4 files changed, 45 insertions(+), 27 deletions(-)
>
Acked-by: Stefan Bader <[hidden email]>


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

ACK/Cmnt: [F/G/Unstable/OEM-5.6] [PATCH 3/3] UBUNTU: SAUCE: ALSA: hda: fix jack detection with Realtek codecs when in D3

Andrea Righi
In reply to this post by Kai-Heng Feng
On Tue, Oct 13, 2020 at 03:53:55PM +0800, Kai-Heng Feng wrote:

> From: Kai Vehmanen <[hidden email]>
>
> BugLink: https://bugs.launchpad.net/bugs/1899586
>
> In case HDA controller becomes active, but codec is runtime suspended,
> jack detection is not successful and no interrupt is raised. This has
> been observed with multiple Realtek codecs and HDA controllers from
> different vendors. Bug does not occur if both codec and controller are
> active, or both are in suspend. Bug can be easily hit on desktop systems
> with no built-in speaker.
>
> The problem can be fixed by powering up the codec once after every
> controller runtime resume. Even if codec goes back to suspend later, the
> jack detection will continue to work. Add a flag to 'hda_codec' to
> describe codecs that require this flow from the controller driver.
> Modify __azx_runtime_resume() to use pm_request_resume() to make the
> intent clearer.
>
> Mark all Realtek codecs with the new forced_resume flag.
>
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=209379
> Cc: Kailang Yang <[hidden email]>
> Co-developed-by: Kai-Heng Feng <[hidden email]>
> Signed-off-by: Kai-Heng Feng <[hidden email]>
> Signed-off-by: Kai Vehmanen <[hidden email]>
> Cc: <[hidden email]>
> Link: https://lore.kernel.org/r/20201012102704.794423-1-kai.vehmanen@...
> Signed-off-by: Takashi Iwai <[hidden email]>
> (cherry picked from commit a6e7d0a4bdb02a7a3ffe0b44aaa8842b7efdd056 git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git master)

It looks like this one landed also in -next, so we can probably replace
the git URI with "linux-next" when this patch is applied.

Apart than that, looks good to me:

Acked-by: Andrea Righi <[hidden email]>

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

APPLIED G: [F/G/Unstable/OEM-5.6] [PATCH 3/3] UBUNTU: SAUCE: ALSA: hda: fix jack detection with Realtek codecs when in D3

Andrea Righi
In reply to this post by Kai-Heng Feng
On Tue, Oct 13, 2020 at 03:53:55PM +0800, Kai-Heng Feng wrote:

> From: Kai Vehmanen <[hidden email]>
>
> BugLink: https://bugs.launchpad.net/bugs/1899586
>
> In case HDA controller becomes active, but codec is runtime suspended,
> jack detection is not successful and no interrupt is raised. This has
> been observed with multiple Realtek codecs and HDA controllers from
> different vendors. Bug does not occur if both codec and controller are
> active, or both are in suspend. Bug can be easily hit on desktop systems
> with no built-in speaker.
>
> The problem can be fixed by powering up the codec once after every
> controller runtime resume. Even if codec goes back to suspend later, the
> jack detection will continue to work. Add a flag to 'hda_codec' to
> describe codecs that require this flow from the controller driver.
> Modify __azx_runtime_resume() to use pm_request_resume() to make the
> intent clearer.
>
> Mark all Realtek codecs with the new forced_resume flag.
>
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=209379
> Cc: Kailang Yang <[hidden email]>
> Co-developed-by: Kai-Heng Feng <[hidden email]>
> Signed-off-by: Kai-Heng Feng <[hidden email]>
> Signed-off-by: Kai Vehmanen <[hidden email]>
> Cc: <[hidden email]>
> Link: https://lore.kernel.org/r/20201012102704.794423-1-kai.vehmanen@...
> Signed-off-by: Takashi Iwai <[hidden email]>
> (cherry picked from commit a6e7d0a4bdb02a7a3ffe0b44aaa8842b7efdd056 git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git master)
> Signed-off-by: Kai-Heng Feng <[hidden email]>
> ---
>  include/sound/hda_codec.h     |  1 +
>  sound/pci/hda/hda_intel.c     | 14 ++++++++------
>  sound/pci/hda/patch_realtek.c |  1 +
>  3 files changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
> index 225154a4f2ed..b4d112e40ae7 100644
> --- a/include/sound/hda_codec.h
> +++ b/include/sound/hda_codec.h
> @@ -253,6 +253,7 @@ struct hda_codec {
>   unsigned int force_pin_prefix:1; /* Add location prefix */
>   unsigned int link_down_at_suspend:1; /* link down at runtime suspend */
>   unsigned int relaxed_resume:1; /* don't resume forcibly for jack */
> + unsigned int forced_resume:1; /* forced resume for jack */
>   unsigned int mst_no_extra_pcms:1; /* no backup PCMs for DP-MST */
>  
>  #ifdef CONFIG_PM
> diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
> index 35c7d5bad1bc..16c66aa4d381 100644
> --- a/sound/pci/hda/hda_intel.c
> +++ b/sound/pci/hda/hda_intel.c
> @@ -1002,12 +1002,14 @@ static void __azx_runtime_resume(struct azx *chip, bool from_rt)
>   azx_init_pci(chip);
>   hda_intel_init_chip(chip, true);
>  
> - if (status && from_rt) {
> - list_for_each_codec(codec, &chip->bus)
> - if (!codec->relaxed_resume &&
> -    (status & (1 << codec->addr)))
> - schedule_delayed_work(&codec->jackpoll_work,
> -      codec->jackpoll_interval);
> + if (from_rt) {
> + list_for_each_codec(codec, &chip->bus) {
> + if (codec->relaxed_resume)
> + continue;
> +
> + if (codec->forced_resume || (status & (1 << codec->addr)))
> + pm_request_resume(hda_codec_dev(codec));
> + }
>   }
>  
>   /* power down again for link-controlled chips */
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index b44219859d82..9b635ae01b6c 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -1150,6 +1150,7 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
>   codec->single_adc_amp = 1;
>   /* FIXME: do we need this for all Realtek codec models? */
>   codec->spdif_status_reset = 1;
> + codec->forced_resume = 1;
>   codec->patch_ops = alc_patch_ops;
>  
>   err = alc_codec_rename_from_preset(codec);
> --
> 2.17.1
>
>
> --
> kernel-team mailing list
> [hidden email]
> https://lists.ubuntu.com/mailman/listinfo/kernel-team

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

APPLIED [OEM-5.6] Re: [RESEND] [SRU] [F/G/Unstable/OEM-5.6] [PATCH 0/3] Fix broken MSI interrupt after HDA controller was suspended

Timo Aaltonen-6
In reply to this post by Kai-Heng Feng
On 13.10.2020 10.53, Kai-Heng Feng wrote:

> BugLink: https://bugs.launchpad.net/bugs/1899586
>
> [Impact]
> After HDA controller gets suspended and resumed, no MSI interrupt raised
> when plugging headset to the audio jack.
>
> [Fix]
> Power up the Realtek codec when HDA controller runtime resumes.
>
> [Test]
> 1) Make sure both codec and HDA controller are runtime suspended.
> 2) Runtime resume the HDA controller without runtime resume the codec.
> 3) Plug a headset and see if the system can detect anything.
>
> With the fix applied, we can see azx_interrupt() is working again by
> using ftrace.
>
> [Regression Potential]
> If there's any system that is not affected by this issue, runtime-resume
> the HDA controller will take a slightly longer time. It's rather
> unlikely, since _all_ systems with Realtek codec we tested have this
> issue, regardless of AMD or Intel.
>
> Kai Vehmanen (1):
>    UBUNTU: SAUCE: ALSA: hda: fix jack detection with Realtek codecs when
>      in D3
>
> Takashi Iwai (2):
>    ALSA: hda: Skip controller resume if not needed
>    ALSA: hda: Always use jackpoll helper for jack update after resume
>
>   include/sound/hda_codec.h     |  6 ++++++
>   sound/pci/hda/hda_codec.c     | 28 +++++++++++++++-----------
>   sound/pci/hda/hda_intel.c     | 37 ++++++++++++++++++++---------------
>   sound/pci/hda/patch_realtek.c |  1 +
>   4 files changed, 45 insertions(+), 27 deletions(-)
>

applied to oem-5.6, thanks


--
t

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team