From 09787492537462e3c7b8f67b30ff9704062f97cc Mon Sep 17 00:00:00 2001 From: Abhijeet Kumar Date: Tue, 23 Jan 2018 23:00:51 +0530 Subject: [PATCH 1/2] ALSA: hda: Copying sync power state helper to core The current sync_power_state is local to hda code, moving it core so that other users apart from hda legacy can use it. The helper function ensures the actual state reaches the target state. Signed-off-by: Abhijeet Kumar Signed-off-by: Takashi Iwai --- include/sound/hdaudio.h | 2 ++ sound/hda/hdac_device.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 68169e3749de1..4c93ff5301bd2 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -146,6 +146,8 @@ int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid, int flags, unsigned int verb, unsigned int parm); bool snd_hdac_check_power_state(struct hdac_device *hdac, hda_nid_t nid, unsigned int target_state); +unsigned int snd_hdac_sync_power_state(struct hdac_device *hdac, + hda_nid_t nid, unsigned int target_state); /** * snd_hdac_read_parm - read a codec parameter * @codec: the codec object diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index 06f845e293cb2..7ba100bb1c3fc 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -1064,3 +1065,37 @@ bool snd_hdac_check_power_state(struct hdac_device *hdac, return (state == target_state); } EXPORT_SYMBOL_GPL(snd_hdac_check_power_state); +/** + * snd_hdac_sync_power_state - wait until actual power state matches + * with the target state + * + * @hdac: the HDAC device + * @nid: NID to send the command + * @target_state: target state to check for + * + * Return power state or PS_ERROR if codec rejects GET verb. + */ +unsigned int snd_hdac_sync_power_state(struct hdac_device *codec, + hda_nid_t nid, unsigned int power_state) +{ + unsigned long end_time = jiffies + msecs_to_jiffies(500); + unsigned int state, actual_state, count; + + for (count = 0; count < 500; count++) { + state = snd_hdac_codec_read(codec, nid, 0, + AC_VERB_GET_POWER_STATE, 0); + if (state & AC_PWRST_ERROR) { + msleep(20); + break; + } + actual_state = (state >> 4) & 0x0f; + if (actual_state == power_state) + break; + if (time_after_eq(jiffies, end_time)) + break; + /* wait until the codec reachs to the target state */ + msleep(1); + } + return state; +} +EXPORT_SYMBOL_GPL(snd_hdac_sync_power_state); From 3b5b899ca67db07a4c4825911072221f99e157e2 Mon Sep 17 00:00:00 2001 From: Abhijeet Kumar Date: Tue, 23 Jan 2018 23:00:52 +0530 Subject: [PATCH 2/2] ALSA: hda: Make use of core codec functions to sync power state Since sync_power_state is moved to core it's better to use the helper function to ensure the actual power state reaches target instead of using the local helper functions already exsisting in hda code. Signed-off-by: Abhijeet Kumar Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 28 +--------------------------- sound/pci/hda/hda_local.h | 6 +++++- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e018ecbf78a8f..5bc3a7468e171 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2702,32 +2702,6 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, } EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all); -/* - * wait until the state is reached, returns the current state - */ -static unsigned int hda_sync_power_state(struct hda_codec *codec, - hda_nid_t fg, - unsigned int power_state) -{ - unsigned long end_time = jiffies + msecs_to_jiffies(500); - unsigned int state, actual_state; - - for (;;) { - state = snd_hda_codec_read(codec, fg, 0, - AC_VERB_GET_POWER_STATE, 0); - if (state & AC_PWRST_ERROR) - break; - actual_state = (state >> 4) & 0x0f; - if (actual_state == power_state) - break; - if (time_after_eq(jiffies, end_time)) - break; - /* wait until the codec reachs to the target state */ - msleep(1); - } - return state; -} - /** * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD * @codec: the HDA codec @@ -2790,7 +2764,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, state); snd_hda_codec_set_power_to_all(codec, fg, power_state); } - state = hda_sync_power_state(codec, fg, power_state); + state = snd_hda_sync_power_state(codec, fg, power_state); if (!(state & AC_PWRST_ERROR)) break; } diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 5b5c324c99b9d..321e78baa63ca 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -622,7 +622,11 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid, { return snd_hdac_check_power_state(&codec->core, nid, target_state); } - +static inline bool snd_hda_sync_power_state(struct hda_codec *codec, + hda_nid_t nid, unsigned int target_state) +{ + return snd_hdac_sync_power_state(&codec->core, nid, target_state); +} unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, hda_nid_t nid, unsigned int power_state);