diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 41ca803a1fff..7504e62188d6 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4393,20 +4393,19 @@ void snd_hda_update_power_acct(struct hda_codec *codec) codec->power_jiffies += delta; } -/** - * snd_hda_power_up - Power-up the codec - * @codec: HD-audio codec - * - * Increment the power-up counter and power up the hardware really when - * not turned on yet. - */ -void snd_hda_power_up(struct hda_codec *codec) +/* Transition to powered up, if wait_power_down then wait for a pending + * transition to D3 to complete. A pending D3 transition is indicated + * with power_transition == -1. */ +static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) { struct hda_bus *bus = codec->bus; spin_lock(&codec->power_lock); codec->power_count++; - if (codec->power_on || codec->power_transition > 0) { + /* Return if power_on or transitioning to power_on, unless currently + * powering down. */ + if ((codec->power_on || codec->power_transition > 0) && + !(wait_power_down && codec->power_transition < 0)) { spin_unlock(&codec->power_lock); return; } @@ -4430,8 +4429,37 @@ void snd_hda_power_up(struct hda_codec *codec) codec->power_transition = 0; spin_unlock(&codec->power_lock); } + +/** + * snd_hda_power_up - Power-up the codec + * @codec: HD-audio codec + * + * Increment the power-up counter and power up the hardware really when + * not turned on yet. + */ +void snd_hda_power_up(struct hda_codec *codec) +{ + __snd_hda_power_up(codec, false); +} EXPORT_SYMBOL_HDA(snd_hda_power_up); +/** + * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending + * D3 transition to complete. This differs from snd_hda_power_up() when + * power_transition == -1. snd_hda_power_up sees this case as a nop, + * snd_hda_power_up_d3wait waits for the D3 transition to complete then powers + * back up. + * @codec: HD-audio codec + * + * Cancel any power down operation hapenning on the work queue, then power up. + */ +void snd_hda_power_up_d3wait(struct hda_codec *codec) +{ + /* This will cancel and wait for pending power_work to complete. */ + __snd_hda_power_up(codec, true); +} +EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait); + #define power_save(codec) \ ((codec)->bus->power_save ? *(codec)->bus->power_save : 0) |