Revert "ALSA: hda - Set codec to D3 forcibly even if not used"
authorTakashi Iwai <tiwai@suse.de>
Tue, 8 May 2012 14:30:59 +0000 (16:30 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 8 May 2012 14:35:42 +0000 (16:35 +0200)
This reverts commit 785f857d1cb0856b612b46a0545b74aa2596e44a.

The commit causes a problem with the wrong D3 state after suspend
because the call of hda_set_power_state() involves with the power-up
sequence, which changes the power_count, and this confuses the resume
sequence that checks the power_count as well.

Originally, this go-to-D3 sequence should be a simple task without the
power-up sequence.  But, it'd need some proper sanity checks in the
case of power-saved state, so it's not too easy to write now in the
3.4-rc cycle.

In short, the safest option now is to revert this affecting commit.

Of course, we need to clean up and robustify the power-saving code
better for 3.5 kernel.

Reported-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c

index 7a8fcc4c15f84acf5baab4ec9301f35f84a75049..841475cc13b657a2627e107354e4b70251fb3296 100644 (file)
@@ -5444,10 +5444,6 @@ int snd_hda_suspend(struct hda_bus *bus)
        list_for_each_entry(codec, &bus->codec_list, list) {
                if (hda_codec_is_power_on(codec))
                        hda_call_codec_suspend(codec);
-               else /* forcibly change the power to D3 even if not used */
-                       hda_set_power_state(codec,
-                                           codec->afg ? codec->afg : codec->mfg,
-                                           AC_PWRST_D3);
                if (codec->patch_ops.post_suspend)
                        codec->patch_ops.post_suspend(codec);
        }
index c19e71a94e1bd5a792ff100cba817134bae04b12..6e958bf941915f3c2b8cb744e12a74a47896cfdf 100644 (file)
@@ -2351,6 +2351,17 @@ static void azx_power_notify(struct hda_bus *bus)
  * power management
  */
 
+static int snd_hda_codecs_inuse(struct hda_bus *bus)
+{
+       struct hda_codec *codec;
+
+       list_for_each_entry(codec, &bus->codec_list, list) {
+               if (snd_hda_codec_needs_resume(codec))
+                       return 1;
+       }
+       return 0;
+}
+
 static int azx_suspend(struct pci_dev *pci, pm_message_t state)
 {
        struct snd_card *card = pci_get_drvdata(pci);
@@ -2397,7 +2408,8 @@ static int azx_resume(struct pci_dev *pci)
                return -EIO;
        azx_init_pci(chip);
 
-       azx_init_chip(chip, 1);
+       if (snd_hda_codecs_inuse(chip->bus))
+               azx_init_chip(chip, 1);
 
        snd_hda_resume(chip->bus);
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);