Created attachment 22408 [details] acpidump When the lid is closed on my Acer Aspire One (D150-1577), kacpid and kacpi_notify both make very active use of the CPU. I cannot find any evidence of a repeating lid event in my logs as suggested by similar problems had by others. Also, my DSDT appears to have the relevant clause to prevent this. This happens with 2.6.29 and 2.6.30 images from debian unstable, as well as with a home-compiled version of the 2.6.30.1 source release. I have the latest acpi packages from debian, and it was happening with slightly older kernels too. Also posted as a debian bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=536240 And notified kernel.org originally/incorrectly at: http://bugzilla.kernel.org/show_bug.cgi?id=13013
Created attachment 22409 [details] "grep . /sys/firmware/acpi/interrupts/*" with lid open
Created attachment 22410 [details] "grep . /sys/firmware/acpi/interrupts/*" with lid closed
Created attachment 22411 [details] customized DSDT: invert GPIO 0x0D correctly please apply this customized DSDT and see if it helps. one question: does "/proc/acpi/button/lid/LID0/state" always report the correct lid status on your laptop?
/proc/acpi/button/lid/LID0/state always reports closed, whether the lid is open or closed. But *something's* letting acpi know the lid's closed. I'll try the DSDT a little later and report on it.
Btw, what DSDT did you base this one on? I just worry that this DSDT will break other things. Wouldn't it be better to modify my current DSDT?
I think it is a safe assumption that Rui based the test on the acpidump in the 1st attachment of this report. When I compile the original, (likely with a different version of the compiler than Rui) the new one is only 45 bytes larger than the original. However, Rui, when you hack a DSDT, it would be helpful if you show the source diff in addition to providing the .hex -- since it is difficult to discover that source from the C .hex file. Jonathan, The lid state is different from the lid event. Lid state is discovered by evaluating the _LID method. On this box, _LID reads a hardware pin/register LPDL: Device (LID0) { Name (_HID, EisaId ("PNP0C0D")) Method (_LID, 0, NotSerialized) { Return (LPDL) } } OperationRegion (GPIO, SystemIO, 0x0500, 0x3C) Field (GPIO, ByteAcc, NoLock, Preserve) { Offset (0x2C), Offset (0x2D), , 1, INV9, 1, INVA, 1, , 18, LPDL, 1, Offset (0x38), , 1, , 1, CPEN, 1 } You could read the same address via inb(1) and get the same value. The GPE 1D is Method (_L1D, 0, NotSerialized) { Not (LPDL, LPDL) Notify (\_SB.LID0, 0x80) } Not() is an integer bitwise NOT -- so presumably writing the not of the current value on this hardware will clear the event source... Of course if there are every any garbage bits in LPDL, then Not(LPDL, LPDL) isn't going to work -- assuming that any bits in the byte would provoke an interrupt. Notify(0x80) just says that there is a lid event. Somebody has to read _LID to figure out what the state is -- or assume that lid events are in sequence open/closed/open/closed etc, which would be generally be a bad idea.
The DSDT did indeed make the problem go away, and it also seems to've made /proc report the right state of the lid. So this is a BIOS bug and not a kernel bug? If that's the case, then maybe the kernel should default to behaving differently when there's this particular BIOS bug? Having the kernel eat CPU cycles when the lid is closed (which uses power and makes the device get hot) seems not good, whether it's really the kernel's fault or not. I'm not sure how easy/possible this is for you guys to change, but that would be what I'd naïvely opt for. From a more self-serving and personal point-of-view: thanks for the quick response and work-around!
Though I see the following in dmesg: [ 779.985047] ACPI: EC: missing confirmations, switch off interrupt mode. [ 780.489074] ACPI Exception (evregion-0422): AE_TIME, Returned by Handler for [EmbeddedControl] [20090320] [ 780.489105] ACPI Error (psparse-0537): Method parse/execution failed [\_SB_.PCI0.LPC_.BAT0._BST] (Node f7036c84), AE_TIME [ 780.489255] ACPI Exception (battery-0385): AE_TIME, Evaluating _BST [20090320]
well, this is a BIOS bug. The lid GPE (0x1D) uses GPIO 0x0D. And we need to invert the GPI_INV register every time a lid event occurs. The DSDT tries to do this by "Not (LPDL, LPDL)" in _L1D method. but unfortunately the stupid BIOS doesn't set the correct bit of GPI_INV register, i.e. it inverts the GPIO 0x1D bit instead of 0x0D... here is the output of "diff -pNur DSDT.dsl DSDT-new.dsl". @@ -94,8 +94,9 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, , 1, INV9, 1, INVA, 1, - , 18, - LPDL, 1, + , 1, + , 1, + LPDL, 1, Offset (0x38), , 1, , 1,
Jonathan, this is a BIOS bug that we can not fix in Linux kernel. I think windows are also affected by this BIOS. IMO, a BIOS upgrade is worth trying. :)
Reply-To: jcapote@gmail.com I am also having this exact same bug on my Acer Aspire One. To answer your question, /proc/acpi/button/lid/LID0/state reports "closed" even though it is open... hope this helps -- Julio Capote