Power Management Interface
OLPC Power Management (OLPC-PM) Kernel Interface
Suspend to RAM
We use the standard kernel interface to suspend to RAM (See http://acpi.sourceforge.net/documentation/sleep.html):
echo mem > /sys/power/state
Setting Wakeup Events
We can set the system to wake (resume) on a number of events:
- Power button
- RTC Alarm
- LID event (GPIO26)
- wake event from the EC (GPIO27)
We wish to be able to control which events will wake the system (since not all of the possible sources are desirable all the time). ACPI uses an interface like this (from my desktop):
> cat /proc/acpi/wakeup Device Sleep state Status PCI1 4 disabled USB0 4 disabled USB1 4 disabled UAR1 1 disabled UAR2 1 disabled GOLA 4 disabled GLAN 4 disabled GOLB 4 disabled SMBC 4 disabled AC97 4 disabled MODM 4 disabled PWRB 1 * enabled
You can enable and disable various devices by echoing the 4 letter code into the file. As an example, if you want to disable the power button for some reason, you would:
echo PWRB > /proc/acpi/wakeup
Which changes the PWRB line to this:
PWRB 1 *disabled
I like this interface - its clean and pretty intuitive. Two problems - first, it is ACPI specific, so we can't share it, and secondly, it doesn't fit in to the sysfs model (which is to return only one value per file). An alternative would be something like this:
/sys/power/wakeup/ |-- PWR |-- RTC |-- LID |-- EC
Each file would contain a "1" if it is enabled, or a "0" if it is not (or alternatively, "on" / "off" if that is more people friendly). To simplify things, we could add another file,
say sources
that could list all the enabled sources:
> cat /sys/power/wakeup/sources PWR RTC LID
To facilitate with the effort, we could make some helper functions, i.e:
struct pm_wakeup_source {
char *name;
int (*enable)(char *);
int (*disable)(char *);
};
pm_register_wakeup_source(struct pm_wakeup_source *);
pm_unregister_wakeup_source(struct pm_wakeup_source *);
Issues
This works fine for OLPC - we only have one power state to worry about. ACPI has 3 different power states to worry about. Can they set an event to trigger on multiple power states? How would that work?
Test Mode
For OLPC, we needed an way to test the suspend/resume path, without actually suspending. This is useful for making sure that our suspend and resume functions are working well, and it can also help with optimization. To enable this, we added a file to the /sys/power directory:
/sys/power/olpc-pm
To run through through a STR cycle without actually suspending, do this:
echo "test" > /sys/power/olpc-pm echo "mem" > /sys/power/state
To go back to "real" mode, do this:
echo "normal" > /sys/power/olpc-pm
This may be something valuable for the PM community at large. If not, then we expect this to only be a test file for olpc-pm, and it won't go upstream.