summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_codec.c21
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_intel.c19
3 files changed, 20 insertions, 22 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 1b35115f7195..90b34e830415 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -98,9 +98,15 @@ EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
static void hda_power_work(struct work_struct *work);
static void hda_keep_power_on(struct hda_codec *codec);
#define hda_codec_is_power_on(codec) ((codec)->power_on)
+static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
+{
+ if (bus->ops.pm_notify)
+ bus->ops.pm_notify(bus, power_up);
+}
#else
static inline void hda_keep_power_on(struct hda_codec *codec) {}
#define hda_codec_is_power_on(codec) 1
+#define hda_call_pm_notify(bus, state) {}
#endif
/**
@@ -1199,6 +1205,10 @@ static void snd_hda_codec_free(struct hda_codec *codec)
codec->bus->caddr_tbl[codec->addr] = NULL;
if (codec->patch_ops.free)
codec->patch_ops.free(codec);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (codec->power_on)
+ hda_call_pm_notify(codec->bus, false);
+#endif
module_put(codec->owner);
free_hda_cache(&codec->amp_cache);
free_hda_cache(&codec->cmd_cache);
@@ -1271,6 +1281,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
* phase.
*/
hda_keep_power_on(codec);
+ hda_call_pm_notify(bus, true);
#endif
if (codec->bus->modelname) {
@@ -3576,7 +3587,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
- if ((power_state == AC_PWRST_D3)
+ if (!codec->bus->power_keep_link_on && power_state == AC_PWRST_D3
&& codec->d3_stop_clk && (state & AC_PWRST_CLK_STOP_OK))
codec->d3_stop_clk_ok = 1;
#endif
@@ -4430,8 +4441,8 @@ static void hda_power_work(struct work_struct *work)
spin_unlock(&codec->power_lock);
hda_call_codec_suspend(codec);
- if (bus->ops.pm_notify)
- bus->ops.pm_notify(bus, codec);
+ if (codec->d3_stop_clk_ok)
+ hda_call_pm_notify(bus, false);
}
static void hda_keep_power_on(struct hda_codec *codec)
@@ -4488,8 +4499,8 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
codec->power_transition = 1; /* avoid reentrance */
spin_unlock(&codec->power_lock);
- if (bus->ops.pm_notify)
- bus->ops.pm_notify(bus, codec);
+ if (codec->d3_stop_clk_ok) /* flag set at suspend */
+ hda_call_pm_notify(bus, true);
hda_call_codec_resume(codec);
spin_lock(&codec->power_lock);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 72477ccb20f9..2e5a22fec0be 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -616,7 +616,7 @@ struct hda_bus_ops {
void (*bus_reset)(struct hda_bus *bus);
#ifdef CONFIG_SND_HDA_POWER_SAVE
/* notify power-up/down from codec to controller */
- void (*pm_notify)(struct hda_bus *bus, struct hda_codec *codec);
+ void (*pm_notify)(struct hda_bus *bus, bool power_up);
#endif
};
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 1c9c779dda55..1b6e856e7ab1 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1033,7 +1033,7 @@ static unsigned int azx_get_response(struct hda_bus *bus,
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void azx_power_notify(struct hda_bus *bus, struct hda_codec *codec);
+static void azx_power_notify(struct hda_bus *bus, bool power_up);
#endif
/* reset codec link */
@@ -2406,14 +2406,11 @@ static void azx_stop_chip(struct azx *chip)
#ifdef CONFIG_SND_HDA_POWER_SAVE
/* power-up/down the controller */
-static void azx_power_notify(struct hda_bus *bus, struct hda_codec *codec)
+static void azx_power_notify(struct hda_bus *bus, bool power_up)
{
struct azx *chip = bus->private_data;
- if (bus->power_keep_link_on || !codec->d3_stop_clk_ok)
- return;
-
- if (codec->power_on)
+ if (power_up)
pm_runtime_get_sync(&chip->pci->dev);
else
pm_runtime_put_sync(&chip->pci->dev);
@@ -3273,15 +3270,6 @@ static void azx_firmware_cb(const struct firmware *fw, void *context)
}
#endif
-static void rpm_get_all_codecs(struct azx *chip)
-{
- struct hda_codec *codec;
-
- list_for_each_entry(codec, &chip->bus->codec_list, list) {
- pm_runtime_get_noresume(&chip->pci->dev);
- }
-}
-
static int __devinit azx_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
@@ -3388,7 +3376,6 @@ static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip)
goto out_free;
chip->running = 1;
- rpm_get_all_codecs(chip); /* all codecs are active */
power_down_all_codecs(chip);
azx_notifier_register(chip);
azx_add_card_list(chip);