I guess the first question would be does your machine have ACPI support? This can be done with either APM or ACPI support but I am using ACPI. Check to see if you have anything under "/proc/acpi" directory. Do you have a file called "sleep"? What's in it?
- Code: Select all
$ cat /proc/acpi/sleep
If yours just shows a line "S0 S3 S4 S5" then I'm guessing you can at least make your system attempt to suspend to RAM and suspend to DISK (assuming you have support built in to your kernel for it. Suspend to
disk is not currently compiled in on default Fedora kernels but suspend to RAM should work with the default). To make your system suspend all you really have to do is:
- Code: Select all
# echo -n 3 > /proc/acpi/sleep
The above signals your machine to suspend to RAM. Use "4" instead of "3" to suspend to disk. Now, before you do this there are some things you might have to do before suspending, like stop unsuspendable processes, update your system clock etc. Likewise there are some things that need to be done after coming out of suspend mode like syncing the system clock to the hardware clock, starting those processes back up that you stopped before going into a suspend (I found MySQL is not suspendable and needs to be stopped before suspending).
You should have no problem suspending to RAM, suspending to disk is a little trickier and there are a few things you should know before doing it (like how to start your system if something goes wrong and it gets into a loop trying to unsuspend when starting your system).
Now, those things I mention that should be done prior to and after a suspend can easily be added to a script (I will show you my scripts at the end of this). You also don't want to have to manually run this script but you want to be able to just press your suspend button and have it automatically execute your script. This is what "acpid" is for. On Fedora systems there is a service called "acpid" (oddly enough). On Fedora systems this daemon logs to /var/log/acpid. Check this log for ACPI events (including special FN key presses).
If your special FN key combos show up in the acpid log then you can create configuration files for those keys and tell them what script to execute. Here is what I have under /etc/acpi:
http://voidmain.is-a-geek.net/files/configs/acpi/There are two directories under /etc/acpi, "actions" and "events". Under the "events" directory is where you place your function key config files. A very simple one on mine is "lid.conf". The name of the file is not significant (other than for me to remember what I created it for). This is the configuration file for what I want to happen when I close the lid on my laptop. Notice the first line:
- Code: Select all
event=button/lid.*
This correlates to the event you will see in your /var/log/acpid file. It will match an event that starts with "button/lid" (the ".*" means any text can follow it (it's a regular expression)). I came up with this because when I close my lid I get this in my acpid log file:
- Code: Select all
[Tue Feb 15 19:25:30 2005] received event "button/lid LID 00000080 00000002"
The "event" is everything in quotes so "button/lid.*" would match that event. Ok, now that we have caught the event we need to do something. That's the second line in the "lid.conf". In my case I want it to execute the "lid.sh":
- Code: Select all
action=/etc/acpi/actions/lid.sh
My lid.sh:
- Code: Select all
#!/bin/sh
# Just turn off LCD to save a little power
if radeontool light | grep -q "looks off"; then radeontool light on; else radeontool light off; fi
In my case I don't want it to suspend when I close the lid, I just want it to turn off the display. You might not need this one because normally laptops turn their displays off when you close the lid already. Mine actually shuts off the display too but not completely power it off so I use a command called "radeontool" to do this.
This is a little different than what happens when you suspend though because the script executes completely to the end when I close the lid. When you suspend your suspend script executes up to the point where you "echo -n 3 > /proc/acpi/sleep" and executes the rest of the script when you wake it up. So, to suspend to RAM (FN+F4 on my system) I have a configuration file that looks like this:
FNF4.conf
- Code: Select all
# With IBM Hotkeys enabled FN+F4
event=ibm/hotkey HKEY 00000080 00001004
action=/etc/acpi/actions/sleep.sh
The above event shows up in my log when I press "FN+F4". When I press "FN+F5" the exact same event is genereated except there is a "5" at the end instead of a "4". So I press FN+F4 and acpid executes my "sleep.sh". Hopefully it's fairly self explanitory:
- Code: Select all
#!/bin/sh
radeontool light off
# Stop mysqld if it is running because you can't suspend it
pgrep mysqld > /tmp/mysqld.dat && /sbin/service mysqld stop
# Stop VMware if running
pgrep vmware > /tmp/vmware.dat && /sbin/service vmware stop
if lsmod | grep '^usbhid' >/dev/null ; then
/sbin/modprobe -r -s usbhid
fi
if lsmod | grep '^uhci_hcd' >/dev/null ; then
/sbin/modprobe -r -s uhci_hcd
fi
if lsmod | grep '^ehci_hcd' >/dev/null ; then
/sbin/modprobe -r -s ehci_hcd
fi
# Stop network
/sbin/service network stop
logger "Fn+F4 Suspending to RAM"
sync
hwclock --systohc
# Go to powersave (suspend to RAM)
echo -n 3 >/proc/acpi/sleep
# We're back!
hwclock --hctosys
# Start network
/sbin/service network start
if !(lsmod | grep '^ehci_hcd') >/dev/null ; then
/sbin/modprobe -s ehci_hcd
fi
if !(lsmod | grep '^uhci_hcd') >/dev/null ; then
/sbin/modprobe -s uhci_hcd
fi
if !(lsmod | grep '^usbhid') >/dev/null ; then
/sbin/modprobe -s usbhid
fi
if [ -s /tmp/mysqld.dat ]; then
/sbin/service mysqld start
fi
if [ -s /tmp/vmware.dat ]; then
/sbin/service vmware start
fi
logger "Resuming from Fn+F4 Suspending to RAM"
radeontool light on
This script might just work for you (take out the radeontool if you don't have a radeon video card). You can tweak things as necessary in this script if you find other things that prevent suspending.
I think my suspend to disk script is identical except I use the "4" instead of "3" as mentioned before. In order to suspend to disk you need to have that capability compiled into the kernel as I mentioned. If you do then it will use your SWAP partition to write it's suspend data to and then power off. When you turn the power back on it loads itself from that info.
I currently have a problem where I can't use "dri" (direct rendering) with Xorg and also have the ability to come back out of a suspend without corrupting my video. This is not acceptable to me so I just stick with the suspend to RAM or shut down completely. I have seen people talk about this problem and I believe I can patch Xorg so it will suspend with dri loaded but it's not worth the effort for me. I figure they'll eventually get it right.
So as you can see by my "events" directory I am turning off the display by either closing the lid or pressing FN+F3, suspending to RAM using FN+F4, suspending to disk using FN+F12, shuts down cleanly with the power button. This is a little bit IBM specific because I turned on extra functionality using the "ibm_acpi" kernel module rather than the normal acpi kernel module. This gives me a directory full of IBM specific items called /proc/acpi/ibm. To turn on the extra IBM function keys I added this to the end of my /etc/rc.d/rc.local startup script:
- Code: Select all
# Turn on thinkpad function keys
echo enable > /proc/acpi/ibm/hotkey
# Enable all FN keys (F3,F4,F5,F7,F8,F9,F12)
echo 0xffff > /proc/acpi/ibm/hotkey
Also note that my FN+F4 event will probably show up differently than yours. What you will have when you press your sleep button is an event that looks something like this in your acpid log:
- Code: Select all
[Sat Feb 12 15:14:45 2005] received event "button/sleep SLPB 00000080 00000001"
In fact that's exactly what I get when I don't enable the extended IBM keys in my rc.local. So basically press the keys and see what shows up in your log. Use that for your "event". You'll see a "sleepbutton.conf" file in my events directory that I was using prior to turning on the extended IBM keys.
Hopefully this will get you going. You'll find lots of other events that you might want to get creative with like what to do when your power cable is plugged in or unplugged, when your processor changes stepping, etc.. I may have been a little verbose but I figure I can just clean this post up a little and turn it into a HOWTO without a lot of changes. Will see if you have any luck following it.
You might look around under your acpi directory and find other cool files. You won't have this file but I have one called /proc/acpi/ibm/light. My laptop has a little nightlight built in to the top of the LCD that can be turned on with a function key. Well, I thought it would be cool if I could just click on an icon on my panel right under the light to turn it on and off (since the light won't be on finding the key to turn it on might be difficult). Anyway, catting the "light" file reveals this:
- Code: Select all
status: off
commands: on, off
It's nice enough to tell us what options we have so I notice that:
- Code: Select all
# echo on > /proc/acpi/ibm/light
turns the light on and amazingly enough this turns it off:
- Code: Select all
# echo off > /proc/acpi/ibm/light
Now you have to be root to write to this file so I had to figure out how to be able to turn it off and on without being root. There are a couple of ways this could have been done. One is with the "sudo" command but I decided to write a little C program and make it SUID root. Here's the C program:
http://voidmain.is-a-geek.net/files/source/light.c
Good luck!