Skip to content

Commit 8d6762a

Browse files
committed
ALSA: hda: Always use jackpoll helper for jack update after resume
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: c4c8dd6 ("ALSA: hda: Skip controller resume if not needed") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 7fbdcd8 commit 8d6762a

File tree

2 files changed

+19
-26
lines changed

2 files changed

+19
-26
lines changed

sound/pci/hda/hda_codec.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -641,8 +641,18 @@ static void hda_jackpoll_work(struct work_struct *work)
641641
struct hda_codec *codec =
642642
container_of(work, struct hda_codec, jackpoll_work.work);
643643

644-
snd_hda_jack_set_dirty_all(codec);
645-
snd_hda_jack_poll_all(codec);
644+
/* for non-polling trigger: we need nothing if already powered on */
645+
if (!codec->jackpoll_interval && snd_hdac_is_power_on(&codec->core))
646+
return;
647+
648+
/* the power-up/down sequence triggers the runtime resume */
649+
snd_hda_power_up_pm(codec);
650+
/* update jacks manually if polling is required, too */
651+
if (codec->jackpoll_interval) {
652+
snd_hda_jack_set_dirty_all(codec);
653+
snd_hda_jack_poll_all(codec);
654+
}
655+
snd_hda_power_down_pm(codec);
646656

647657
if (!codec->jackpoll_interval)
648658
return;
@@ -2951,18 +2961,14 @@ static int hda_codec_runtime_resume(struct device *dev)
29512961
static int hda_codec_force_resume(struct device *dev)
29522962
{
29532963
struct hda_codec *codec = dev_to_hda_codec(dev);
2954-
bool forced_resume = hda_codec_need_resume(codec);
29552964
int ret;
29562965

2957-
/* The get/put pair below enforces the runtime resume even if the
2958-
* device hasn't been used at suspend time. This trick is needed to
2959-
* update the jack state change during the sleep.
2960-
*/
2961-
if (forced_resume)
2962-
pm_runtime_get_noresume(dev);
29632966
ret = pm_runtime_force_resume(dev);
2964-
if (forced_resume)
2965-
pm_runtime_put(dev);
2967+
/* schedule jackpoll work for jack detection update */
2968+
if (codec->jackpoll_interval ||
2969+
(pm_runtime_suspended(dev) && hda_codec_need_resume(codec)))
2970+
schedule_delayed_work(&codec->jackpoll_work,
2971+
codec->jackpoll_interval);
29662972
return ret;
29672973
}
29682974

sound/pci/hda/hda_intel.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,8 @@ static void __azx_runtime_resume(struct azx *chip, bool from_rt)
10041004

10051005
if (status && from_rt) {
10061006
list_for_each_codec(codec, &chip->bus)
1007-
if (status & (1 << codec->addr))
1007+
if (!codec->relaxed_resume &&
1008+
(status & (1 << codec->addr)))
10081009
schedule_delayed_work(&codec->jackpoll_work,
10091010
codec->jackpoll_interval);
10101011
}
@@ -1044,9 +1045,7 @@ static int azx_suspend(struct device *dev)
10441045
static int azx_resume(struct device *dev)
10451046
{
10461047
struct snd_card *card = dev_get_drvdata(dev);
1047-
struct hda_codec *codec;
10481048
struct azx *chip;
1049-
bool forced_resume = false;
10501049

10511050
if (!azx_is_pm_ready(card))
10521051
return 0;
@@ -1058,19 +1057,7 @@ static int azx_resume(struct device *dev)
10581057
if (azx_acquire_irq(chip, 1) < 0)
10591058
return -EIO;
10601059

1061-
/* check for the forced resume */
1062-
list_for_each_codec(codec, &chip->bus) {
1063-
if (hda_codec_need_resume(codec)) {
1064-
forced_resume = true;
1065-
break;
1066-
}
1067-
}
1068-
1069-
if (forced_resume)
1070-
pm_runtime_get_noresume(dev);
10711060
pm_runtime_force_resume(dev);
1072-
if (forced_resume)
1073-
pm_runtime_put(dev);
10741061
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
10751062

10761063
trace_azx_resume(chip);

0 commit comments

Comments
 (0)