Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c376e2c7 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Implement snd_hda_power_sync() helper function



Added a new helper function snd_hda_power_sync() to trigger the
power-saving manually.  It's an inline function call to
snd_hda_power_save() helper function.

Together with this addition, snd_hda_power_up*() and
snd_hda_power_down() functions are inlined to a call of the same
snd_hda_power_save() helper function.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b244d335
Loading
Loading
Loading
Loading
+28 −54
Original line number Original line Diff line number Diff line
@@ -4411,20 +4411,16 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
/* Transition to powered up, if wait_power_down then wait for a pending
/* Transition to powered up, if wait_power_down then wait for a pending
 * transition to D3 to complete. A pending D3 transition is indicated
 * transition to D3 to complete. A pending D3 transition is indicated
 * with power_transition == -1. */
 * with power_transition == -1. */
/* call this with codec->power_lock held! */
static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
{
{
	struct hda_bus *bus = codec->bus;
	struct hda_bus *bus = codec->bus;


	spin_lock(&codec->power_lock);
	codec->power_count++;
	trace_hda_power_count(codec);
	/* Return if power_on or transitioning to power_on, unless currently
	/* Return if power_on or transitioning to power_on, unless currently
	 * powering down. */
	 * powering down. */
	if ((codec->power_on || codec->power_transition > 0) &&
	if ((codec->power_on || codec->power_transition > 0) &&
	    !(wait_power_down && codec->power_transition < 0)) {
	    !(wait_power_down && codec->power_transition < 0))
		spin_unlock(&codec->power_lock);
		return;
		return;
	}
	spin_unlock(&codec->power_lock);
	spin_unlock(&codec->power_lock);


	cancel_delayed_work_sync(&codec->power_work);
	cancel_delayed_work_sync(&codec->power_work);
@@ -4433,10 +4429,9 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
	/* If the power down delayed work was cancelled above before starting,
	/* If the power down delayed work was cancelled above before starting,
	 * then there is no need to go through power up here.
	 * then there is no need to go through power up here.
	 */
	 */
	if (codec->power_on) {
	if (codec->power_on)
		spin_unlock(&codec->power_lock);
		return;
		return;
	}

	trace_hda_power_up(codec);
	trace_hda_power_up(codec);
	snd_hda_update_power_acct(codec);
	snd_hda_update_power_acct(codec);
	codec->power_on = 1;
	codec->power_on = 1;
@@ -4450,66 +4445,45 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)


	spin_lock(&codec->power_lock);
	spin_lock(&codec->power_lock);
	codec->power_transition = 0;
	codec->power_transition = 0;
	spin_unlock(&codec->power_lock);
}
}


/**
#define power_save(codec)	\
 * snd_hda_power_up - Power-up the codec
	((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
 * @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);


/**
/* Transition to powered down */
 * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
static void __snd_hda_power_down(struct hda_codec *codec)
 *   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. */
	if (!codec->power_on || codec->power_count || codec->power_transition)
	__snd_hda_power_up(codec, true);
		return;
}
EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait);


#define power_save(codec)	\
	if (power_save(codec)) {
	((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
		codec->power_transition = -1; /* avoid reentrance */
		queue_delayed_work(codec->bus->workq, &codec->power_work,
				msecs_to_jiffies(power_save(codec) * 1000));
	}
}


/**
/**
 * snd_hda_power_down - Power-down the codec
 * snd_hda_power_save - Power-up/down/sync the codec
 * @codec: HD-audio codec
 * @codec: HD-audio codec
 * @delta: the counter delta to change
 *
 *
 * Decrement the power-up counter and schedules the power-off work if
 * Change the power-up counter via @delta, and power up or down the hardware
 * the counter rearches to zero.
 * appropriately.  For the power-down, queue to the delayed action.
 * Passing zero to @delta means to synchronize the power state.
 */
 */
void snd_hda_power_down(struct hda_codec *codec)
void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait)
{
{
	spin_lock(&codec->power_lock);
	spin_lock(&codec->power_lock);
	--codec->power_count;
	codec->power_count += delta;
	trace_hda_power_count(codec);
	trace_hda_power_count(codec);
	if (!codec->power_on || codec->power_count || codec->power_transition) {
	if (delta > 0)
		spin_unlock(&codec->power_lock);
		__snd_hda_power_up(codec, d3wait);
		return;
	else
	}
		__snd_hda_power_down(codec);
	if (power_save(codec)) {
		codec->power_transition = -1; /* avoid reentrance */
		queue_delayed_work(codec->bus->workq, &codec->power_work,
				msecs_to_jiffies(power_save(codec) * 1000));
	}
	spin_unlock(&codec->power_lock);
	spin_unlock(&codec->power_lock);
}
}
EXPORT_SYMBOL_HDA(snd_hda_power_down);
EXPORT_SYMBOL_HDA(snd_hda_power_save);


/**
/**
 * snd_hda_check_amp_list_power - Check the amp list and update the power
 * snd_hda_check_amp_list_power - Check the amp list and update the power
+54 −6
Original line number Original line Diff line number Diff line
@@ -1062,16 +1062,64 @@ const char *snd_hda_get_jack_location(u32 cfg);
 * power saving
 * power saving
 */
 */
#ifdef CONFIG_SND_HDA_POWER_SAVE
#ifdef CONFIG_SND_HDA_POWER_SAVE
void snd_hda_power_up(struct hda_codec *codec);
void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait);
void snd_hda_power_up_d3wait(struct hda_codec *codec);
void snd_hda_power_down(struct hda_codec *codec);
void snd_hda_update_power_acct(struct hda_codec *codec);
void snd_hda_update_power_acct(struct hda_codec *codec);
#else
#else
static inline void snd_hda_power_up(struct hda_codec *codec) {}
static inline void snd_hda_power_save(struct hda_codec *codec, int delta,
static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {}
				      bool d3wait) {}
static inline void snd_hda_power_down(struct hda_codec *codec) {}
#endif
#endif


/**
 * 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.
 */
static inline void snd_hda_power_up(struct hda_codec *codec)
{
	snd_hda_power_save(codec, 1, false);
}

/**
 * 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.
 */
static inline void snd_hda_power_up_d3wait(struct hda_codec *codec)
{
	snd_hda_power_save(codec, 1, true);
}

/**
 * snd_hda_power_down - Power-down the codec
 * @codec: HD-audio codec
 *
 * Decrement the power-up counter and schedules the power-off work if
 * the counter rearches to zero.
 */
static inline void snd_hda_power_down(struct hda_codec *codec)
{
	snd_hda_power_save(codec, -1, false);
}

/**
 * snd_hda_power_sync - Synchronize the power-save status
 * @codec: HD-audio codec
 *
 * Synchronize the actual power state with the power account;
 * called when power_save parameter is changed
 */
static inline void snd_hda_power_sync(struct hda_codec *codec)
{
	snd_hda_power_save(codec, 0, false);
}

#ifdef CONFIG_SND_HDA_PATCH_LOADER
#ifdef CONFIG_SND_HDA_PATCH_LOADER
/*
/*
 * patch firmware
 * patch firmware