[alsa-devel] Broken powersave in 3.5.2, codec is always active
Hello! I have a Lenovo ThinkPad X220 laptop with a conexant codec and recently (after kernel 3.5.2) it is active all the time after KDE login, as powertop says. This couldn't be fixed by logging of from KDE or playing some music in mplayer from console. The only kernel I tried in 3.5.x is 3.5.2, so I can't say is this bug reproducible in 3.5.0 or 3.5.1, but everything is fine with 3.4.9. This never happens if you don't start KDE after reboot, you can listen to some music in mplayer in console and everything seems to be fine. lsof and fuser /dev/snd/* shows nothing. Thank you!
$ cat /etc/modprobe.d/options.conf options snd-hda-intel power_save=1 power_save_controller=1
$ lspci -nn | grep Audio 00:1b.0 Audio device [0403]: Intel Corporation 6 Series/C200 Series Chipset Family High Definition Audio Controller [8086:1c20] (rev 04)
$ lsmod | grep snd snd_hda_codec_hdmi 23704 1 snd_hda_codec_conexant 47158 1 snd_hda_intel 25700 2 snd_hda_codec 97400 3 snd_hda_codec_hdmi,snd_hda_codec_conexant,snd_hda_intel snd_hwdep 6300 1 snd_hda_codec snd_pcm 74926 3 snd_hda_codec_hdmi,snd_hda_codec,snd_hda_intel snd_page_alloc 7185 2 snd_pcm,snd_hda_intel snd_timer 18966 1 snd_pcm snd 60021 12 snd_hwdep,snd_timer,snd_hda_codec_hdmi,snd_hda_codec_conexant,snd_pcm,snd_hda_codec,snd_hda_intel,thinkpad_acpi soundcore 5442 1 snd
At Sat, 18 Aug 2012 12:44:29 +0700, ValdikSS wrote:
Hello! I have a Lenovo ThinkPad X220 laptop with a conexant codec and recently (after kernel 3.5.2) it is active all the time after KDE login, as powertop says. This couldn't be fixed by logging of from KDE or playing some music in mplayer from console. The only kernel I tried in 3.5.x is 3.5.2, so I can't say is this bug reproducible in 3.5.0 or 3.5.1, but everything is fine with 3.4.9. This never happens if you don't start KDE after reboot, you can listen to some music in mplayer in console and everything seems to be fine. lsof and fuser /dev/snd/* shows nothing.
Just to be sure, check /sys/module/snd_hda_intel/parameters/power_save value after logging into KDE. This value can be changed dynamically.
If the value is still set properly, try to build the kernel with the tracing option with the patch below. Then try to trace the power up/down sequences in the tracing buffer. Some brief description is found in Documentation/sound/alsa/HD-Audio.txt Tracepoints section.
thanks,
Takashi
--- From: Takashi Iwai tiwai@suse.de Subject: [PATCH] ALSA: hda - Add tracepoints at snd_hda_power_up/down entrances.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_codec.c | 2 ++ sound/pci/hda/hda_trace.h | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 408babc..ad0101e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4417,6 +4417,7 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
spin_lock(&codec->power_lock); codec->power_count++; + trace_hda_power_count(codec); /* Return if power_on or transitioning to power_on, unless currently * powering down. */ if ((codec->power_on || codec->power_transition > 0) && @@ -4496,6 +4497,7 @@ void snd_hda_power_down(struct hda_codec *codec) { spin_lock(&codec->power_lock); --codec->power_count; + trace_hda_power_count(codec); if (!codec->power_on || codec->power_count || codec->power_transition) { spin_unlock(&codec->power_lock); return; diff --git a/sound/pci/hda/hda_trace.h b/sound/pci/hda/hda_trace.h index 9884871..9a34b86 100644 --- a/sound/pci/hda/hda_trace.h +++ b/sound/pci/hda/hda_trace.h @@ -87,6 +87,30 @@ DEFINE_EVENT(hda_power, hda_power_up, TP_ARGS(codec) );
+TRACE_EVENT(hda_power_count, + TP_PROTO(struct hda_codec *codec), + TP_ARGS(codec), + TP_STRUCT__entry( + __field( unsigned int, card ) + __field( unsigned int, addr ) + __field( int, power_count ) + __field( int, power_on ) + __field( int, power_transition ) + ), + + TP_fast_assign( + __entry->card = (codec)->bus->card->number; + __entry->addr = (codec)->addr; + __entry->power_count = (codec)->power_count; + __entry->power_on = (codec)->power_on; + __entry->power_transition = (codec)->power_transition; + ), + + TP_printk("[%d:%d] power_count=%d, power_on=%d, power_transition=%d", + __entry->card, __entry->addr, __entry->power_count, + __entry->power_on, __entry->power_transition) +); + TRACE_EVENT(hda_unsol_event,
TP_PROTO(struct hda_bus *bus, u32 res, u32 res_ex),
participants (2)
-
Takashi Iwai
-
ValdikSS