Skip to content

Commit b5a236c

Browse files
jason77-wangtiwai
authored andcommitted
ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec
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: cc72da7 ("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>
1 parent 744c67f commit b5a236c

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

sound/pci/hda/hda_codec.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,6 +2939,20 @@ static int hda_codec_runtime_resume(struct device *dev)
29392939
#endif /* CONFIG_PM */
29402940

29412941
#ifdef CONFIG_PM_SLEEP
2942+
static int hda_codec_force_resume(struct device *dev)
2943+
{
2944+
int ret;
2945+
2946+
/* The get/put pair below enforces the runtime resume even if the
2947+
* device hasn't been used at suspend time. This trick is needed to
2948+
* update the jack state change during the sleep.
2949+
*/
2950+
pm_runtime_get_noresume(dev);
2951+
ret = pm_runtime_force_resume(dev);
2952+
pm_runtime_put(dev);
2953+
return ret;
2954+
}
2955+
29422956
static int hda_codec_pm_suspend(struct device *dev)
29432957
{
29442958
dev->power.power_state = PMSG_SUSPEND;
@@ -2948,7 +2962,7 @@ static int hda_codec_pm_suspend(struct device *dev)
29482962
static int hda_codec_pm_resume(struct device *dev)
29492963
{
29502964
dev->power.power_state = PMSG_RESUME;
2951-
return pm_runtime_force_resume(dev);
2965+
return hda_codec_force_resume(dev);
29522966
}
29532967

29542968
static int hda_codec_pm_freeze(struct device *dev)
@@ -2960,13 +2974,13 @@ static int hda_codec_pm_freeze(struct device *dev)
29602974
static int hda_codec_pm_thaw(struct device *dev)
29612975
{
29622976
dev->power.power_state = PMSG_THAW;
2963-
return pm_runtime_force_resume(dev);
2977+
return hda_codec_force_resume(dev);
29642978
}
29652979

29662980
static int hda_codec_pm_restore(struct device *dev)
29672981
{
29682982
dev->power.power_state = PMSG_RESTORE;
2969-
return pm_runtime_force_resume(dev);
2983+
return hda_codec_force_resume(dev);
29702984
}
29712985
#endif /* CONFIG_PM_SLEEP */
29722986

0 commit comments

Comments
 (0)