Power Management Interface

From OLPC
Revision as of 12:07, 2 April 2007 by JordanCrouse (talk | contribs) (Obsoleting wakeup section)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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

Note - This section is more or less withdrawn following discussions on the mailing list:

http://mailman.laptop.org/pipermail/devel/2007-March/004491.html http://mailman.laptop.org/pipermail/devel/2007-April/004514.html

Stay tuned. - JordanCrouse (Talk to me!) 12:07, 2 April 2007 (EDT)

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.