summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-08-14 15:12:47 (GMT)
committerTakashi Iwai <tiwai@suse.de>2012-08-20 09:46:05 (GMT)
commitc376e2c72ba2d510486d7dea41163dce5f5606ea (patch)
tree6bf51453c5c9f54f1955ecb3330e576d357622d7 /sound
parentb244d335609f9bbf4c0204a365bf03b7ac53c3c8 (diff)
downloadlinux-fsl-qoriq-c376e2c72ba2d510486d7dea41163dce5f5606ea.tar.xz
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: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c82
-rw-r--r--sound/pci/hda/hda_codec.h60
2 files changed, 82 insertions, 60 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index ad0101e..5e0bdea 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -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 D3 to complete. A pending D3 transition is indicated
* 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)
{
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
* powering down. */
if ((codec->power_on || codec->power_transition > 0) &&
- !(wait_power_down && codec->power_transition < 0)) {
- spin_unlock(&codec->power_lock);
+ !(wait_power_down && codec->power_transition < 0))
return;
- }
spin_unlock(&codec->power_lock);
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,
* then there is no need to go through power up here.
*/
- if (codec->power_on) {
- spin_unlock(&codec->power_lock);
+ if (codec->power_on)
return;
- }
+
trace_hda_power_up(codec);
snd_hda_update_power_acct(codec);
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);
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);
+#define power_save(codec) \
+ ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
-/**
- * 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)
+/* Transition to powered down */
+static void __snd_hda_power_down(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);
+ if (!codec->power_on || codec->power_count || codec->power_transition)
+ return;
-#define power_save(codec) \
- ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
+ 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));
+ }
+}
/**
- * snd_hda_power_down - Power-down the codec
+ * snd_hda_power_save - Power-up/down/sync the codec
* @codec: HD-audio codec
+ * @delta: the counter delta to change
*
- * Decrement the power-up counter and schedules the power-off work if
- * the counter rearches to zero.
+ * Change the power-up counter via @delta, and power up or down the hardware
+ * 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);
- --codec->power_count;
+ codec->power_count += delta;
trace_hda_power_count(codec);
- if (!codec->power_on || codec->power_count || codec->power_transition) {
- spin_unlock(&codec->power_lock);
- return;
- }
- 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));
- }
+ if (delta > 0)
+ __snd_hda_power_up(codec, d3wait);
+ else
+ __snd_hda_power_down(codec);
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
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index d772c25..1d4dfce 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -1062,16 +1062,64 @@ const char *snd_hda_get_jack_location(u32 cfg);
* power saving
*/
#ifdef CONFIG_SND_HDA_POWER_SAVE
-void snd_hda_power_up(struct hda_codec *codec);
-void snd_hda_power_up_d3wait(struct hda_codec *codec);
-void snd_hda_power_down(struct hda_codec *codec);
+void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait);
void snd_hda_update_power_acct(struct hda_codec *codec);
#else
-static inline void snd_hda_power_up(struct hda_codec *codec) {}
-static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {}
-static inline void snd_hda_power_down(struct hda_codec *codec) {}
+static inline void snd_hda_power_save(struct hda_codec *codec, int delta,
+ bool d3wait) {}
#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
/*
* patch firmware