Skip to content

Commit 215a22e

Browse files
khfengtiwai
authored andcommitted
ALSA: hda: Refactor codec PM to use direct-complete optimization
Upon system resume, hda_codec_pm_resume() uses hda_codec_force_resume() to resume the codec. However, pm_runtime_force_resume() won't really resume the codec because of pm_runtime_need_not_resume() check. Hence, hda_codec_force_resume() schedules a jackpoll work, which is to really power up the codec. Instead of doing that, we can use direct-complete to make the PM flow more straightforward, and keep codec always suspended through system PM flow if conditions are met. On system suspend, PM core will decide what to do based on hda_codec_pm_prepare(): - If codec is not runtime-suspended, PM core will suspend and resume the device as normal. - If codec is runtime-suspended, PM core will try to keep it suspended. If it's still suspended after system resume, we use hda_codec_pm_complete() to resume codec if it's needed. Signed-off-by: Kai-Heng Feng <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 8a8de09 commit 215a22e

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

sound/pci/hda/hda_codec.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2934,7 +2934,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
29342934
snd_hdac_leave_pm(&codec->core);
29352935
}
29362936

2937-
static int hda_codec_runtime_suspend(struct device *dev)
2937+
static int hda_codec_suspend(struct device *dev)
29382938
{
29392939
struct hda_codec *codec = dev_to_hda_codec(dev);
29402940
unsigned int state;
@@ -2953,7 +2953,7 @@ static int hda_codec_runtime_suspend(struct device *dev)
29532953
return 0;
29542954
}
29552955

2956-
static int hda_codec_runtime_resume(struct device *dev)
2956+
static int hda_codec_resume(struct device *dev)
29572957
{
29582958
struct hda_codec *codec = dev_to_hda_codec(dev);
29592959

@@ -2967,57 +2967,70 @@ static int hda_codec_runtime_resume(struct device *dev)
29672967
pm_runtime_mark_last_busy(dev);
29682968
return 0;
29692969
}
2970+
2971+
static int hda_codec_runtime_suspend(struct device *dev)
2972+
{
2973+
return hda_codec_suspend(dev);
2974+
}
2975+
2976+
static int hda_codec_runtime_resume(struct device *dev)
2977+
{
2978+
return hda_codec_resume(dev);
2979+
}
2980+
29702981
#endif /* CONFIG_PM */
29712982

29722983
#ifdef CONFIG_PM_SLEEP
2973-
static int hda_codec_force_resume(struct device *dev)
2984+
static int hda_codec_pm_prepare(struct device *dev)
2985+
{
2986+
return pm_runtime_suspended(dev);
2987+
}
2988+
2989+
static void hda_codec_pm_complete(struct device *dev)
29742990
{
29752991
struct hda_codec *codec = dev_to_hda_codec(dev);
2976-
int ret;
29772992

2978-
ret = pm_runtime_force_resume(dev);
2979-
/* schedule jackpoll work for jack detection update */
2980-
if (codec->jackpoll_interval ||
2981-
(pm_runtime_suspended(dev) && hda_codec_need_resume(codec)))
2982-
schedule_delayed_work(&codec->jackpoll_work,
2983-
codec->jackpoll_interval);
2984-
return ret;
2993+
if (pm_runtime_suspended(dev) && (codec->jackpoll_interval ||
2994+
hda_codec_need_resume(codec) || codec->forced_resume))
2995+
pm_request_resume(dev);
29852996
}
29862997

29872998
static int hda_codec_pm_suspend(struct device *dev)
29882999
{
29893000
dev->power.power_state = PMSG_SUSPEND;
2990-
return pm_runtime_force_suspend(dev);
3001+
return hda_codec_suspend(dev);
29913002
}
29923003

29933004
static int hda_codec_pm_resume(struct device *dev)
29943005
{
29953006
dev->power.power_state = PMSG_RESUME;
2996-
return hda_codec_force_resume(dev);
3007+
return hda_codec_resume(dev);
29973008
}
29983009

29993010
static int hda_codec_pm_freeze(struct device *dev)
30003011
{
30013012
dev->power.power_state = PMSG_FREEZE;
3002-
return pm_runtime_force_suspend(dev);
3013+
return hda_codec_suspend(dev);
30033014
}
30043015

30053016
static int hda_codec_pm_thaw(struct device *dev)
30063017
{
30073018
dev->power.power_state = PMSG_THAW;
3008-
return hda_codec_force_resume(dev);
3019+
return hda_codec_resume(dev);
30093020
}
30103021

30113022
static int hda_codec_pm_restore(struct device *dev)
30123023
{
30133024
dev->power.power_state = PMSG_RESTORE;
3014-
return hda_codec_force_resume(dev);
3025+
return hda_codec_resume(dev);
30153026
}
30163027
#endif /* CONFIG_PM_SLEEP */
30173028

30183029
/* referred in hda_bind.c */
30193030
const struct dev_pm_ops hda_codec_driver_pm = {
30203031
#ifdef CONFIG_PM_SLEEP
3032+
.prepare = hda_codec_pm_prepare,
3033+
.complete = hda_codec_pm_complete,
30213034
.suspend = hda_codec_pm_suspend,
30223035
.resume = hda_codec_pm_resume,
30233036
.freeze = hda_codec_pm_freeze,

0 commit comments

Comments
 (0)