aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c22
-rw-r--r--sound/pci/hda/hda_codec.h2
2 files changed, 16 insertions, 8 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e0f8667ae226..731f8500a23a 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2265,7 +2265,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2265 /* OK, let it free */ 2265 /* OK, let it free */
2266 2266
2267#ifdef CONFIG_SND_HDA_POWER_SAVE 2267#ifdef CONFIG_SND_HDA_POWER_SAVE
2268 cancel_delayed_work(&codec->power_work); 2268 cancel_delayed_work_sync(&codec->power_work);
2269 codec->power_on = 0; 2269 codec->power_on = 0;
2270 codec->power_transition = 0; 2270 codec->power_transition = 0;
2271 codec->power_jiffies = jiffies; 2271 codec->power_jiffies = jiffies;
@@ -3491,11 +3491,14 @@ static void hda_call_codec_suspend(struct hda_codec *codec)
3491 codec->afg ? codec->afg : codec->mfg, 3491 codec->afg ? codec->afg : codec->mfg,
3492 AC_PWRST_D3); 3492 AC_PWRST_D3);
3493#ifdef CONFIG_SND_HDA_POWER_SAVE 3493#ifdef CONFIG_SND_HDA_POWER_SAVE
3494 snd_hda_update_power_acct(codec);
3495 cancel_delayed_work(&codec->power_work); 3494 cancel_delayed_work(&codec->power_work);
3495 spin_lock(&codec->power_lock);
3496 snd_hda_update_power_acct(codec);
3497 trace_hda_power_down(codec);
3496 codec->power_on = 0; 3498 codec->power_on = 0;
3497 codec->power_transition = 0; 3499 codec->power_transition = 0;
3498 codec->power_jiffies = jiffies; 3500 codec->power_jiffies = jiffies;
3501 spin_unlock(&codec->power_lock);
3499#endif 3502#endif
3500} 3503}
3501 3504
@@ -4294,13 +4297,15 @@ static void hda_power_work(struct work_struct *work)
4294 struct hda_bus *bus = codec->bus; 4297 struct hda_bus *bus = codec->bus;
4295 4298
4296 spin_lock(&codec->power_lock); 4299 spin_lock(&codec->power_lock);
4300 if (codec->power_transition > 0) { /* during power-up sequence? */
4301 spin_unlock(&codec->power_lock);
4302 return;
4303 }
4297 if (!codec->power_on || codec->power_count) { 4304 if (!codec->power_on || codec->power_count) {
4298 codec->power_transition = 0; 4305 codec->power_transition = 0;
4299 spin_unlock(&codec->power_lock); 4306 spin_unlock(&codec->power_lock);
4300 return; 4307 return;
4301 } 4308 }
4302
4303 trace_hda_power_down(codec);
4304 spin_unlock(&codec->power_lock); 4309 spin_unlock(&codec->power_lock);
4305 4310
4306 hda_call_codec_suspend(codec); 4311 hda_call_codec_suspend(codec);
@@ -4341,11 +4346,15 @@ void snd_hda_power_up(struct hda_codec *codec)
4341 4346
4342 spin_lock(&codec->power_lock); 4347 spin_lock(&codec->power_lock);
4343 codec->power_count++; 4348 codec->power_count++;
4344 if (codec->power_on || codec->power_transition) { 4349 if (codec->power_on || codec->power_transition > 0) {
4345 spin_unlock(&codec->power_lock); 4350 spin_unlock(&codec->power_lock);
4346 return; 4351 return;
4347 } 4352 }
4353 spin_unlock(&codec->power_lock);
4348 4354
4355 cancel_delayed_work_sync(&codec->power_work);
4356
4357 spin_lock(&codec->power_lock);
4349 trace_hda_power_up(codec); 4358 trace_hda_power_up(codec);
4350 snd_hda_update_power_acct(codec); 4359 snd_hda_update_power_acct(codec);
4351 codec->power_on = 1; 4360 codec->power_on = 1;
@@ -4358,7 +4367,6 @@ void snd_hda_power_up(struct hda_codec *codec)
4358 hda_call_codec_resume(codec); 4367 hda_call_codec_resume(codec);
4359 4368
4360 spin_lock(&codec->power_lock); 4369 spin_lock(&codec->power_lock);
4361 cancel_delayed_work(&codec->power_work);
4362 codec->power_transition = 0; 4370 codec->power_transition = 0;
4363 spin_unlock(&codec->power_lock); 4371 spin_unlock(&codec->power_lock);
4364} 4372}
@@ -4383,7 +4391,7 @@ void snd_hda_power_down(struct hda_codec *codec)
4383 return; 4391 return;
4384 } 4392 }
4385 if (power_save(codec)) { 4393 if (power_save(codec)) {
4386 codec->power_transition = 1; /* avoid reentrance */ 4394 codec->power_transition = -1; /* avoid reentrance */
4387 queue_delayed_work(codec->bus->workq, &codec->power_work, 4395 queue_delayed_work(codec->bus->workq, &codec->power_work,
4388 msecs_to_jiffies(power_save(codec) * 1000)); 4396 msecs_to_jiffies(power_save(codec) * 1000));
4389 } 4397 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 78f89147d620..fce30b42bc46 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -859,7 +859,7 @@ struct hda_codec {
859 unsigned int no_jack_detect:1; /* Machine has no jack-detection */ 859 unsigned int no_jack_detect:1; /* Machine has no jack-detection */
860#ifdef CONFIG_SND_HDA_POWER_SAVE 860#ifdef CONFIG_SND_HDA_POWER_SAVE
861 unsigned int power_on :1; /* current (global) power-state */ 861 unsigned int power_on :1; /* current (global) power-state */
862 unsigned int power_transition :1; /* power-state in transition */ 862 int power_transition; /* power-state in transition */
863 int power_count; /* current (global) power refcount */ 863 int power_count; /* current (global) power refcount */
864 struct delayed_work power_work; /* delayed task for powerdown */ 864 struct delayed_work power_work; /* delayed task for powerdown */
865 unsigned long power_on_acct; 865 unsigned long power_on_acct;