My laptop has broken lid close behaviour, when I close the lid, the
screen stays on. When I open the lid, the screen turns off at a low lid
angle and then at a higher angle it turns back on.
With Windows XP it always turns back on at the higher angle. With Linux
it only turns on if I open the lid very slowly. I only just discovered
that workaround while gathering the data for this bug. This behaviour
happens in Xorg and on virtual consoles, even if I boot in single user
mode and X has not started.
When the screen is off in Linux, the system is still available, I can
SSH in or blindly hit Ctrl+Alt+F1 to login as root. If I suspend and
resume afterwards, the screen turns back on.
Now that I found a way to ensure the screen gets turned on (slowly open
the lid), this isn't a huge issue, but it would be nice if Linux could
turn off the screen on lid close and turn it on again on lid open. The
first issue causes the laptop to heat up a lot. The second issue
requires me to remember to only open the laptop slowly and is a delay.
I don't remember when this problem was introduced, I think it happened
back in 2007 when I bought this laptop, since I remember having some
trouble with it at DebConf7. Definitely reproducible with 2.6.32 from
squeeze, 2.6.36 and 2.6.37 rc4 from experimental.
After cloning the upstream intel-gpu-tools repo I noticed that the
intel_lid program sometimes reports inconsistencies between SWF14 and
the ACPI lid state. So I figure it must be some sort of ACPI issue and
include acpidump output in the attached debug info.
I've been using the A14 revision of my BIOS for most of the laptop's
life but recently upgraded to A17. This update had no effect on the
behaviour of the laptop. The laptop is a Dell Inspiron 6400.
I wrote a short script and a patch for intel_lid to gather some debug
info, thanks to jcristau for the pointers. Output tarball attached for
Linux 2.6.32, 2.6.36 and 2.6.37 rc4.
I'll forward this bug upstream after I get the bug number from the BTS.
#!/bin/bash
rm -rf log
mkdir log
export PATH="~pabs/tmp/intel-gpu-tools/tools/:$PATH"
acpidump --binary --output log/acpidump-"$(date --utc --rfc-3339=ns)"
dmesg > log/dmesg-before-"$(date --utc --rfc-3339=ns)"
intel_lid > log/lid-"$(date --utc --rfc-3339=ns)" &
intel_reg_dumper > log/reg-dump-before-lid-close-"$(date --utc --rfc-3339=ns)"
sleep 1s
intel_reg_dumper > log/reg-dump-before-lid-close-"$(date --utc --rfc-3339=ns)"
sleep 1s
read -p 'Please press enter then close the lid, wait for 15s then open it and wait for suspend' foo
i=0
while [ $((i++)) -ne 40 ] ; do
sleep 1s
intel_reg_dumper > log/reg-dump-during-loop-"$(date --utc --rfc-3339=ns)"
done
pm-suspend
intel_reg_dumper > log/reg-dump-post-suspend-"$(date --utc --rfc-3339=ns)"
sleep 1s
intel_reg_dumper > log/reg-dump-post-suspend-"$(date --utc --rfc-3339=ns)"
dmesg > log/dmesg-after-"$(date --utc --rfc-3339=ns)"
kill %1
tar zcf debug.tar.gz debug.bash log
rm -rf log
diff --git a/tools/intel_lid.c b/tools/intel_lid.c
index 908224e..10d1732 100644
--- a/tools/intel_lid.c
+++ b/tools/intel_lid.c
@@ -36,6 +36,7 @@
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#include "intel_gpu_tools.h"
#include "intel_reg.h"
@@ -115,6 +116,7 @@ out:
int main(int argc, char **argv)
{
+ time_t t;
int swf14, acpi_lid;
intel_get_mmio(intel_get_pci_device());
@@ -122,7 +124,8 @@ int main(int argc, char **argv)
while (1) {
swf14 = INREG(SWF14);
- printf("Intel LVDS Lid status:\n");
+ t = time(NULL);
+ printf("Intel LVDS Lid status at %s", asctime(gmtime(&t)));
printf("\tSWF14(0x%x) : %s\n", swf14,
swf14 & SWF14_LID_SWITCH_EN ? "close" : "open");
@@ -138,7 +141,7 @@ int main(int argc, char **argv)
printf("\tACPI Lid state : close\n");
break;
}
- sleep(2);
+ sleep(1);
}
return 0;
}