aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c21
1 files changed, 16 insertions, 5 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);
98static void hda_power_work(struct work_struct *work); 98static void hda_power_work(struct work_struct *work);
99static void hda_keep_power_on(struct hda_codec *codec); 99static void hda_keep_power_on(struct hda_codec *codec);
100#define hda_codec_is_power_on(codec) ((codec)->power_on) 100#define hda_codec_is_power_on(codec) ((codec)->power_on)
101static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
102{
103 if (bus->ops.pm_notify)
104 bus->ops.pm_notify(bus, power_up);
105}
101#else 106#else
102static inline void hda_keep_power_on(struct hda_codec *codec) {} 107static inline void hda_keep_power_on(struct hda_codec *codec) {}
103#define hda_codec_is_power_on(codec) 1 108#define hda_codec_is_power_on(codec) 1
109#define hda_call_pm_notify(bus, state) {}
104#endif 110#endif
105 111
106/** 112/**
@@ -1199,6 +1205,10 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1199 codec->bus->caddr_tbl[codec->addr] = NULL; 1205 codec->bus->caddr_tbl[codec->addr] = NULL;
1200 if (codec->patch_ops.free) 1206 if (codec->patch_ops.free)
1201 codec->patch_ops.free(codec); 1207 codec->patch_ops.free(codec);
1208#ifdef CONFIG_SND_HDA_POWER_SAVE
1209 if (codec->power_on)
1210 hda_call_pm_notify(codec->bus, false);
1211#endif
1202 module_put(codec->owner); 1212 module_put(codec->owner);
1203 free_hda_cache(&codec->amp_cache); 1213 free_hda_cache(&codec->amp_cache);
1204 free_hda_cache(&codec->cmd_cache); 1214 free_hda_cache(&codec->cmd_cache);
@@ -1271,6 +1281,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1271 * phase. 1281 * phase.
1272 */ 1282 */
1273 hda_keep_power_on(codec); 1283 hda_keep_power_on(codec);
1284 hda_call_pm_notify(bus, true);
1274#endif 1285#endif
1275 1286
1276 if (codec->bus->modelname) { 1287 if (codec->bus->modelname) {
@@ -3576,7 +3587,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3576 } 3587 }
3577 3588
3578#ifdef CONFIG_SND_HDA_POWER_SAVE 3589#ifdef CONFIG_SND_HDA_POWER_SAVE
3579 if ((power_state == AC_PWRST_D3) 3590 if (!codec->bus->power_keep_link_on && power_state == AC_PWRST_D3
3580 && codec->d3_stop_clk && (state & AC_PWRST_CLK_STOP_OK)) 3591 && codec->d3_stop_clk && (state & AC_PWRST_CLK_STOP_OK))
3581 codec->d3_stop_clk_ok = 1; 3592 codec->d3_stop_clk_ok = 1;
3582#endif 3593#endif
@@ -4430,8 +4441,8 @@ static void hda_power_work(struct work_struct *work)
4430 spin_unlock(&codec->power_lock); 4441 spin_unlock(&codec->power_lock);
4431 4442
4432 hda_call_codec_suspend(codec); 4443 hda_call_codec_suspend(codec);
4433 if (bus->ops.pm_notify) 4444 if (codec->d3_stop_clk_ok)
4434 bus->ops.pm_notify(bus, codec); 4445 hda_call_pm_notify(bus, false);
4435} 4446}
4436 4447
4437static void hda_keep_power_on(struct hda_codec *codec) 4448static 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)
4488 codec->power_transition = 1; /* avoid reentrance */ 4499 codec->power_transition = 1; /* avoid reentrance */
4489 spin_unlock(&codec->power_lock); 4500 spin_unlock(&codec->power_lock);
4490 4501
4491 if (bus->ops.pm_notify) 4502 if (codec->d3_stop_clk_ok) /* flag set at suspend */
4492 bus->ops.pm_notify(bus, codec); 4503 hda_call_pm_notify(bus, true);
4493 hda_call_codec_resume(codec); 4504 hda_call_codec_resume(codec);
4494 4505
4495 spin_lock(&codec->power_lock); 4506 spin_lock(&codec->power_lock);