]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
[ALSA] hda-intel - Fix resume logic, when dynamic power managment is on
authorMaxim Levitsky <maximlevitsky@gmail.com>
Mon, 3 Sep 2007 13:28:04 +0000 (15:28 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 16 Oct 2007 13:59:47 +0000 (15:59 +0200)
Comment in hda_intel.c states that 'the explicit resume is needed only
when POWER_SAVE isn't set', but this is not true.
There is no code that will automaticly power up the codec on resume,
but only code that powers it up when user accesses it. So if user
leaves a sound playing, codec will not be powered
To fix that I check if there are any codecs that should be powered
codec->power_count, and if so I power them up together with main
controller.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_intel.c

index 08104e2a3e99a550cc3ddf8e120e3161a651093c..e594de0b153e90102b11939da29042b81e5e12a8 100644 (file)
@@ -2787,7 +2787,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
        return 0;
 }
 
-#ifndef CONFIG_SND_HDA_POWER_SAVE
 /**
  * snd_hda_resume - resume the codecs
  * @bus: the HDA bus
@@ -2803,10 +2802,21 @@ int snd_hda_resume(struct hda_bus *bus)
        struct hda_codec *codec;
 
        list_for_each_entry(codec, &bus->codec_list, list) {
-               hda_call_codec_resume(codec);
+               if (snd_hda_codec_needs_resume(codec))
+                       hda_call_codec_resume(codec);
        }
        return 0;
 }
-#endif /* !CONFIG_SND_HDA_POWER_SAVE */
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+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;
+}
+#endif
 #endif
index ca157e5100c9b00d3cb7fb92fa95a65bfd7ad5b5..2bce925d84ef5b0412f67320d65f732bd06e5aa7 100644 (file)
@@ -686,9 +686,13 @@ int snd_hda_resume(struct hda_bus *bus);
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 void snd_hda_power_up(struct hda_codec *codec);
 void snd_hda_power_down(struct hda_codec *codec);
+#define snd_hda_codec_needs_resume(codec) codec->power_count
+int snd_hda_codecs_inuse(struct hda_bus *bus);
 #else
 static inline void snd_hda_power_up(struct hda_codec *codec) {}
 static inline void snd_hda_power_down(struct hda_codec *codec) {}
+#define snd_hda_codec_needs_resume(codec) 1
+#define snd_hda_codecs_inuse(bus) 1
 #endif
 
 #endif /* __SOUND_HDA_CODEC_H */
index 3d06eccc9b9c0fda0c8ad658b638dfe1cb179de8..72fd345389948916fd4901ea2b5608e51fc9c519 100644 (file)
@@ -1586,11 +1586,11 @@ static int azx_resume(struct pci_dev *pci)
        if (azx_acquire_irq(chip, 1) < 0)
                return -EIO;
        azx_init_pci(chip);
-#ifndef CONFIG_SND_HDA_POWER_SAVE
-       /* the explicit resume is needed only when POWER_SAVE isn't set */
-       azx_init_chip(chip);
+
+       if (snd_hda_codecs_inuse(chip->bus))
+               azx_init_chip(chip);
+
        snd_hda_resume(chip->bus);
-#endif
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
        return 0;
 }