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 41ca803a1ff..7504e62188d 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)  |