Ubuntu

Comment 63 for bug 1093217

Here is a possible workaround.

After reading up some on ACPI, I decided it was that the system got stuck in the BIOSs’ ACPI code. This is what the error message showed and I also came to the (possibly wrong) conclusion that this error was there all along and other kernel changes actually fixed something else that made async accesses to the ACPI functions “proper”. But for us Z580 users it created the long delay waiting for the AML interpreter to determine that the BIOS was hung.

So I got the iasl tool, decompiled, changed and recompiled the DSDT, then used grub to load the changed version before loading the kernel. It worked and now there is no delay with this workaround.

The change I made was in DSDT method WAEC (wait on embedded controller?). Here is the method along with the one line fix:

        Method (WAEC, 0, NotSerialized)
        {
            Name (CUNT, 0x1E)
            While (LNotEqual (^PCI0.LPCB.EC0.BYFG, Zero))
            {
                Sleep (0x05)
                Decrement (CUNT)
                If (LEqual (CUNT, Zero))
                {
                    Store (Zero, ^PCI0.LPCB.EC0.BYFG)
                    Store (Zero, ^PCI0.LPCB.EC0.DRFG)
                    Break
                }
            }
            Sleep (50) // #### adding this line is the only change ####
        }

When getting battery info, this method is used 3 times. It is called just before commanding the EC to return a different piece of battery info. Since battery info is fetched twice for some reason, this only adds about 300 milliseconds (a lot better than 20 minutes).

Here are the approximate steps I used:

Install the ASL compiler iasl (apt-get install iasl I think).

Make a copy of /sys/firmware/acpi/tables/DSDT

isal -d DSDT to decompile to DSDT.dsl

[Compile to aml and you see two differences, the version number of the compiler is different]

Edit the change into DSDT.dsl

iasl DSDT.dsl to produce DSDT.aml

sudo cp DSDT.aml /boot/.

Reboot and enter ‘c’ at the grub menu, then enter “acpi /boot/DSDT.aml”, then escape and boot (I am using 3.2.0-38-generic).

Then I edited /boot/grub/grub.cfg and put the acpi command in there. An approach that works even with upgrades is described by Michael Kuron at http://blog.michael.kuron-germany.de/2011/03/patching-dsdt-in-recent-linux-kernels-without-recompiling/

I just guessed on where to put the delay. I thought it must be a race or timing issue and I planned to shotgun delays everywhere, but got lucky and the first one worked. Someone else may be able to determine if there is a better fix.

By the way, you can confirm the DSDT is loaded from the line in dmesg:
[ 0.000000] ACPI: DSDT 00000000d82bc1f0 0AD5B (v02 LENOVO IVB-CPT 00000000 INTL 20100528)
The original has 20061109 I think.

Another thing I tried that did NOT help the problem was adding acpi_serialize to kernel boot options.