Running Linux 2.6 and Fedora Core 2 / 3 on the IBM ThinkPad T41
Alex Fedosov

[ overview ] [ video ] [ frequency scaling ] [ suspend ] [ ACPI ] [ TV out ] [ other ]

Configuring ACPI events and actions
The biggest initial problem with ACPI was that you can't use the Fn-F* keys to suspend or hibernate the ThinkPad. In addition, closing the lid has no effect (despite being configured in BIOS to suspend the latpop.) Naturally, all of the above works fine with APM.

Turns out, mostly everything can be made with work with ACPI as well by the means of ACPI daemon (acpid) that listens for ACPI events from the kernel and triggers appropriate actions. The trouble is, by default, the ACPI daemon is not set up to do anything in FC2, besides shutting down the computer. To fix that, you simply create a config file for each event specifying which action should be taken. These config files live under /etc/acpi/events and only need to contain two things: a string beginning with event= specifying the event, and a string beginning with action= specifying which action to take in response to that event. For example, pressing the power button triggers the 'button/power' event, and if we wanted to shut down the computer in response to it, (in fact, this is the behavior of the only provided config file in /etc/acpi/events) we would say:
event=button[ /]power
action=/sbin/shutdown -h now
in /etc/acpi/events/powerbutton.conf (or any file name in that directory.)
That's it. Now your computer will automatically shut down when you press the power button. Admittedly, this is boring and not very useful because most people rarely shut down their laptops, suspending to disk instead. So why not have the power button perform a suspend to disk? (With swsusp, this is done via echo 4 > /proc/acpi/sleep. Because echo is a bash primitive rather than a separate executable, we can't just specify it as the action, we have to create a small bash script instead. So our event config would look something like this:
event=button[ /]power
action=/etc/acpi/actions/powerbutton.sh
And the powerbutton.sh script would contain:
#!/bin/sh
echo 4 > /proc/acpi/sleep
Now restart acpid, press the power button, and hopefully watch your laptop suspend to disk.

Another useful thing to do is suspend to RAM when either Fn-F4 is pressed or the lid is closed. Those two things generate the 'button/sleep' and 'button/lid' events, respectively. So you can have a /etc/acpi/events/lid.conf:
event=button[ /]lid
action=/etc/acpi/actions/sleep.sh
and/or /etc/acpi/events/sleep.conf:
event=button[ /]sleep
action=/etc/acpi/actions/sleep.sh
And in the sleep.sh action script:
#!/bin/sh
rmmod ehci_hcd
echo mem > /sys/power/state
modprobe ehci_hcd
Note: USB 2.0 driver, ehci_hcd, when loaded, prevents the laptop from going into suspend. Thus we unload it before going into suspend, and reload it afterwards.

Now, here is a tricky part: to come back from suspend you need to press the power button, but since Linux will already be in memory at that point, the power button press will emit an ACPI 'button/power' event and thus trigger a suspend to disk. The easiest fix is, of course, not to assign any action to the power button. But if you want to use the power button anyway, your script has to somehow know to ignore the power button press when coming back from suspend. In the UNIX tradition, we'll just use a file, the existence of which will indicate the fact we are simply coming back from suspend to RAM, not trying to suspend to disk. So, in sleep.sh (or whatever your suspend to RAM script is):
#!/bin/sh
touch /tmp/suspended
rmmod ehci_hcd
echo mem > /sys/power/state
modprobe ehci_hcd
Then in the powerbutton.sh we test for the presence of the file, and if it does not exist, do the suspend to disk, otherwise do nothing and remove the file:
#!/bin/sh
if [ ! -f /tmp/suspended] ; then
	hwclock --systohc
	echo 4 > /proc/acpi/sleep
	hwclock --hctosys
else
	rm -f /tmp/suspended
fi
Note: to keep the system clock sane, it's a good idea to add the synchronizations before and after suspend to disk.

Known problems: Credit where it's due: a lot of these ideas are taken from Alexander Wagner's T41p page and Florian Weimer's T40p page.

You can download a tarball of my /etc/acpi/ directory if you don't want to type all this stuff in.




Last modified Monday December 13, 2004
Alex Fedosov
Department of Computer Science, University of San Francisco