Here is a patch to deal with PM events (e.g. button presses) in a
system independent way. Could people with the applicable hardware test
out or comment on the changes?
The files affected are
arch/i386/kernel/apm.c
arch/mips/sgi/kernel/reset.c
arch/mips64/sgi-ip22/ip22-reset.c
arch/sparc64/kernel/power.c
drivers/acpi/driver.c
drivers/char/nwbutton.c
drivers/char/nwbutton.h
There are many power management and button press drivers in the
kernel. They all tend to have their own interface to distribute events
to userspace. This is bad, because it means duplicated code, and
requires arch specific userspace whatnots, which should not be
necessary.
Specifically, at the moment, the following approaches are taken by
various subsystems:
- launch /sbin/shutdown
- signal init
- do nothing
And there 3 or so different special devices that userspace can read to
see events. After this patch there are only 2 that I know of (ACPI and
/dev/boxevent, perhaps the ACPI stuff could also be removed, I didn't
look).
The patch converts the PM drivers I found to use a single
interface. (Only APM is tested because nobody has given me e.g. a
SPARC box: i.e. the patch is just a suggestion.)
The kernel interface is very simple. Each driver just does
#include <linux/boxevent.h>
void button_interrupt() {
boxevent(BUTTONEVENT_OFF,"TurboSnail","button pressed");
}
and the event is exported to any number of userspace listeners on
/dev/boxevent. Thereby writing a new power button driver does not
involve having to deal with all the baggage of device nodes, etc.
You can create /dev/boxevent with mknod boxevent c 10 137
You can see what events occur simply by "cat"ing it to the console.
The format is very simple.
<event> <WS> <subsystem> <WS> <description> <LF>
Where <event> is one of the strings OFF,SLEEP,WAKE,EMERGENCY,NOTIFY
(if a reader does not read events quickly enough, it will get a
MSGFLOOD event), <WS> is a space character, <subsystem> is a word
denoting the kernel pm interface responsible for generating the event,
<description> is an arbitrary string. <LF> is a newline character \n.
This is flexible. It means a reasonable default behaviour can be
suggested by the kernel (OFF,SLEEP,etc.) for events that userspace
doesn't know about, but userspace can choose fine grained policy and
provide helpful error messages based on the exact event name by
checking the description.
In fact, here is the "daemon" I use
#! /bin/perl
use Sys::Syslog qw(:DEFAULT setlogsock);
sub do_off {
system("/sbin/shutdown -p now");
exit(0);
}
sub do_overflow {
setlogsock("unix");
openlog("boxd","cons","daemon");
syslog('err',"messages arriving too fast");
closelog();
}
while(<>){
if(/MSGFLOOD/) {
do_overflow();
next
}
if(/^SLEEP APM user suspend/){
do_off();
next
}
if(/^OFF/){
do_off();
next
}
}
The patch against 2.4.4 is attached.