Creation of Cybook 2416 (actually Gen4) repository
This commit is contained in:
553
Documentation/power/devices.txt
Normal file
553
Documentation/power/devices.txt
Normal file
@@ -0,0 +1,553 @@
|
||||
Most of the code in Linux is device drivers, so most of the Linux power
|
||||
management code is also driver-specific. Most drivers will do very little;
|
||||
others, especially for platforms with small batteries (like cell phones),
|
||||
will do a lot.
|
||||
|
||||
This writeup gives an overview of how drivers interact with system-wide
|
||||
power management goals, emphasizing the models and interfaces that are
|
||||
shared by everything that hooks up to the driver model core. Read it as
|
||||
background for the domain-specific work you'd do with any specific driver.
|
||||
|
||||
|
||||
Two Models for Device Power Management
|
||||
======================================
|
||||
Drivers will use one or both of these models to put devices into low-power
|
||||
states:
|
||||
|
||||
System Sleep model:
|
||||
Drivers can enter low power states as part of entering system-wide
|
||||
low-power states like "suspend-to-ram", or (mostly for systems with
|
||||
disks) "hibernate" (suspend-to-disk).
|
||||
|
||||
This is something that device, bus, and class drivers collaborate on
|
||||
by implementing various role-specific suspend and resume methods to
|
||||
cleanly power down hardware and software subsystems, then reactivate
|
||||
them without loss of data.
|
||||
|
||||
Some drivers can manage hardware wakeup events, which make the system
|
||||
leave that low-power state. This feature may be disabled using the
|
||||
relevant /sys/devices/.../power/wakeup file; enabling it may cost some
|
||||
power usage, but let the whole system enter low power states more often.
|
||||
|
||||
Runtime Power Management model:
|
||||
Drivers may also enter low power states while the system is running,
|
||||
independently of other power management activity. Upstream drivers
|
||||
will normally not know (or care) if the device is in some low power
|
||||
state when issuing requests; the driver will auto-resume anything
|
||||
that's needed when it gets a request.
|
||||
|
||||
This doesn't have, or need much infrastructure; it's just something you
|
||||
should do when writing your drivers. For example, clk_disable() unused
|
||||
clocks as part of minimizing power drain for currently-unused hardware.
|
||||
Of course, sometimes clusters of drivers will collaborate with each
|
||||
other, which could involve task-specific power management.
|
||||
|
||||
There's not a lot to be said about those low power states except that they
|
||||
are very system-specific, and often device-specific. Also, that if enough
|
||||
drivers put themselves into low power states (at "runtime"), the effect may be
|
||||
the same as entering some system-wide low-power state (system sleep) ... and
|
||||
that synergies exist, so that several drivers using runtime pm might put the
|
||||
system into a state where even deeper power saving options are available.
|
||||
|
||||
Most suspended devices will have quiesced all I/O: no more DMA or irqs, no
|
||||
more data read or written, and requests from upstream drivers are no longer
|
||||
accepted. A given bus or platform may have different requirements though.
|
||||
|
||||
Examples of hardware wakeup events include an alarm from a real time clock,
|
||||
network wake-on-LAN packets, keyboard or mouse activity, and media insertion
|
||||
or removal (for PCMCIA, MMC/SD, USB, and so on).
|
||||
|
||||
|
||||
Interfaces for Entering System Sleep States
|
||||
===========================================
|
||||
Most of the programming interfaces a device driver needs to know about
|
||||
relate to that first model: entering a system-wide low power state,
|
||||
rather than just minimizing power consumption by one device.
|
||||
|
||||
|
||||
Bus Driver Methods
|
||||
------------------
|
||||
The core methods to suspend and resume devices reside in struct bus_type.
|
||||
These are mostly of interest to people writing infrastructure for busses
|
||||
like PCI or USB, or because they define the primitives that device drivers
|
||||
may need to apply in domain-specific ways to their devices:
|
||||
|
||||
struct bus_type {
|
||||
...
|
||||
int (*suspend)(struct device *dev, pm_message_t state);
|
||||
int (*suspend_late)(struct device *dev, pm_message_t state);
|
||||
|
||||
int (*resume_early)(struct device *dev);
|
||||
int (*resume)(struct device *dev);
|
||||
};
|
||||
|
||||
Bus drivers implement those methods as appropriate for the hardware and
|
||||
the drivers using it; PCI works differently from USB, and so on. Not many
|
||||
people write bus drivers; most driver code is a "device driver" that
|
||||
builds on top of bus-specific framework code.
|
||||
|
||||
For more information on these driver calls, see the description later;
|
||||
they are called in phases for every device, respecting the parent-child
|
||||
sequencing in the driver model tree. Note that as this is being written,
|
||||
only the suspend() and resume() are widely available; not many bus drivers
|
||||
leverage all of those phases, or pass them down to lower driver levels.
|
||||
|
||||
|
||||
/sys/devices/.../power/wakeup files
|
||||
-----------------------------------
|
||||
All devices in the driver model have two flags to control handling of
|
||||
wakeup events, which are hardware signals that can force the device and/or
|
||||
system out of a low power state. These are initialized by bus or device
|
||||
driver code using device_init_wakeup(dev,can_wakeup).
|
||||
|
||||
The "can_wakeup" flag just records whether the device (and its driver) can
|
||||
physically support wakeup events. When that flag is clear, the sysfs
|
||||
"wakeup" file is empty, and device_may_wakeup() returns false.
|
||||
|
||||
For devices that can issue wakeup events, a separate flag controls whether
|
||||
that device should try to use its wakeup mechanism. The initial value of
|
||||
device_may_wakeup() will be true, so that the device's "wakeup" file holds
|
||||
the value "enabled". Userspace can change that to "disabled" so that
|
||||
device_may_wakeup() returns false; or change it back to "enabled" (so that
|
||||
it returns true again).
|
||||
|
||||
|
||||
EXAMPLE: PCI Device Driver Methods
|
||||
-----------------------------------
|
||||
PCI framework software calls these methods when the PCI device driver bound
|
||||
to a device device has provided them:
|
||||
|
||||
struct pci_driver {
|
||||
...
|
||||
int (*suspend)(struct pci_device *pdev, pm_message_t state);
|
||||
int (*suspend_late)(struct pci_device *pdev, pm_message_t state);
|
||||
|
||||
int (*resume_early)(struct pci_device *pdev);
|
||||
int (*resume)(struct pci_device *pdev);
|
||||
};
|
||||
|
||||
Drivers will implement those methods, and call PCI-specific procedures
|
||||
like pci_set_power_state(), pci_enable_wake(), pci_save_state(), and
|
||||
pci_restore_state() to manage PCI-specific mechanisms. (PCI config space
|
||||
could be saved during driver probe, if it weren't for the fact that some
|
||||
systems rely on userspace tweaking using setpci.) Devices are suspended
|
||||
before their bridges enter low power states, and likewise bridges resume
|
||||
before their devices.
|
||||
|
||||
|
||||
Upper Layers of Driver Stacks
|
||||
-----------------------------
|
||||
Device drivers generally have at least two interfaces, and the methods
|
||||
sketched above are the ones which apply to the lower level (nearer PCI, USB,
|
||||
or other bus hardware). The network and block layers are examples of upper
|
||||
level interfaces, as is a character device talking to userspace.
|
||||
|
||||
Power management requests normally need to flow through those upper levels,
|
||||
which often use domain-oriented requests like "blank that screen". In
|
||||
some cases those upper levels will have power management intelligence that
|
||||
relates to end-user activity, or other devices that work in cooperation.
|
||||
|
||||
When those interfaces are structured using class interfaces, there is a
|
||||
standard way to have the upper layer stop issuing requests to a given
|
||||
class device (and restart later):
|
||||
|
||||
struct class {
|
||||
...
|
||||
int (*suspend)(struct device *dev, pm_message_t state);
|
||||
int (*resume)(struct device *dev);
|
||||
};
|
||||
|
||||
Those calls are issued in specific phases of the process by which the
|
||||
system enters a low power "suspend" state, or resumes from it.
|
||||
|
||||
|
||||
Calling Drivers to Enter System Sleep States
|
||||
============================================
|
||||
When the system enters a low power state, each device's driver is asked
|
||||
to suspend the device by putting it into state compatible with the target
|
||||
system state. That's usually some version of "off", but the details are
|
||||
system-specific. Also, wakeup-enabled devices will usually stay partly
|
||||
functional in order to wake the system.
|
||||
|
||||
When the system leaves that low power state, the device's driver is asked
|
||||
to resume it. The suspend and resume operations always go together, and
|
||||
both are multi-phase operations.
|
||||
|
||||
For simple drivers, suspend might quiesce the device using the class code
|
||||
and then turn its hardware as "off" as possible with late_suspend. The
|
||||
matching resume calls would then completely reinitialize the hardware
|
||||
before reactivating its class I/O queues.
|
||||
|
||||
More power-aware drivers drivers will use more than one device low power
|
||||
state, either at runtime or during system sleep states, and might trigger
|
||||
system wakeup events.
|
||||
|
||||
|
||||
Call Sequence Guarantees
|
||||
------------------------
|
||||
To ensure that bridges and similar links needed to talk to a device are
|
||||
available when the device is suspended or resumed, the device tree is
|
||||
walked in a bottom-up order to suspend devices. A top-down order is
|
||||
used to resume those devices.
|
||||
|
||||
The ordering of the device tree is defined by the order in which devices
|
||||
get registered: a child can never be registered, probed or resumed before
|
||||
its parent; and can't be removed or suspended after that parent.
|
||||
|
||||
The policy is that the device tree should match hardware bus topology.
|
||||
(Or at least the control bus, for devices which use multiple busses.)
|
||||
|
||||
|
||||
Suspending Devices
|
||||
------------------
|
||||
Suspending a given device is done in several phases. Suspending the
|
||||
system always includes every phase, executing calls for every device
|
||||
before the next phase begins. Not all busses or classes support all
|
||||
these callbacks; and not all drivers use all the callbacks.
|
||||
|
||||
The phases are seen by driver notifications issued in this order:
|
||||
|
||||
1 class.suspend(dev, message) is called after tasks are frozen, for
|
||||
devices associated with a class that has such a method. This
|
||||
method may sleep.
|
||||
|
||||
Since I/O activity usually comes from such higher layers, this is
|
||||
a good place to quiesce all drivers of a given type (and keep such
|
||||
code out of those drivers).
|
||||
|
||||
2 bus.suspend(dev, message) is called next. This method may sleep,
|
||||
and is often morphed into a device driver call with bus-specific
|
||||
parameters and/or rules.
|
||||
|
||||
This call should handle parts of device suspend logic that require
|
||||
sleeping. It probably does work to quiesce the device which hasn't
|
||||
been abstracted into class.suspend() or bus.suspend_late().
|
||||
|
||||
3 bus.suspend_late(dev, message) is called with IRQs disabled, and
|
||||
with only one CPU active. Until the bus.resume_early() phase
|
||||
completes (see later), IRQs are not enabled again. This method
|
||||
won't be exposed by all busses; for message based busses like USB,
|
||||
I2C, or SPI, device interactions normally require IRQs. This bus
|
||||
call may be morphed into a driver call with bus-specific parameters.
|
||||
|
||||
This call might save low level hardware state that might otherwise
|
||||
be lost in the upcoming low power state, and actually put the
|
||||
device into a low power state ... so that in some cases the device
|
||||
may stay partly usable until this late. This "late" call may also
|
||||
help when coping with hardware that behaves badly.
|
||||
|
||||
The pm_message_t parameter is currently used to refine those semantics
|
||||
(described later).
|
||||
|
||||
At the end of those phases, drivers should normally have stopped all I/O
|
||||
transactions (DMA, IRQs), saved enough state that they can re-initialize
|
||||
or restore previous state (as needed by the hardware), and placed the
|
||||
device into a low-power state. On many platforms they will also use
|
||||
clk_disable() to gate off one or more clock sources; sometimes they will
|
||||
also switch off power supplies, or reduce voltages. Drivers which have
|
||||
runtime PM support may already have performed some or all of the steps
|
||||
needed to prepare for the upcoming system sleep state.
|
||||
|
||||
When any driver sees that its device_can_wakeup(dev), it should make sure
|
||||
to use the relevant hardware signals to trigger a system wakeup event.
|
||||
For example, enable_irq_wake() might identify GPIO signals hooked up to
|
||||
a switch or other external hardware, and pci_enable_wake() does something
|
||||
similar for PCI's PME# signal.
|
||||
|
||||
If a driver (or bus, or class) fails it suspend method, the system won't
|
||||
enter the desired low power state; it will resume all the devices it's
|
||||
suspended so far.
|
||||
|
||||
Note that drivers may need to perform different actions based on the target
|
||||
system lowpower/sleep state. At this writing, there are only platform
|
||||
specific APIs through which drivers could determine those target states.
|
||||
|
||||
|
||||
Device Low Power (suspend) States
|
||||
---------------------------------
|
||||
Device low-power states aren't very standard. One device might only handle
|
||||
"on" and "off, while another might support a dozen different versions of
|
||||
"on" (how many engines are active?), plus a state that gets back to "on"
|
||||
faster than from a full "off".
|
||||
|
||||
Some busses define rules about what different suspend states mean. PCI
|
||||
gives one example: after the suspend sequence completes, a non-legacy
|
||||
PCI device may not perform DMA or issue IRQs, and any wakeup events it
|
||||
issues would be issued through the PME# bus signal. Plus, there are
|
||||
several PCI-standard device states, some of which are optional.
|
||||
|
||||
In contrast, integrated system-on-chip processors often use irqs as the
|
||||
wakeup event sources (so drivers would call enable_irq_wake) and might
|
||||
be able to treat DMA completion as a wakeup event (sometimes DMA can stay
|
||||
active too, it'd only be the CPU and some peripherals that sleep).
|
||||
|
||||
Some details here may be platform-specific. Systems may have devices that
|
||||
can be fully active in certain sleep states, such as an LCD display that's
|
||||
refreshed using DMA while most of the system is sleeping lightly ... and
|
||||
its frame buffer might even be updated by a DSP or other non-Linux CPU while
|
||||
the Linux control processor stays idle.
|
||||
|
||||
Moreover, the specific actions taken may depend on the target system state.
|
||||
One target system state might allow a given device to be very operational;
|
||||
another might require a hard shut down with re-initialization on resume.
|
||||
And two different target systems might use the same device in different
|
||||
ways; the aforementioned LCD might be active in one product's "standby",
|
||||
but a different product using the same SOC might work differently.
|
||||
|
||||
|
||||
Meaning of pm_message_t.event
|
||||
-----------------------------
|
||||
Parameters to suspend calls include the device affected and a message of
|
||||
type pm_message_t, which has one field: the event. If driver does not
|
||||
recognize the event code, suspend calls may abort the request and return
|
||||
a negative errno. However, most drivers will be fine if they implement
|
||||
PM_EVENT_SUSPEND semantics for all messages.
|
||||
|
||||
The event codes are used to refine the goal of suspending the device, and
|
||||
mostly matter when creating or resuming system memory image snapshots, as
|
||||
used with suspend-to-disk:
|
||||
|
||||
PM_EVENT_SUSPEND -- quiesce the driver and put hardware into a low-power
|
||||
state. When used with system sleep states like "suspend-to-RAM" or
|
||||
"standby", the upcoming resume() call will often be able to rely on
|
||||
state kept in hardware, or issue system wakeup events. When used
|
||||
instead with suspend-to-disk, few devices support this capability;
|
||||
most are completely powered off.
|
||||
|
||||
PM_EVENT_FREEZE -- quiesce the driver, but don't necessarily change into
|
||||
any low power mode. A system snapshot is about to be taken, often
|
||||
followed by a call to the driver's resume() method. Neither wakeup
|
||||
events nor DMA are allowed.
|
||||
|
||||
PM_EVENT_PRETHAW -- quiesce the driver, knowing that the upcoming resume()
|
||||
will restore a suspend-to-disk snapshot from a different kernel image.
|
||||
Drivers that are smart enough to look at their hardware state during
|
||||
resume() processing need that state to be correct ... a PRETHAW could
|
||||
be used to invalidate that state (by resetting the device), like a
|
||||
shutdown() invocation would before a kexec() or system halt. Other
|
||||
drivers might handle this the same way as PM_EVENT_FREEZE. Neither
|
||||
wakeup events nor DMA are allowed.
|
||||
|
||||
To enter "standby" (ACPI S1) or "Suspend to RAM" (STR, ACPI S3) states, or
|
||||
the similarly named APM states, only PM_EVENT_SUSPEND is used; for "Suspend
|
||||
to Disk" (STD, hibernate, ACPI S4), all of those event codes are used.
|
||||
|
||||
There's also PM_EVENT_ON, a value which never appears as a suspend event
|
||||
but is sometimes used to record the "not suspended" device state.
|
||||
|
||||
|
||||
Resuming Devices
|
||||
----------------
|
||||
Resuming is done in multiple phases, much like suspending, with all
|
||||
devices processing each phase's calls before the next phase begins.
|
||||
|
||||
The phases are seen by driver notifications issued in this order:
|
||||
|
||||
1 bus.resume_early(dev) is called with IRQs disabled, and with
|
||||
only one CPU active. As with bus.suspend_late(), this method
|
||||
won't be supported on busses that require IRQs in order to
|
||||
interact with devices.
|
||||
|
||||
This reverses the effects of bus.suspend_late().
|
||||
|
||||
2 bus.resume(dev) is called next. This may be morphed into a device
|
||||
driver call with bus-specific parameters; implementations may sleep.
|
||||
|
||||
This reverses the effects of bus.suspend().
|
||||
|
||||
3 class.resume(dev) is called for devices associated with a class
|
||||
that has such a method. Implementations may sleep.
|
||||
|
||||
This reverses the effects of class.suspend(), and would usually
|
||||
reactivate the device's I/O queue.
|
||||
|
||||
At the end of those phases, drivers should normally be as functional as
|
||||
they were before suspending: I/O can be performed using DMA and IRQs, and
|
||||
the relevant clocks are gated on. The device need not be "fully on"; it
|
||||
might be in a runtime lowpower/suspend state that acts as if it were.
|
||||
|
||||
However, the details here may again be platform-specific. For example,
|
||||
some systems support multiple "run" states, and the mode in effect at
|
||||
the end of resume() might not be the one which preceded suspension.
|
||||
That means availability of certain clocks or power supplies changed,
|
||||
which could easily affect how a driver works.
|
||||
|
||||
|
||||
Drivers need to be able to handle hardware which has been reset since the
|
||||
suspend methods were called, for example by complete reinitialization.
|
||||
This may be the hardest part, and the one most protected by NDA'd documents
|
||||
and chip errata. It's simplest if the hardware state hasn't changed since
|
||||
the suspend() was called, but that can't always be guaranteed.
|
||||
|
||||
Drivers must also be prepared to notice that the device has been removed
|
||||
while the system was powered off, whenever that's physically possible.
|
||||
PCMCIA, MMC, USB, Firewire, SCSI, and even IDE are common examples of busses
|
||||
where common Linux platforms will see such removal. Details of how drivers
|
||||
will notice and handle such removals are currently bus-specific, and often
|
||||
involve a separate thread.
|
||||
|
||||
|
||||
Note that the bus-specific runtime PM wakeup mechanism can exist, and might
|
||||
be defined to share some of the same driver code as for system wakeup. For
|
||||
example, a bus-specific device driver's resume() method might be used there,
|
||||
so it wouldn't only be called from bus.resume() during system-wide wakeup.
|
||||
See bus-specific information about how runtime wakeup events are handled.
|
||||
|
||||
|
||||
System Devices
|
||||
--------------
|
||||
System devices follow a slightly different API, which can be found in
|
||||
|
||||
include/linux/sysdev.h
|
||||
drivers/base/sys.c
|
||||
|
||||
System devices will only be suspended with interrupts disabled, and after
|
||||
all other devices have been suspended. On resume, they will be resumed
|
||||
before any other devices, and also with interrupts disabled.
|
||||
|
||||
That is, IRQs are disabled, the suspend_late() phase begins, then the
|
||||
sysdev_driver.suspend() phase, and the system enters a sleep state. Then
|
||||
the sysdev_driver.resume() phase begins, followed by the resume_early()
|
||||
phase, after which IRQs are enabled.
|
||||
|
||||
Code to actually enter and exit the system-wide low power state sometimes
|
||||
involves hardware details that are only known to the boot firmware, and
|
||||
may leave a CPU running software (from SRAM or flash memory) that monitors
|
||||
the system and manages its wakeup sequence.
|
||||
|
||||
|
||||
Runtime Power Management
|
||||
========================
|
||||
Many devices are able to dynamically power down while the system is still
|
||||
running. This feature is useful for devices that are not being used, and
|
||||
can offer significant power savings on a running system. These devices
|
||||
often support a range of runtime power states, which might use names such
|
||||
as "off", "sleep", "idle", "active", and so on. Those states will in some
|
||||
cases (like PCI) be partially constrained by a bus the device uses, and will
|
||||
usually include hardware states that are also used in system sleep states.
|
||||
|
||||
However, note that if a driver puts a device into a runtime low power state
|
||||
and the system then goes into a system-wide sleep state, it normally ought
|
||||
to resume into that runtime low power state rather than "full on". Such
|
||||
distinctions would be part of the driver-internal state machine for that
|
||||
hardware; the whole point of runtime power management is to be sure that
|
||||
drivers are decoupled in that way from the state machine governing phases
|
||||
of the system-wide power/sleep state transitions.
|
||||
|
||||
|
||||
Power Saving Techniques
|
||||
-----------------------
|
||||
Normally runtime power management is handled by the drivers without specific
|
||||
userspace or kernel intervention, by device-aware use of techniques like:
|
||||
|
||||
Using information provided by other system layers
|
||||
- stay deeply "off" except between open() and close()
|
||||
- if transceiver/PHY indicates "nobody connected", stay "off"
|
||||
- application protocols may include power commands or hints
|
||||
|
||||
Using fewer CPU cycles
|
||||
- using DMA instead of PIO
|
||||
- removing timers, or making them lower frequency
|
||||
- shortening "hot" code paths
|
||||
- eliminating cache misses
|
||||
- (sometimes) offloading work to device firmware
|
||||
|
||||
Reducing other resource costs
|
||||
- gating off unused clocks in software (or hardware)
|
||||
- switching off unused power supplies
|
||||
- eliminating (or delaying/merging) IRQs
|
||||
- tuning DMA to use word and/or burst modes
|
||||
|
||||
Using device-specific low power states
|
||||
- using lower voltages
|
||||
- avoiding needless DMA transfers
|
||||
|
||||
Read your hardware documentation carefully to see the opportunities that
|
||||
may be available. If you can, measure the actual power usage and check
|
||||
it against the budget established for your project.
|
||||
|
||||
|
||||
Examples: USB hosts, system timer, system CPU
|
||||
----------------------------------------------
|
||||
USB host controllers make interesting, if complex, examples. In many cases
|
||||
these have no work to do: no USB devices are connected, or all of them are
|
||||
in the USB "suspend" state. Linux host controller drivers can then disable
|
||||
periodic DMA transfers that would otherwise be a constant power drain on the
|
||||
memory subsystem, and enter a suspend state. In power-aware controllers,
|
||||
entering that suspend state may disable the clock used with USB signaling,
|
||||
saving a certain amount of power.
|
||||
|
||||
The controller will be woken from that state (with an IRQ) by changes to the
|
||||
signal state on the data lines of a given port, for example by an existing
|
||||
peripheral requesting "remote wakeup" or by plugging a new peripheral. The
|
||||
same wakeup mechanism usually works from "standby" sleep states, and on some
|
||||
systems also from "suspend to RAM" (or even "suspend to disk") states.
|
||||
(Except that ACPI may be involved instead of normal IRQs, on some hardware.)
|
||||
|
||||
System devices like timers and CPUs may have special roles in the platform
|
||||
power management scheme. For example, system timers using a "dynamic tick"
|
||||
approach don't just save CPU cycles (by eliminating needless timer IRQs),
|
||||
but they may also open the door to using lower power CPU "idle" states that
|
||||
cost more than a jiffie to enter and exit. On x86 systems these are states
|
||||
like "C3"; note that periodic DMA transfers from a USB host controller will
|
||||
also prevent entry to a C3 state, much like a periodic timer IRQ.
|
||||
|
||||
That kind of runtime mechanism interaction is common. "System On Chip" (SOC)
|
||||
processors often have low power idle modes that can't be entered unless
|
||||
certain medium-speed clocks (often 12 or 48 MHz) are gated off. When the
|
||||
drivers gate those clocks effectively, then the system idle task may be able
|
||||
to use the lower power idle modes and thereby increase battery life.
|
||||
|
||||
If the CPU can have a "cpufreq" driver, there also may be opportunities
|
||||
to shift to lower voltage settings and reduce the power cost of executing
|
||||
a given number of instructions. (Without voltage adjustment, it's rare
|
||||
for cpufreq to save much power; the cost-per-instruction must go down.)
|
||||
|
||||
|
||||
/sys/devices/.../power/state files
|
||||
==================================
|
||||
For now you can also test some of this functionality using sysfs.
|
||||
|
||||
DEPRECATED: USE "power/state" ONLY FOR DRIVER TESTING, AND
|
||||
AVOID USING dev->power.power_state IN DRIVERS.
|
||||
|
||||
THESE WILL BE REMOVED. IF THE "power/state" FILE GETS REPLACED,
|
||||
IT WILL BECOME SOMETHING COUPLED TO THE BUS OR DRIVER.
|
||||
|
||||
In each device's directory, there is a 'power' directory, which contains
|
||||
at least a 'state' file. The value of this field is effectively boolean,
|
||||
PM_EVENT_ON or PM_EVENT_SUSPEND.
|
||||
|
||||
* Reading from this file displays a value corresponding to
|
||||
the power.power_state.event field. All nonzero values are
|
||||
displayed as "2", corresponding to a low power state; zero
|
||||
is displayed as "0", corresponding to normal operation.
|
||||
|
||||
* Writing to this file initiates a transition using the
|
||||
specified event code number; only '0', '2', and '3' are
|
||||
accepted (without a newline); '2' and '3' are both
|
||||
mapped to PM_EVENT_SUSPEND.
|
||||
|
||||
On writes, the PM core relies on that recorded event code and the device/bus
|
||||
capabilities to determine whether it uses a partial suspend() or resume()
|
||||
sequence to change things so that the recorded event corresponds to the
|
||||
numeric parameter.
|
||||
|
||||
- If the bus requires the irqs-disabled suspend_late()/resume_early()
|
||||
phases, writes fail because those operations are not supported here.
|
||||
|
||||
- If the recorded value is the expected value, nothing is done.
|
||||
|
||||
- If the recorded value is nonzero, the device is partially resumed,
|
||||
using the bus.resume() and/or class.resume() methods.
|
||||
|
||||
- If the target value is nonzero, the device is partially suspended,
|
||||
using the class.suspend() and/or bus.suspend() methods and the
|
||||
PM_EVENT_SUSPEND message.
|
||||
|
||||
Drivers have no way to tell whether their suspend() and resume() calls
|
||||
have come through the sysfs power/state file or as part of entering a
|
||||
system sleep state, except that when accessed through sysfs the normal
|
||||
parent/child sequencing rules are ignored. Drivers (such as bus, bridge,
|
||||
or hub drivers) which expose child devices may need to enforce those rules
|
||||
on their own.
|
||||
82
Documentation/power/interface.txt
Normal file
82
Documentation/power/interface.txt
Normal file
@@ -0,0 +1,82 @@
|
||||
Power Management Interface
|
||||
|
||||
|
||||
The power management subsystem provides a unified sysfs interface to
|
||||
userspace, regardless of what architecture or platform one is
|
||||
running. The interface exists in /sys/power/ directory (assuming sysfs
|
||||
is mounted at /sys).
|
||||
|
||||
/sys/power/state controls system power state. Reading from this file
|
||||
returns what states are supported, which is hard-coded to 'standby'
|
||||
(Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk'
|
||||
(Suspend-to-Disk).
|
||||
|
||||
Writing to this file one of those strings causes the system to
|
||||
transition into that state. Please see the file
|
||||
Documentation/power/states.txt for a description of each of those
|
||||
states.
|
||||
|
||||
|
||||
/sys/power/disk controls the operating mode of the suspend-to-disk
|
||||
mechanism. Suspend-to-disk can be handled in several ways. The
|
||||
greatest distinction is who writes memory to disk - the firmware or
|
||||
the kernel. If the firmware does it, we assume that it also handles
|
||||
suspending the system.
|
||||
|
||||
If the kernel does it, then we have three options for putting the system
|
||||
to sleep - using the platform driver (e.g. ACPI or other PM
|
||||
registers), powering off the system or rebooting the system (for
|
||||
testing). The system will support either 'firmware' or 'platform', and
|
||||
that is known a priori. But, the user may choose 'shutdown' or
|
||||
'reboot' as alternatives.
|
||||
|
||||
Additionally, /sys/power/disk can be used to turn on one of the two testing
|
||||
modes of the suspend-to-disk mechanism: 'testproc' or 'test'. If the
|
||||
suspend-to-disk mechanism is in the 'testproc' mode, writing 'disk' to
|
||||
/sys/power/state will cause the kernel to disable nonboot CPUs and freeze
|
||||
tasks, wait for 5 seconds, unfreeze tasks and enable nonboot CPUs. If it is
|
||||
in the 'test' mode, writing 'disk' to /sys/power/state will cause the kernel
|
||||
to disable nonboot CPUs and freeze tasks, shrink memory, suspend devices, wait
|
||||
for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then,
|
||||
we are able to look in the log messages and work out, for example, which code
|
||||
is being slow and which device drivers are misbehaving.
|
||||
|
||||
Reading from this file will display what the mode is currently set
|
||||
to. Writing to this file will accept one of
|
||||
|
||||
'firmware'
|
||||
'platform'
|
||||
'shutdown'
|
||||
'reboot'
|
||||
'testproc'
|
||||
'test'
|
||||
|
||||
It will only change to 'firmware' or 'platform' if the system supports
|
||||
it.
|
||||
|
||||
/sys/power/image_size controls the size of the image created by
|
||||
the suspend-to-disk mechanism. It can be written a string
|
||||
representing a non-negative integer that will be used as an upper
|
||||
limit of the image size, in bytes. The suspend-to-disk mechanism will
|
||||
do its best to ensure the image size will not exceed that number. However,
|
||||
if this turns out to be impossible, it will try to suspend anyway using the
|
||||
smallest image possible. In particular, if "0" is written to this file, the
|
||||
suspend image will be as small as possible.
|
||||
|
||||
Reading from this file will display the current image size limit, which
|
||||
is set to 500 MB by default.
|
||||
|
||||
/sys/power/pm_trace controls the code which saves the last PM event point in
|
||||
the RTC across reboots, so that you can debug a machine that just hangs
|
||||
during suspend (or more commonly, during resume). Namely, the RTC is only
|
||||
used to save the last PM event point if this file contains '1'. Initially it
|
||||
contains '0' which may be changed to '1' by writing a string representing a
|
||||
nonzero integer into it.
|
||||
|
||||
To use this debugging feature you should attempt to suspend the machine, then
|
||||
reboot it and run
|
||||
|
||||
dmesg -s 1000000 | grep 'hash matches'
|
||||
|
||||
CAUTION: Using it will cause your machine's real-time (CMOS) clock to be
|
||||
set to a random invalid time after a resume.
|
||||
40
Documentation/power/kernel_threads.txt
Normal file
40
Documentation/power/kernel_threads.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
KERNEL THREADS
|
||||
|
||||
|
||||
Freezer
|
||||
|
||||
Upon entering a suspended state the system will freeze all
|
||||
tasks. This is done by delivering pseudosignals. This affects
|
||||
kernel threads, too. To successfully freeze a kernel thread
|
||||
the thread has to check for the pseudosignal and enter the
|
||||
refrigerator. Code to do this looks like this:
|
||||
|
||||
do {
|
||||
hub_events();
|
||||
wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list));
|
||||
try_to_freeze();
|
||||
} while (!signal_pending(current));
|
||||
|
||||
from drivers/usb/core/hub.c::hub_thread()
|
||||
|
||||
|
||||
The Unfreezable
|
||||
|
||||
Some kernel threads however, must not be frozen. The kernel must
|
||||
be able to finish pending IO operations and later on be able to
|
||||
write the memory image to disk. Kernel threads needed to do IO
|
||||
must stay awake. Such threads must mark themselves unfreezable
|
||||
like this:
|
||||
|
||||
/*
|
||||
* This thread doesn't need any user-level access,
|
||||
* so get rid of all our resources.
|
||||
*/
|
||||
daemonize("usb-storage");
|
||||
|
||||
current->flags |= PF_NOFREEZE;
|
||||
|
||||
from drivers/usb/storage/usb.c::usb_stor_control_thread()
|
||||
|
||||
Such drivers are themselves responsible for staying quiet during
|
||||
the actual snapshotting.
|
||||
336
Documentation/power/pci.txt
Normal file
336
Documentation/power/pci.txt
Normal file
@@ -0,0 +1,336 @@
|
||||
|
||||
PCI Power Management
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An overview of the concepts and the related functions in the Linux kernel
|
||||
|
||||
Patrick Mochel <mochel@transmeta.com>
|
||||
(and others)
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
1. Overview
|
||||
2. How the PCI Subsystem Does Power Management
|
||||
3. PCI Utility Functions
|
||||
4. PCI Device Drivers
|
||||
5. Resources
|
||||
|
||||
1. Overview
|
||||
~~~~~~~~~~~
|
||||
|
||||
The PCI Power Management Specification was introduced between the PCI 2.1 and
|
||||
PCI 2.2 Specifications. It a standard interface for controlling various
|
||||
power management operations.
|
||||
|
||||
Implementation of the PCI PM Spec is optional, as are several sub-components of
|
||||
it. If a device supports the PCI PM Spec, the device will have an 8 byte
|
||||
capability field in its PCI configuration space. This field is used to describe
|
||||
and control the standard PCI power management features.
|
||||
|
||||
The PCI PM spec defines 4 operating states for devices (D0 - D3) and for buses
|
||||
(B0 - B3). The higher the number, the less power the device consumes. However,
|
||||
the higher the number, the longer the latency is for the device to return to
|
||||
an operational state (D0).
|
||||
|
||||
There are actually two D3 states. When someone talks about D3, they usually
|
||||
mean D3hot, which corresponds to an ACPI D2 state (power is reduced, the
|
||||
device may lose some context). But they may also mean D3cold, which is an
|
||||
ACPI D3 state (power is fully off, all state was discarded); or both.
|
||||
|
||||
Bus power management is not covered in this version of this document.
|
||||
|
||||
Note that all PCI devices support D0 and D3cold by default, regardless of
|
||||
whether or not they implement any of the PCI PM spec.
|
||||
|
||||
The possible state transitions that a device can undergo are:
|
||||
|
||||
+---------------------------+
|
||||
| Current State | New State |
|
||||
+---------------------------+
|
||||
| D0 | D1, D2, D3|
|
||||
+---------------------------+
|
||||
| D1 | D2, D3 |
|
||||
+---------------------------+
|
||||
| D2 | D3 |
|
||||
+---------------------------+
|
||||
| D1, D2, D3 | D0 |
|
||||
+---------------------------+
|
||||
|
||||
Note that when the system is entering a global suspend state, all devices will
|
||||
be placed into D3 and when resuming, all devices will be placed into D0.
|
||||
However, when the system is running, other state transitions are possible.
|
||||
|
||||
2. How The PCI Subsystem Handles Power Management
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The PCI suspend/resume functionality is accessed indirectly via the Power
|
||||
Management subsystem. At boot, the PCI driver registers a power management
|
||||
callback with that layer. Upon entering a suspend state, the PM layer iterates
|
||||
through all of its registered callbacks. This currently takes place only during
|
||||
APM state transitions.
|
||||
|
||||
Upon going to sleep, the PCI subsystem walks its device tree twice. Both times,
|
||||
it does a depth first walk of the device tree. The first walk saves each of the
|
||||
device's state and checks for devices that will prevent the system from entering
|
||||
a global power state. The next walk then places the devices in a low power
|
||||
state.
|
||||
|
||||
The first walk allows a graceful recovery in the event of a failure, since none
|
||||
of the devices have actually been powered down.
|
||||
|
||||
In both walks, in particular the second, all children of a bridge are touched
|
||||
before the actual bridge itself. This allows the bridge to retain power while
|
||||
its children are being accessed.
|
||||
|
||||
Upon resuming from sleep, just the opposite must be true: all bridges must be
|
||||
powered on and restored before their children are powered on. This is easily
|
||||
accomplished with a breadth-first walk of the PCI device tree.
|
||||
|
||||
|
||||
3. PCI Utility Functions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
These are helper functions designed to be called by individual device drivers.
|
||||
Assuming that a device behaves as advertised, these should be applicable in most
|
||||
cases. However, results may vary.
|
||||
|
||||
Note that these functions are never implicitly called for the driver. The driver
|
||||
is always responsible for deciding when and if to call these.
|
||||
|
||||
|
||||
pci_save_state
|
||||
--------------
|
||||
|
||||
Usage:
|
||||
pci_save_state(struct pci_dev *dev);
|
||||
|
||||
Description:
|
||||
Save first 64 bytes of PCI config space, along with any additional
|
||||
PCI-Express or PCI-X information.
|
||||
|
||||
|
||||
pci_restore_state
|
||||
-----------------
|
||||
|
||||
Usage:
|
||||
pci_restore_state(struct pci_dev *dev);
|
||||
|
||||
Description:
|
||||
Restore previously saved config space.
|
||||
|
||||
|
||||
pci_set_power_state
|
||||
-------------------
|
||||
|
||||
Usage:
|
||||
pci_set_power_state(struct pci_dev *dev, pci_power_t state);
|
||||
|
||||
Description:
|
||||
Transition device to low power state using PCI PM Capabilities
|
||||
registers.
|
||||
|
||||
Will fail under one of the following conditions:
|
||||
- If state is less than current state, but not D0 (illegal transition)
|
||||
- Device doesn't support PM Capabilities
|
||||
- Device does not support requested state
|
||||
|
||||
|
||||
pci_enable_wake
|
||||
---------------
|
||||
|
||||
Usage:
|
||||
pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
|
||||
|
||||
Description:
|
||||
Enable device to generate PME# during low power state using PCI PM
|
||||
Capabilities.
|
||||
|
||||
Checks whether if device supports generating PME# from requested state
|
||||
and fail if it does not, unless enable == 0 (request is to disable wake
|
||||
events, which is implicit if it doesn't even support it in the first
|
||||
place).
|
||||
|
||||
Note that the PMC Register in the device's PM Capabilities has a bitmask
|
||||
of the states it supports generating PME# from. D3hot is bit 3 and
|
||||
D3cold is bit 4. So, while a value of 4 as the state may not seem
|
||||
semantically correct, it is.
|
||||
|
||||
|
||||
4. PCI Device Drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
These functions are intended for use by individual drivers, and are defined in
|
||||
struct pci_driver:
|
||||
|
||||
int (*suspend) (struct pci_dev *dev, pm_message_t state);
|
||||
int (*resume) (struct pci_dev *dev);
|
||||
int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable);
|
||||
|
||||
|
||||
suspend
|
||||
-------
|
||||
|
||||
Usage:
|
||||
|
||||
if (dev->driver && dev->driver->suspend)
|
||||
dev->driver->suspend(dev,state);
|
||||
|
||||
A driver uses this function to actually transition the device into a low power
|
||||
state. This should include disabling I/O, IRQs, and bus-mastering, as well as
|
||||
physically transitioning the device to a lower power state; it may also include
|
||||
calls to pci_enable_wake().
|
||||
|
||||
Bus mastering may be disabled by doing:
|
||||
|
||||
pci_disable_device(dev);
|
||||
|
||||
For devices that support the PCI PM Spec, this may be used to set the device's
|
||||
power state to match the suspend() parameter:
|
||||
|
||||
pci_set_power_state(dev,state);
|
||||
|
||||
The driver is also responsible for disabling any other device-specific features
|
||||
(e.g blanking screen, turning off on-card memory, etc).
|
||||
|
||||
The driver should be sure to track the current state of the device, as it may
|
||||
obviate the need for some operations.
|
||||
|
||||
The driver should update the current_state field in its pci_dev structure in
|
||||
this function, except for PM-capable devices when pci_set_power_state is used.
|
||||
|
||||
resume
|
||||
------
|
||||
|
||||
Usage:
|
||||
|
||||
if (dev->driver && dev->driver->suspend)
|
||||
dev->driver->resume(dev)
|
||||
|
||||
The resume callback may be called from any power state, and is always meant to
|
||||
transition the device to the D0 state.
|
||||
|
||||
The driver is responsible for reenabling any features of the device that had
|
||||
been disabled during previous suspend calls, such as IRQs and bus mastering,
|
||||
as well as calling pci_restore_state().
|
||||
|
||||
If the device is currently in D3, it may need to be reinitialized in resume().
|
||||
|
||||
* Some types of devices, like bus controllers, will preserve context in D3hot
|
||||
(using Vcc power). Their drivers will often want to avoid re-initializing
|
||||
them after re-entering D0 (perhaps to avoid resetting downstream devices).
|
||||
|
||||
* Other kinds of devices in D3hot will discard device context as part of a
|
||||
soft reset when re-entering the D0 state.
|
||||
|
||||
* Devices resuming from D3cold always go through a power-on reset. Some
|
||||
device context can also be preserved using Vaux power.
|
||||
|
||||
* Some systems hide D3cold resume paths from drivers. For example, on PCs
|
||||
the resume path for suspend-to-disk often runs BIOS powerup code, which
|
||||
will sometimes re-initialize the device.
|
||||
|
||||
To handle resets during D3 to D0 transitions, it may be convenient to share
|
||||
device initialization code between probe() and resume(). Device parameters
|
||||
can also be saved before the driver suspends into D3, avoiding re-probe.
|
||||
|
||||
If the device supports the PCI PM Spec, it can use this to physically transition
|
||||
the device to D0:
|
||||
|
||||
pci_set_power_state(dev,0);
|
||||
|
||||
Note that if the entire system is transitioning out of a global sleep state, all
|
||||
devices will be placed in the D0 state, so this is not necessary. However, in
|
||||
the event that the device is placed in the D3 state during normal operation,
|
||||
this call is necessary. It is impossible to determine which of the two events is
|
||||
taking place in the driver, so it is always a good idea to make that call.
|
||||
|
||||
The driver should take note of the state that it is resuming from in order to
|
||||
ensure correct (and speedy) operation.
|
||||
|
||||
The driver should update the current_state field in its pci_dev structure in
|
||||
this function, except for PM-capable devices when pci_set_power_state is used.
|
||||
|
||||
|
||||
enable_wake
|
||||
-----------
|
||||
|
||||
Usage:
|
||||
|
||||
if (dev->driver && dev->driver->enable_wake)
|
||||
dev->driver->enable_wake(dev,state,enable);
|
||||
|
||||
This callback is generally only relevant for devices that support the PCI PM
|
||||
spec and have the ability to generate a PME# (Power Management Event Signal)
|
||||
to wake the system up. (However, it is possible that a device may support
|
||||
some non-standard way of generating a wake event on sleep.)
|
||||
|
||||
Bits 15:11 of the PMC (Power Mgmt Capabilities) Register in a device's
|
||||
PM Capabilities describe what power states the device supports generating a
|
||||
wake event from:
|
||||
|
||||
+------------------+
|
||||
| Bit | State |
|
||||
+------------------+
|
||||
| 11 | D0 |
|
||||
| 12 | D1 |
|
||||
| 13 | D2 |
|
||||
| 14 | D3hot |
|
||||
| 15 | D3cold |
|
||||
+------------------+
|
||||
|
||||
A device can use this to enable wake events:
|
||||
|
||||
pci_enable_wake(dev,state,enable);
|
||||
|
||||
Note that to enable PME# from D3cold, a value of 4 should be passed to
|
||||
pci_enable_wake (since it uses an index into a bitmask). If a driver gets
|
||||
a request to enable wake events from D3, two calls should be made to
|
||||
pci_enable_wake (one for both D3hot and D3cold).
|
||||
|
||||
|
||||
A reference implementation
|
||||
-------------------------
|
||||
.suspend()
|
||||
{
|
||||
/* driver specific operations */
|
||||
|
||||
/* Disable IRQ */
|
||||
free_irq();
|
||||
/* If using MSI */
|
||||
pci_disable_msi();
|
||||
|
||||
pci_save_state();
|
||||
pci_enable_wake();
|
||||
/* Disable IO/bus master/irq router */
|
||||
pci_disable_device();
|
||||
pci_set_power_state(pci_choose_state());
|
||||
}
|
||||
|
||||
.resume()
|
||||
{
|
||||
pci_set_power_state(PCI_D0);
|
||||
pci_restore_state();
|
||||
/* device's irq possibly is changed, driver should take care */
|
||||
pci_enable_device();
|
||||
pci_set_master();
|
||||
|
||||
/* if using MSI, device's vector possibly is changed */
|
||||
pci_enable_msi();
|
||||
|
||||
request_irq();
|
||||
/* driver specific operations; */
|
||||
}
|
||||
|
||||
This is a typical implementation. Drivers can slightly change the order
|
||||
of the operations in the implementation, ignore some operations or add
|
||||
more driver specific operations in it, but drivers should do something like
|
||||
this on the whole.
|
||||
|
||||
5. Resources
|
||||
~~~~~~~~~~~~
|
||||
|
||||
PCI Local Bus Specification
|
||||
PCI Bus Power Management Interface Specification
|
||||
|
||||
http://www.pcisig.com
|
||||
|
||||
56
Documentation/power/s2ram.txt
Normal file
56
Documentation/power/s2ram.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
How to get s2ram working
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
2006 Linus Torvalds
|
||||
2006 Pavel Machek
|
||||
|
||||
1) Check suspend.sf.net, program s2ram there has long whitelist of
|
||||
"known ok" machines, along with tricks to use on each one.
|
||||
|
||||
2) If that does not help, try reading tricks.txt and
|
||||
video.txt. Perhaps problem is as simple as broken module, and
|
||||
simple module unload can fix it.
|
||||
|
||||
3) You can use Linus' TRACE_RESUME infrastructure, described below.
|
||||
|
||||
Using TRACE_RESUME
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
I've been working at making the machines I have able to STR, and almost
|
||||
always it's a driver that is buggy. Thank God for the suspend/resume
|
||||
debugging - the thing that Chuck tried to disable. That's often the _only_
|
||||
way to debug these things, and it's actually pretty powerful (but
|
||||
time-consuming - having to insert TRACE_RESUME() markers into the device
|
||||
driver that doesn't resume and recompile and reboot).
|
||||
|
||||
Anyway, the way to debug this for people who are interested (have a
|
||||
machine that doesn't boot) is:
|
||||
|
||||
- enable PM_DEBUG, and PM_TRACE
|
||||
|
||||
- use a script like this:
|
||||
|
||||
#!/bin/sh
|
||||
sync
|
||||
echo 1 > /sys/power/pm_trace
|
||||
echo mem > /sys/power/state
|
||||
|
||||
to suspend
|
||||
|
||||
- if it doesn't come back up (which is usually the problem), reboot by
|
||||
holding the power button down, and look at the dmesg output for things
|
||||
like
|
||||
|
||||
Magic number: 4:156:725
|
||||
hash matches drivers/base/power/resume.c:28
|
||||
hash matches device 0000:01:00.0
|
||||
|
||||
which means that the last trace event was just before trying to resume
|
||||
device 0000:01:00.0. Then figure out what driver is controlling that
|
||||
device (lspci and /sys/devices/pci* is your friend), and see if you can
|
||||
fix it, disable it, or trace into its resume function.
|
||||
|
||||
For example, the above happens to be the VGA device on my EVO, which I
|
||||
used to run with "radeonfb" (it's an ATI Radeon mobility). It turns out
|
||||
that "radeonfb" simply cannot resume that device - it tries to set the
|
||||
PLL's, and it just _hangs_. Using the regular VGA console and letting X
|
||||
resume it instead works fine.
|
||||
79
Documentation/power/states.txt
Normal file
79
Documentation/power/states.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
System Power Management States
|
||||
|
||||
|
||||
The kernel supports three power management states generically, though
|
||||
each is dependent on platform support code to implement the low-level
|
||||
details for each state. This file describes each state, what they are
|
||||
commonly called, what ACPI state they map to, and what string to write
|
||||
to /sys/power/state to enter that state
|
||||
|
||||
|
||||
State: Standby / Power-On Suspend
|
||||
ACPI State: S1
|
||||
String: "standby"
|
||||
|
||||
This state offers minimal, though real, power savings, while providing
|
||||
a very low-latency transition back to a working system. No operating
|
||||
state is lost (the CPU retains power), so the system easily starts up
|
||||
again where it left off.
|
||||
|
||||
We try to put devices in a low-power state equivalent to D1, which
|
||||
also offers low power savings, but low resume latency. Not all devices
|
||||
support D1, and those that don't are left on.
|
||||
|
||||
A transition from Standby to the On state should take about 1-2
|
||||
seconds.
|
||||
|
||||
|
||||
State: Suspend-to-RAM
|
||||
ACPI State: S3
|
||||
String: "mem"
|
||||
|
||||
This state offers significant power savings as everything in the
|
||||
system is put into a low-power state, except for memory, which is
|
||||
placed in self-refresh mode to retain its contents.
|
||||
|
||||
System and device state is saved and kept in memory. All devices are
|
||||
suspended and put into D3. In many cases, all peripheral buses lose
|
||||
power when entering STR, so devices must be able to handle the
|
||||
transition back to the On state.
|
||||
|
||||
For at least ACPI, STR requires some minimal boot-strapping code to
|
||||
resume the system from STR. This may be true on other platforms.
|
||||
|
||||
A transition from Suspend-to-RAM to the On state should take about
|
||||
3-5 seconds.
|
||||
|
||||
|
||||
State: Suspend-to-disk
|
||||
ACPI State: S4
|
||||
String: "disk"
|
||||
|
||||
This state offers the greatest power savings, and can be used even in
|
||||
the absence of low-level platform support for power management. This
|
||||
state operates similarly to Suspend-to-RAM, but includes a final step
|
||||
of writing memory contents to disk. On resume, this is read and memory
|
||||
is restored to its pre-suspend state.
|
||||
|
||||
STD can be handled by the firmware or the kernel. If it is handled by
|
||||
the firmware, it usually requires a dedicated partition that must be
|
||||
setup via another operating system for it to use. Despite the
|
||||
inconvenience, this method requires minimal work by the kernel, since
|
||||
the firmware will also handle restoring memory contents on resume.
|
||||
|
||||
If the kernel is responsible for persistently saving state, a mechanism
|
||||
called 'swsusp' (Swap Suspend) is used to write memory contents to
|
||||
free swap space. swsusp has some restrictive requirements, but should
|
||||
work in most cases. Some, albeit outdated, documentation can be found
|
||||
in Documentation/power/swsusp.txt.
|
||||
|
||||
Once memory state is written to disk, the system may either enter a
|
||||
low-power state (like ACPI S4), or it may simply power down. Powering
|
||||
down offers greater savings, and allows this mechanism to work on any
|
||||
system. However, entering a real low-power state allows the user to
|
||||
trigger wake up events (e.g. pressing a key or opening a laptop lid).
|
||||
|
||||
A transition from Suspend-to-Disk to the On state should take about 30
|
||||
seconds, though it's typically a bit more with the current
|
||||
implementation.
|
||||
60
Documentation/power/swsusp-and-swap-files.txt
Normal file
60
Documentation/power/swsusp-and-swap-files.txt
Normal file
@@ -0,0 +1,60 @@
|
||||
Using swap files with software suspend (swsusp)
|
||||
(C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
|
||||
|
||||
The Linux kernel handles swap files almost in the same way as it handles swap
|
||||
partitions and there are only two differences between these two types of swap
|
||||
areas:
|
||||
(1) swap files need not be contiguous,
|
||||
(2) the header of a swap file is not in the first block of the partition that
|
||||
holds it. From the swsusp's point of view (1) is not a problem, because it is
|
||||
already taken care of by the swap-handling code, but (2) has to be taken into
|
||||
consideration.
|
||||
|
||||
In principle the location of a swap file's header may be determined with the
|
||||
help of appropriate filesystem driver. Unfortunately, however, it requires the
|
||||
filesystem holding the swap file to be mounted, and if this filesystem is
|
||||
journaled, it cannot be mounted during resume from disk. For this reason to
|
||||
identify a swap file swsusp uses the name of the partition that holds the file
|
||||
and the offset from the beginning of the partition at which the swap file's
|
||||
header is located. For convenience, this offset is expressed in <PAGE_SIZE>
|
||||
units.
|
||||
|
||||
In order to use a swap file with swsusp, you need to:
|
||||
|
||||
1) Create the swap file and make it active, eg.
|
||||
|
||||
# dd if=/dev/zero of=<swap_file_path> bs=1024 count=<swap_file_size_in_k>
|
||||
# mkswap <swap_file_path>
|
||||
# swapon <swap_file_path>
|
||||
|
||||
2) Use an application that will bmap the swap file with the help of the
|
||||
FIBMAP ioctl and determine the location of the file's swap header, as the
|
||||
offset, in <PAGE_SIZE> units, from the beginning of the partition which
|
||||
holds the swap file.
|
||||
|
||||
3) Add the following parameters to the kernel command line:
|
||||
|
||||
resume=<swap_file_partition> resume_offset=<swap_file_offset>
|
||||
|
||||
where <swap_file_partition> is the partition on which the swap file is located
|
||||
and <swap_file_offset> is the offset of the swap header determined by the
|
||||
application in 2) (of course, this step may be carried out automatically
|
||||
by the same application that determies the swap file's header offset using the
|
||||
FIBMAP ioctl)
|
||||
|
||||
OR
|
||||
|
||||
Use a userland suspend application that will set the partition and offset
|
||||
with the help of the SNAPSHOT_SET_SWAP_AREA ioctl described in
|
||||
Documentation/power/userland-swsusp.txt (this is the only method to suspend
|
||||
to a swap file allowing the resume to be initiated from an initrd or initramfs
|
||||
image).
|
||||
|
||||
Now, swsusp will use the swap file in the same way in which it would use a swap
|
||||
partition. In particular, the swap file has to be active (ie. be present in
|
||||
/proc/swaps) so that it can be used for suspending.
|
||||
|
||||
Note that if the swap file used for suspending is deleted and recreated,
|
||||
the location of its header need not be the same as before. Thus every time
|
||||
this happens the value of the "resume_offset=" kernel command line parameter
|
||||
has to be updated.
|
||||
138
Documentation/power/swsusp-dmcrypt.txt
Normal file
138
Documentation/power/swsusp-dmcrypt.txt
Normal file
@@ -0,0 +1,138 @@
|
||||
Author: Andreas Steinmetz <ast@domdv.de>
|
||||
|
||||
|
||||
How to use dm-crypt and swsusp together:
|
||||
========================================
|
||||
|
||||
Some prerequisites:
|
||||
You know how dm-crypt works. If not, visit the following web page:
|
||||
http://www.saout.de/misc/dm-crypt/
|
||||
You have read Documentation/power/swsusp.txt and understand it.
|
||||
You did read Documentation/initrd.txt and know how an initrd works.
|
||||
You know how to create or how to modify an initrd.
|
||||
|
||||
Now your system is properly set up, your disk is encrypted except for
|
||||
the swap device(s) and the boot partition which may contain a mini
|
||||
system for crypto setup and/or rescue purposes. You may even have
|
||||
an initrd that does your current crypto setup already.
|
||||
|
||||
At this point you want to encrypt your swap, too. Still you want to
|
||||
be able to suspend using swsusp. This, however, means that you
|
||||
have to be able to either enter a passphrase or that you read
|
||||
the key(s) from an external device like a pcmcia flash disk
|
||||
or an usb stick prior to resume. So you need an initrd, that sets
|
||||
up dm-crypt and then asks swsusp to resume from the encrypted
|
||||
swap device.
|
||||
|
||||
The most important thing is that you set up dm-crypt in such
|
||||
a way that the swap device you suspend to/resume from has
|
||||
always the same major/minor within the initrd as well as
|
||||
within your running system. The easiest way to achieve this is
|
||||
to always set up this swap device first with dmsetup, so that
|
||||
it will always look like the following:
|
||||
|
||||
brw------- 1 root root 254, 0 Jul 28 13:37 /dev/mapper/swap0
|
||||
|
||||
Now set up your kernel to use /dev/mapper/swap0 as the default
|
||||
resume partition, so your kernel .config contains:
|
||||
|
||||
CONFIG_PM_STD_PARTITION="/dev/mapper/swap0"
|
||||
|
||||
Prepare your boot loader to use the initrd you will create or
|
||||
modify. For lilo the simplest setup looks like the following
|
||||
lines:
|
||||
|
||||
image=/boot/vmlinuz
|
||||
initrd=/boot/initrd.gz
|
||||
label=linux
|
||||
append="root=/dev/ram0 init=/linuxrc rw"
|
||||
|
||||
Finally you need to create or modify your initrd. Lets assume
|
||||
you create an initrd that reads the required dm-crypt setup
|
||||
from a pcmcia flash disk card. The card is formatted with an ext2
|
||||
fs which resides on /dev/hde1 when the card is inserted. The
|
||||
card contains at least the encrypted swap setup in a file
|
||||
named "swapkey". /etc/fstab of your initrd contains something
|
||||
like the following:
|
||||
|
||||
/dev/hda1 /mnt ext3 ro 0 0
|
||||
none /proc proc defaults,noatime,nodiratime 0 0
|
||||
none /sys sysfs defaults,noatime,nodiratime 0 0
|
||||
|
||||
/dev/hda1 contains an unencrypted mini system that sets up all
|
||||
of your crypto devices, again by reading the setup from the
|
||||
pcmcia flash disk. What follows now is a /linuxrc for your
|
||||
initrd that allows you to resume from encrypted swap and that
|
||||
continues boot with your mini system on /dev/hda1 if resume
|
||||
does not happen:
|
||||
|
||||
#!/bin/sh
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
mount /proc
|
||||
mount /sys
|
||||
mapped=0
|
||||
noresume=`grep -c noresume /proc/cmdline`
|
||||
if [ "$*" != "" ]
|
||||
then
|
||||
noresume=1
|
||||
fi
|
||||
dmesg -n 1
|
||||
/sbin/cardmgr -q
|
||||
for i in 1 2 3 4 5 6 7 8 9 0
|
||||
do
|
||||
if [ -f /proc/ide/hde/media ]
|
||||
then
|
||||
usleep 500000
|
||||
mount -t ext2 -o ro /dev/hde1 /mnt
|
||||
if [ -f /mnt/swapkey ]
|
||||
then
|
||||
dmsetup create swap0 /mnt/swapkey > /dev/null 2>&1 && mapped=1
|
||||
fi
|
||||
umount /mnt
|
||||
break
|
||||
fi
|
||||
usleep 500000
|
||||
done
|
||||
killproc /sbin/cardmgr
|
||||
dmesg -n 6
|
||||
if [ $mapped = 1 ]
|
||||
then
|
||||
if [ $noresume != 0 ]
|
||||
then
|
||||
mkswap /dev/mapper/swap0 > /dev/null 2>&1
|
||||
fi
|
||||
echo 254:0 > /sys/power/resume
|
||||
dmsetup remove swap0
|
||||
fi
|
||||
umount /sys
|
||||
mount /mnt
|
||||
umount /proc
|
||||
cd /mnt
|
||||
pivot_root . mnt
|
||||
mount /proc
|
||||
umount -l /mnt
|
||||
umount /proc
|
||||
exec chroot . /sbin/init $* < dev/console > dev/console 2>&1
|
||||
|
||||
Please don't mind the weird loop above, busybox's msh doesn't know
|
||||
the let statement. Now, what is happening in the script?
|
||||
First we have to decide if we want to try to resume, or not.
|
||||
We will not resume if booting with "noresume" or any parameters
|
||||
for init like "single" or "emergency" as boot parameters.
|
||||
|
||||
Then we need to set up dmcrypt with the setup data from the
|
||||
pcmcia flash disk. If this succeeds we need to reset the swap
|
||||
device if we don't want to resume. The line "echo 254:0 > /sys/power/resume"
|
||||
then attempts to resume from the first device mapper device.
|
||||
Note that it is important to set the device in /sys/power/resume,
|
||||
regardless if resuming or not, otherwise later suspend will fail.
|
||||
If resume starts, script execution terminates here.
|
||||
|
||||
Otherwise we just remove the encrypted swap device and leave it to the
|
||||
mini system on /dev/hda1 to set the whole crypto up (it is up to
|
||||
you to modify this to your taste).
|
||||
|
||||
What then follows is the well known process to change the root
|
||||
file system and continue booting from there. I prefer to unmount
|
||||
the initrd prior to continue booting but it is up to you to modify
|
||||
this.
|
||||
413
Documentation/power/swsusp.txt
Normal file
413
Documentation/power/swsusp.txt
Normal file
@@ -0,0 +1,413 @@
|
||||
Some warnings, first.
|
||||
|
||||
* BIG FAT WARNING *********************************************************
|
||||
*
|
||||
* If you touch anything on disk between suspend and resume...
|
||||
* ...kiss your data goodbye.
|
||||
*
|
||||
* If you do resume from initrd after your filesystems are mounted...
|
||||
* ...bye bye root partition.
|
||||
* [this is actually same case as above]
|
||||
*
|
||||
* If you have unsupported (*) devices using DMA, you may have some
|
||||
* problems. If your disk driver does not support suspend... (IDE does),
|
||||
* it may cause some problems, too. If you change kernel command line
|
||||
* between suspend and resume, it may do something wrong. If you change
|
||||
* your hardware while system is suspended... well, it was not good idea;
|
||||
* but it will probably only crash.
|
||||
*
|
||||
* (*) suspend/resume support is needed to make it safe.
|
||||
*
|
||||
* If you have any filesystems on USB devices mounted before software suspend,
|
||||
* they won't be accessible after resume and you may lose data, as though
|
||||
* you have unplugged the USB devices with mounted filesystems on them;
|
||||
* see the FAQ below for details. (This is not true for more traditional
|
||||
* power states like "standby", which normally don't turn USB off.)
|
||||
|
||||
You need to append resume=/dev/your_swap_partition to kernel command
|
||||
line. Then you suspend by
|
||||
|
||||
echo shutdown > /sys/power/disk; echo disk > /sys/power/state
|
||||
|
||||
. If you feel ACPI works pretty well on your system, you might try
|
||||
|
||||
echo platform > /sys/power/disk; echo disk > /sys/power/state
|
||||
|
||||
. If you have SATA disks, you'll need recent kernels with SATA suspend
|
||||
support. For suspend and resume to work, make sure your disk drivers
|
||||
are built into kernel -- not modules. [There's way to make
|
||||
suspend/resume with modular disk drivers, see FAQ, but you probably
|
||||
should not do that.]
|
||||
|
||||
If you want to limit the suspend image size to N bytes, do
|
||||
|
||||
echo N > /sys/power/image_size
|
||||
|
||||
before suspend (it is limited to 500 MB by default).
|
||||
|
||||
|
||||
Article about goals and implementation of Software Suspend for Linux
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Author: G<><47>bor Kuti
|
||||
Last revised: 2003-10-20 by Pavel Machek
|
||||
|
||||
Idea and goals to achieve
|
||||
|
||||
Nowadays it is common in several laptops that they have a suspend button. It
|
||||
saves the state of the machine to a filesystem or to a partition and switches
|
||||
to standby mode. Later resuming the machine the saved state is loaded back to
|
||||
ram and the machine can continue its work. It has two real benefits. First we
|
||||
save ourselves the time machine goes down and later boots up, energy costs
|
||||
are real high when running from batteries. The other gain is that we don't have to
|
||||
interrupt our programs so processes that are calculating something for a long
|
||||
time shouldn't need to be written interruptible.
|
||||
|
||||
swsusp saves the state of the machine into active swaps and then reboots or
|
||||
powerdowns. You must explicitly specify the swap partition to resume from with
|
||||
``resume='' kernel option. If signature is found it loads and restores saved
|
||||
state. If the option ``noresume'' is specified as a boot parameter, it skips
|
||||
the resuming.
|
||||
|
||||
In the meantime while the system is suspended you should not add/remove any
|
||||
of the hardware, write to the filesystems, etc.
|
||||
|
||||
Sleep states summary
|
||||
====================
|
||||
|
||||
There are three different interfaces you can use, /proc/acpi should
|
||||
work like this:
|
||||
|
||||
In a really perfect world:
|
||||
echo 1 > /proc/acpi/sleep # for standby
|
||||
echo 2 > /proc/acpi/sleep # for suspend to ram
|
||||
echo 3 > /proc/acpi/sleep # for suspend to ram, but with more power conservative
|
||||
echo 4 > /proc/acpi/sleep # for suspend to disk
|
||||
echo 5 > /proc/acpi/sleep # for shutdown unfriendly the system
|
||||
|
||||
and perhaps
|
||||
echo 4b > /proc/acpi/sleep # for suspend to disk via s4bios
|
||||
|
||||
Frequently Asked Questions
|
||||
==========================
|
||||
|
||||
Q: well, suspending a server is IMHO a really stupid thing,
|
||||
but... (Diego Zuccato):
|
||||
|
||||
A: You bought new UPS for your server. How do you install it without
|
||||
bringing machine down? Suspend to disk, rearrange power cables,
|
||||
resume.
|
||||
|
||||
You have your server on UPS. Power died, and UPS is indicating 30
|
||||
seconds to failure. What do you do? Suspend to disk.
|
||||
|
||||
|
||||
Q: Maybe I'm missing something, but why don't the regular I/O paths work?
|
||||
|
||||
A: We do use the regular I/O paths. However we cannot restore the data
|
||||
to its original location as we load it. That would create an
|
||||
inconsistent kernel state which would certainly result in an oops.
|
||||
Instead, we load the image into unused memory and then atomically copy
|
||||
it back to it original location. This implies, of course, a maximum
|
||||
image size of half the amount of memory.
|
||||
|
||||
There are two solutions to this:
|
||||
|
||||
* require half of memory to be free during suspend. That way you can
|
||||
read "new" data onto free spots, then cli and copy
|
||||
|
||||
* assume we had special "polling" ide driver that only uses memory
|
||||
between 0-640KB. That way, I'd have to make sure that 0-640KB is free
|
||||
during suspending, but otherwise it would work...
|
||||
|
||||
suspend2 shares this fundamental limitation, but does not include user
|
||||
data and disk caches into "used memory" by saving them in
|
||||
advance. That means that the limitation goes away in practice.
|
||||
|
||||
Q: Does linux support ACPI S4?
|
||||
|
||||
A: Yes. That's what echo platform > /sys/power/disk does.
|
||||
|
||||
Q: What is 'suspend2'?
|
||||
|
||||
A: suspend2 is 'Software Suspend 2', a forked implementation of
|
||||
suspend-to-disk which is available as separate patches for 2.4 and 2.6
|
||||
kernels from swsusp.sourceforge.net. It includes support for SMP, 4GB
|
||||
highmem and preemption. It also has a extensible architecture that
|
||||
allows for arbitrary transformations on the image (compression,
|
||||
encryption) and arbitrary backends for writing the image (eg to swap
|
||||
or an NFS share[Work In Progress]). Questions regarding suspend2
|
||||
should be sent to the mailing list available through the suspend2
|
||||
website, and not to the Linux Kernel Mailing List. We are working
|
||||
toward merging suspend2 into the mainline kernel.
|
||||
|
||||
Q: A kernel thread must voluntarily freeze itself (call 'refrigerator').
|
||||
I found some kernel threads that don't do it, and they don't freeze
|
||||
so the system can't sleep. Is this a known behavior?
|
||||
|
||||
A: All such kernel threads need to be fixed, one by one. Select the
|
||||
place where the thread is safe to be frozen (no kernel semaphores
|
||||
should be held at that point and it must be safe to sleep there), and
|
||||
add:
|
||||
|
||||
try_to_freeze();
|
||||
|
||||
If the thread is needed for writing the image to storage, you should
|
||||
instead set the PF_NOFREEZE process flag when creating the thread (and
|
||||
be very careful).
|
||||
|
||||
|
||||
Q: What is the difference between "platform", "shutdown" and
|
||||
"firmware" in /sys/power/disk?
|
||||
|
||||
A:
|
||||
|
||||
shutdown: save state in linux, then tell bios to powerdown
|
||||
|
||||
platform: save state in linux, then tell bios to powerdown and blink
|
||||
"suspended led"
|
||||
|
||||
firmware: tell bios to save state itself [needs BIOS-specific suspend
|
||||
partition, and has very little to do with swsusp]
|
||||
|
||||
"platform" is actually right thing to do, but "shutdown" is most
|
||||
reliable.
|
||||
|
||||
Q: I do not understand why you have such strong objections to idea of
|
||||
selective suspend.
|
||||
|
||||
A: Do selective suspend during runtime power management, that's okay. But
|
||||
it's useless for suspend-to-disk. (And I do not see how you could use
|
||||
it for suspend-to-ram, I hope you do not want that).
|
||||
|
||||
Lets see, so you suggest to
|
||||
|
||||
* SUSPEND all but swap device and parents
|
||||
* Snapshot
|
||||
* Write image to disk
|
||||
* SUSPEND swap device and parents
|
||||
* Powerdown
|
||||
|
||||
Oh no, that does not work, if swap device or its parents uses DMA,
|
||||
you've corrupted data. You'd have to do
|
||||
|
||||
* SUSPEND all but swap device and parents
|
||||
* FREEZE swap device and parents
|
||||
* Snapshot
|
||||
* UNFREEZE swap device and parents
|
||||
* Write
|
||||
* SUSPEND swap device and parents
|
||||
|
||||
Which means that you still need that FREEZE state, and you get more
|
||||
complicated code. (And I have not yet introduce details like system
|
||||
devices).
|
||||
|
||||
Q: There don't seem to be any generally useful behavioral
|
||||
distinctions between SUSPEND and FREEZE.
|
||||
|
||||
A: Doing SUSPEND when you are asked to do FREEZE is always correct,
|
||||
but it may be unneccessarily slow. If you want your driver to stay simple,
|
||||
slowness may not matter to you. It can always be fixed later.
|
||||
|
||||
For devices like disk it does matter, you do not want to spindown for
|
||||
FREEZE.
|
||||
|
||||
Q: After resuming, system is paging heavily, leading to very bad interactivity.
|
||||
|
||||
A: Try running
|
||||
|
||||
cat `cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u` > /dev/null
|
||||
|
||||
after resume. swapoff -a; swapon -a may also be useful.
|
||||
|
||||
Q: What happens to devices during swsusp? They seem to be resumed
|
||||
during system suspend?
|
||||
|
||||
A: That's correct. We need to resume them if we want to write image to
|
||||
disk. Whole sequence goes like
|
||||
|
||||
Suspend part
|
||||
~~~~~~~~~~~~
|
||||
running system, user asks for suspend-to-disk
|
||||
|
||||
user processes are stopped
|
||||
|
||||
suspend(PMSG_FREEZE): devices are frozen so that they don't interfere
|
||||
with state snapshot
|
||||
|
||||
state snapshot: copy of whole used memory is taken with interrupts disabled
|
||||
|
||||
resume(): devices are woken up so that we can write image to swap
|
||||
|
||||
write image to swap
|
||||
|
||||
suspend(PMSG_SUSPEND): suspend devices so that we can power off
|
||||
|
||||
turn the power off
|
||||
|
||||
Resume part
|
||||
~~~~~~~~~~~
|
||||
(is actually pretty similar)
|
||||
|
||||
running system, user asks for suspend-to-disk
|
||||
|
||||
user processes are stopped (in common case there are none, but with resume-from-initrd, noone knows)
|
||||
|
||||
read image from disk
|
||||
|
||||
suspend(PMSG_FREEZE): devices are frozen so that they don't interfere
|
||||
with image restoration
|
||||
|
||||
image restoration: rewrite memory with image
|
||||
|
||||
resume(): devices are woken up so that system can continue
|
||||
|
||||
thaw all user processes
|
||||
|
||||
Q: What is this 'Encrypt suspend image' for?
|
||||
|
||||
A: First of all: it is not a replacement for dm-crypt encrypted swap.
|
||||
It cannot protect your computer while it is suspended. Instead it does
|
||||
protect from leaking sensitive data after resume from suspend.
|
||||
|
||||
Think of the following: you suspend while an application is running
|
||||
that keeps sensitive data in memory. The application itself prevents
|
||||
the data from being swapped out. Suspend, however, must write these
|
||||
data to swap to be able to resume later on. Without suspend encryption
|
||||
your sensitive data are then stored in plaintext on disk. This means
|
||||
that after resume your sensitive data are accessible to all
|
||||
applications having direct access to the swap device which was used
|
||||
for suspend. If you don't need swap after resume these data can remain
|
||||
on disk virtually forever. Thus it can happen that your system gets
|
||||
broken in weeks later and sensitive data which you thought were
|
||||
encrypted and protected are retrieved and stolen from the swap device.
|
||||
To prevent this situation you should use 'Encrypt suspend image'.
|
||||
|
||||
During suspend a temporary key is created and this key is used to
|
||||
encrypt the data written to disk. When, during resume, the data was
|
||||
read back into memory the temporary key is destroyed which simply
|
||||
means that all data written to disk during suspend are then
|
||||
inaccessible so they can't be stolen later on. The only thing that
|
||||
you must then take care of is that you call 'mkswap' for the swap
|
||||
partition used for suspend as early as possible during regular
|
||||
boot. This asserts that any temporary key from an oopsed suspend or
|
||||
from a failed or aborted resume is erased from the swap device.
|
||||
|
||||
As a rule of thumb use encrypted swap to protect your data while your
|
||||
system is shut down or suspended. Additionally use the encrypted
|
||||
suspend image to prevent sensitive data from being stolen after
|
||||
resume.
|
||||
|
||||
Q: Can I suspend to a swap file?
|
||||
|
||||
A: Generally, yes, you can. However, it requires you to use the "resume=" and
|
||||
"resume_offset=" kernel command line parameters, so the resume from a swap file
|
||||
cannot be initiated from an initrd or initramfs image. See
|
||||
swsusp-and-swap-files.txt for details.
|
||||
|
||||
Q: Is there a maximum system RAM size that is supported by swsusp?
|
||||
|
||||
A: It should work okay with highmem.
|
||||
|
||||
Q: Does swsusp (to disk) use only one swap partition or can it use
|
||||
multiple swap partitions (aggregate them into one logical space)?
|
||||
|
||||
A: Only one swap partition, sorry.
|
||||
|
||||
Q: If my application(s) causes lots of memory & swap space to be used
|
||||
(over half of the total system RAM), is it correct that it is likely
|
||||
to be useless to try to suspend to disk while that app is running?
|
||||
|
||||
A: No, it should work okay, as long as your app does not mlock()
|
||||
it. Just prepare big enough swap partition.
|
||||
|
||||
Q: What information is useful for debugging suspend-to-disk problems?
|
||||
|
||||
A: Well, last messages on the screen are always useful. If something
|
||||
is broken, it is usually some kernel driver, therefore trying with as
|
||||
little as possible modules loaded helps a lot. I also prefer people to
|
||||
suspend from console, preferably without X running. Booting with
|
||||
init=/bin/bash, then swapon and starting suspend sequence manually
|
||||
usually does the trick. Then it is good idea to try with latest
|
||||
vanilla kernel.
|
||||
|
||||
Q: How can distributions ship a swsusp-supporting kernel with modular
|
||||
disk drivers (especially SATA)?
|
||||
|
||||
A: Well, it can be done, load the drivers, then do echo into
|
||||
/sys/power/disk/resume file from initrd. Be sure not to mount
|
||||
anything, not even read-only mount, or you are going to lose your
|
||||
data.
|
||||
|
||||
Q: How do I make suspend more verbose?
|
||||
|
||||
A: If you want to see any non-error kernel messages on the virtual
|
||||
terminal the kernel switches to during suspend, you have to set the
|
||||
kernel console loglevel to at least 4 (KERN_WARNING), for example by
|
||||
doing
|
||||
|
||||
# save the old loglevel
|
||||
read LOGLEVEL DUMMY < /proc/sys/kernel/printk
|
||||
# set the loglevel so we see the progress bar.
|
||||
# if the level is higher than needed, we leave it alone.
|
||||
if [ $LOGLEVEL -lt 5 ]; then
|
||||
echo 5 > /proc/sys/kernel/printk
|
||||
fi
|
||||
|
||||
IMG_SZ=0
|
||||
read IMG_SZ < /sys/power/image_size
|
||||
echo -n disk > /sys/power/state
|
||||
RET=$?
|
||||
#
|
||||
# the logic here is:
|
||||
# if image_size > 0 (without kernel support, IMG_SZ will be zero),
|
||||
# then try again with image_size set to zero.
|
||||
if [ $RET -ne 0 -a $IMG_SZ -ne 0 ]; then # try again with minimal image size
|
||||
echo 0 > /sys/power/image_size
|
||||
echo -n disk > /sys/power/state
|
||||
RET=$?
|
||||
fi
|
||||
|
||||
# restore previous loglevel
|
||||
echo $LOGLEVEL > /proc/sys/kernel/printk
|
||||
exit $RET
|
||||
|
||||
Q: Is this true that if I have a mounted filesystem on a USB device and
|
||||
I suspend to disk, I can lose data unless the filesystem has been mounted
|
||||
with "sync"?
|
||||
|
||||
A: That's right ... if you disconnect that device, you may lose data.
|
||||
In fact, even with "-o sync" you can lose data if your programs have
|
||||
information in buffers they haven't written out to a disk you disconnect,
|
||||
or if you disconnect before the device finished saving data you wrote.
|
||||
|
||||
Software suspend normally powers down USB controllers, which is equivalent
|
||||
to disconnecting all USB devices attached to your system.
|
||||
|
||||
Your system might well support low-power modes for its USB controllers
|
||||
while the system is asleep, maintaining the connection, using true sleep
|
||||
modes like "suspend-to-RAM" or "standby". (Don't write "disk" to the
|
||||
/sys/power/state file; write "standby" or "mem".) We've not seen any
|
||||
hardware that can use these modes through software suspend, although in
|
||||
theory some systems might support "platform" or "firmware" modes that
|
||||
won't break the USB connections.
|
||||
|
||||
Remember that it's always a bad idea to unplug a disk drive containing a
|
||||
mounted filesystem. That's true even when your system is asleep! The
|
||||
safest thing is to unmount all filesystems on removable media (such USB,
|
||||
Firewire, CompactFlash, MMC, external SATA, or even IDE hotplug bays)
|
||||
before suspending; then remount them after resuming.
|
||||
|
||||
Q: I upgraded the kernel from 2.6.15 to 2.6.16. Both kernels were
|
||||
compiled with the similar configuration files. Anyway I found that
|
||||
suspend to disk (and resume) is much slower on 2.6.16 compared to
|
||||
2.6.15. Any idea for why that might happen or how can I speed it up?
|
||||
|
||||
A: This is because the size of the suspend image is now greater than
|
||||
for 2.6.15 (by saving more data we can get more responsive system
|
||||
after resume).
|
||||
|
||||
There's the /sys/power/image_size knob that controls the size of the
|
||||
image. If you set it to 0 (eg. by echo 0 > /sys/power/image_size as
|
||||
root), the 2.6.15 behavior should be restored. If it is still too
|
||||
slow, take a look at suspend.sf.net -- userland suspend is faster and
|
||||
supports LZF compression to speed it up further.
|
||||
27
Documentation/power/tricks.txt
Normal file
27
Documentation/power/tricks.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
swsusp/S3 tricks
|
||||
~~~~~~~~~~~~~~~~
|
||||
Pavel Machek <pavel@suse.cz>
|
||||
|
||||
If you want to trick swsusp/S3 into working, you might want to try:
|
||||
|
||||
* go with minimal config, turn off drivers like USB, AGP you don't
|
||||
really need
|
||||
|
||||
* turn off APIC and preempt
|
||||
|
||||
* use ext2. At least it has working fsck. [If something seems to go
|
||||
wrong, force fsck when you have a chance]
|
||||
|
||||
* turn off modules
|
||||
|
||||
* use vga text console, shut down X. [If you really want X, you might
|
||||
want to try vesafb later]
|
||||
|
||||
* try running as few processes as possible, preferably go to single
|
||||
user mode.
|
||||
|
||||
* due to video issues, swsusp should be easier to get working than
|
||||
S3. Try that first.
|
||||
|
||||
When you make it work, try to find out what exactly was it that broke
|
||||
suspend, and preferably fix that.
|
||||
187
Documentation/power/userland-swsusp.txt
Normal file
187
Documentation/power/userland-swsusp.txt
Normal file
@@ -0,0 +1,187 @@
|
||||
Documentation for userland software suspend interface
|
||||
(C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
|
||||
|
||||
First, the warnings at the beginning of swsusp.txt still apply.
|
||||
|
||||
Second, you should read the FAQ in swsusp.txt _now_ if you have not
|
||||
done it already.
|
||||
|
||||
Now, to use the userland interface for software suspend you need special
|
||||
utilities that will read/write the system memory snapshot from/to the
|
||||
kernel. Such utilities are available, for example, from
|
||||
<http://suspend.sourceforge.net>. You may want to have a look at them if you
|
||||
are going to develop your own suspend/resume utilities.
|
||||
|
||||
The interface consists of a character device providing the open(),
|
||||
release(), read(), and write() operations as well as several ioctl()
|
||||
commands defined in kernel/power/power.h. The major and minor
|
||||
numbers of the device are, respectively, 10 and 231, and they can
|
||||
be read from /sys/class/misc/snapshot/dev.
|
||||
|
||||
The device can be open either for reading or for writing. If open for
|
||||
reading, it is considered to be in the suspend mode. Otherwise it is
|
||||
assumed to be in the resume mode. The device cannot be open for simultaneous
|
||||
reading and writing. It is also impossible to have the device open more than
|
||||
once at a time.
|
||||
|
||||
The ioctl() commands recognized by the device are:
|
||||
|
||||
SNAPSHOT_FREEZE - freeze user space processes (the current process is
|
||||
not frozen); this is required for SNAPSHOT_ATOMIC_SNAPSHOT
|
||||
and SNAPSHOT_ATOMIC_RESTORE to succeed
|
||||
|
||||
SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE
|
||||
|
||||
SNAPSHOT_ATOMIC_SNAPSHOT - create a snapshot of the system memory; the
|
||||
last argument of ioctl() should be a pointer to an int variable,
|
||||
the value of which will indicate whether the call returned after
|
||||
creating the snapshot (1) or after restoring the system memory state
|
||||
from it (0) (after resume the system finds itself finishing the
|
||||
SNAPSHOT_ATOMIC_SNAPSHOT ioctl() again); after the snapshot
|
||||
has been created the read() operation can be used to transfer
|
||||
it out of the kernel
|
||||
|
||||
SNAPSHOT_ATOMIC_RESTORE - restore the system memory state from the
|
||||
uploaded snapshot image; before calling it you should transfer
|
||||
the system memory snapshot back to the kernel using the write()
|
||||
operation; this call will not succeed if the snapshot
|
||||
image is not available to the kernel
|
||||
|
||||
SNAPSHOT_FREE - free memory allocated for the snapshot image
|
||||
|
||||
SNAPSHOT_SET_IMAGE_SIZE - set the preferred maximum size of the image
|
||||
(the kernel will do its best to ensure the image size will not exceed
|
||||
this number, but if it turns out to be impossible, the kernel will
|
||||
create the smallest image possible)
|
||||
|
||||
SNAPSHOT_AVAIL_SWAP - return the amount of available swap in bytes (the last
|
||||
argument should be a pointer to an unsigned int variable that will
|
||||
contain the result if the call is successful).
|
||||
|
||||
SNAPSHOT_GET_SWAP_PAGE - allocate a swap page from the resume partition
|
||||
(the last argument should be a pointer to a loff_t variable that
|
||||
will contain the swap page offset if the call is successful)
|
||||
|
||||
SNAPSHOT_FREE_SWAP_PAGES - free all swap pages allocated with
|
||||
SNAPSHOT_GET_SWAP_PAGE
|
||||
|
||||
SNAPSHOT_SET_SWAP_FILE - set the resume partition (the last ioctl() argument
|
||||
should specify the device's major and minor numbers in the old
|
||||
two-byte format, as returned by the stat() function in the .st_rdev
|
||||
member of the stat structure)
|
||||
|
||||
SNAPSHOT_SET_SWAP_AREA - set the resume partition and the offset (in <PAGE_SIZE>
|
||||
units) from the beginning of the partition at which the swap header is
|
||||
located (the last ioctl() argument should point to a struct
|
||||
resume_swap_area, as defined in kernel/power/power.h, containing the
|
||||
resume device specification, as for the SNAPSHOT_SET_SWAP_FILE ioctl(),
|
||||
and the offset); for swap partitions the offset is always 0, but it is
|
||||
different to zero for swap files (please see
|
||||
Documentation/swsusp-and-swap-files.txt for details).
|
||||
The SNAPSHOT_SET_SWAP_AREA ioctl() is considered as a replacement for
|
||||
SNAPSHOT_SET_SWAP_FILE which is regarded as obsolete. It is
|
||||
recommended to always use this call, because the code to set the resume
|
||||
partition may be removed from future kernels
|
||||
|
||||
SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to
|
||||
immediately enter the suspend-to-RAM state, so this call must always
|
||||
be preceded by the SNAPSHOT_FREEZE call and it is also necessary
|
||||
to use the SNAPSHOT_UNFREEZE call after the system wakes up. This call
|
||||
is needed to implement the suspend-to-both mechanism in which the
|
||||
suspend image is first created, as though the system had been suspended
|
||||
to disk, and then the system is suspended to RAM (this makes it possible
|
||||
to resume the system from RAM if there's enough battery power or restore
|
||||
its state on the basis of the saved suspend image otherwise)
|
||||
|
||||
SNAPSHOT_PMOPS - enable the usage of the pmops->prepare, pmops->enter and
|
||||
pmops->finish methods (the in-kernel swsusp knows these as the "platform
|
||||
method") which are needed on many machines to (among others) speed up
|
||||
the resume by letting the BIOS skip some steps or to let the system
|
||||
recognise the correct state of the hardware after the resume (in
|
||||
particular on many machines this ensures that unplugged AC
|
||||
adapters get correctly detected and that kacpid does not run wild after
|
||||
the resume). The last ioctl() argument can take one of the three
|
||||
values, defined in kernel/power/power.h:
|
||||
PMOPS_PREPARE - make the kernel carry out the
|
||||
pm_ops->prepare(PM_SUSPEND_DISK) operation
|
||||
PMOPS_ENTER - make the kernel power off the system by calling
|
||||
pm_ops->enter(PM_SUSPEND_DISK)
|
||||
PMOPS_FINISH - make the kernel carry out the
|
||||
pm_ops->finish(PM_SUSPEND_DISK) operation
|
||||
|
||||
The device's read() operation can be used to transfer the snapshot image from
|
||||
the kernel. It has the following limitations:
|
||||
- you cannot read() more than one virtual memory page at a time
|
||||
- read()s accross page boundaries are impossible (ie. if ypu read() 1/2 of
|
||||
a page in the previous call, you will only be able to read()
|
||||
_at_ _most_ 1/2 of the page in the next call)
|
||||
|
||||
The device's write() operation is used for uploading the system memory snapshot
|
||||
into the kernel. It has the same limitations as the read() operation.
|
||||
|
||||
The release() operation frees all memory allocated for the snapshot image
|
||||
and all swap pages allocated with SNAPSHOT_GET_SWAP_PAGE (if any).
|
||||
Thus it is not necessary to use either SNAPSHOT_FREE or
|
||||
SNAPSHOT_FREE_SWAP_PAGES before closing the device (in fact it will also
|
||||
unfreeze user space processes frozen by SNAPSHOT_UNFREEZE if they are
|
||||
still frozen when the device is being closed).
|
||||
|
||||
Currently it is assumed that the userland utilities reading/writing the
|
||||
snapshot image from/to the kernel will use a swap parition, called the resume
|
||||
partition, or a swap file as storage space (if a swap file is used, the resume
|
||||
partition is the partition that holds this file). However, this is not really
|
||||
required, as they can use, for example, a special (blank) suspend partition or
|
||||
a file on a partition that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and
|
||||
mounted afterwards.
|
||||
|
||||
These utilities SHOULD NOT make any assumptions regarding the ordering of
|
||||
data within the snapshot image, except for the image header that MAY be
|
||||
assumed to start with an swsusp_info structure, as specified in
|
||||
kernel/power/power.h. This structure MAY be used by the userland utilities
|
||||
to obtain some information about the snapshot image, such as the size
|
||||
of the snapshot image, including the metadata and the header itself,
|
||||
contained in the .size member of swsusp_info.
|
||||
|
||||
The snapshot image MUST be written to the kernel unaltered (ie. all of the image
|
||||
data, metadata and header MUST be written in _exactly_ the same amount, form
|
||||
and order in which they have been read). Otherwise, the behavior of the
|
||||
resumed system may be totally unpredictable.
|
||||
|
||||
While executing SNAPSHOT_ATOMIC_RESTORE the kernel checks if the
|
||||
structure of the snapshot image is consistent with the information stored
|
||||
in the image header. If any inconsistencies are detected,
|
||||
SNAPSHOT_ATOMIC_RESTORE will not succeed. Still, this is not a fool-proof
|
||||
mechanism and the userland utilities using the interface SHOULD use additional
|
||||
means, such as checksums, to ensure the integrity of the snapshot image.
|
||||
|
||||
The suspending and resuming utilities MUST lock themselves in memory,
|
||||
preferrably using mlockall(), before calling SNAPSHOT_FREEZE.
|
||||
|
||||
The suspending utility MUST check the value stored by SNAPSHOT_ATOMIC_SNAPSHOT
|
||||
in the memory location pointed to by the last argument of ioctl() and proceed
|
||||
in accordance with it:
|
||||
1. If the value is 1 (ie. the system memory snapshot has just been
|
||||
created and the system is ready for saving it):
|
||||
(a) The suspending utility MUST NOT close the snapshot device
|
||||
_unless_ the whole suspend procedure is to be cancelled, in
|
||||
which case, if the snapshot image has already been saved, the
|
||||
suspending utility SHOULD destroy it, preferrably by zapping
|
||||
its header. If the suspend is not to be cancelled, the
|
||||
system MUST be powered off or rebooted after the snapshot
|
||||
image has been saved.
|
||||
(b) The suspending utility SHOULD NOT attempt to perform any
|
||||
file system operations (including reads) on the file systems
|
||||
that were mounted before SNAPSHOT_ATOMIC_SNAPSHOT has been
|
||||
called. However, it MAY mount a file system that was not
|
||||
mounted at that time and perform some operations on it (eg.
|
||||
use it for saving the image).
|
||||
2. If the value is 0 (ie. the system state has just been restored from
|
||||
the snapshot image), the suspending utility MUST close the snapshot
|
||||
device. Afterwards it will be treated as a regular userland process,
|
||||
so it need not exit.
|
||||
|
||||
The resuming utility SHOULD NOT attempt to mount any file systems that could
|
||||
be mounted before suspend and SHOULD NOT attempt to perform any operations
|
||||
involving such file systems.
|
||||
|
||||
For details, please refer to the source code.
|
||||
185
Documentation/power/video.txt
Normal file
185
Documentation/power/video.txt
Normal file
@@ -0,0 +1,185 @@
|
||||
|
||||
Video issues with S3 resume
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
2003-2006, Pavel Machek
|
||||
|
||||
During S3 resume, hardware needs to be reinitialized. For most
|
||||
devices, this is easy, and kernel driver knows how to do
|
||||
it. Unfortunately there's one exception: video card. Those are usually
|
||||
initialized by BIOS, and kernel does not have enough information to
|
||||
boot video card. (Kernel usually does not even contain video card
|
||||
driver -- vesafb and vgacon are widely used).
|
||||
|
||||
This is not problem for swsusp, because during swsusp resume, BIOS is
|
||||
run normally so video card is normally initialized. It should not be
|
||||
problem for S1 standby, because hardware should retain its state over
|
||||
that.
|
||||
|
||||
We either have to run video BIOS during early resume, or interpret it
|
||||
using vbetool later, or maybe nothing is necessary on particular
|
||||
system because video state is preserved. Unfortunately different
|
||||
methods work on different systems, and no known method suits all of
|
||||
them.
|
||||
|
||||
Userland application called s2ram has been developed; it contains long
|
||||
whitelist of systems, and automatically selects working method for a
|
||||
given system. It can be downloaded from CVS at
|
||||
www.sf.net/projects/suspend . If you get a system that is not in the
|
||||
whitelist, please try to find a working solution, and submit whitelist
|
||||
entry so that work does not need to be repeated.
|
||||
|
||||
Currently, VBE_SAVE method (6 below) works on most
|
||||
systems. Unfortunately, vbetool only runs after userland is resumed,
|
||||
so it makes debugging of early resume problems
|
||||
hard/impossible. Methods that do not rely on userland are preferable.
|
||||
|
||||
Details
|
||||
~~~~~~~
|
||||
|
||||
There are a few types of systems where video works after S3 resume:
|
||||
|
||||
(1) systems where video state is preserved over S3.
|
||||
|
||||
(2) systems where it is possible to call the video BIOS during S3
|
||||
resume. Unfortunately, it is not correct to call the video BIOS at
|
||||
that point, but it happens to work on some machines. Use
|
||||
acpi_sleep=s3_bios.
|
||||
|
||||
(3) systems that initialize video card into vga text mode and where
|
||||
the BIOS works well enough to be able to set video mode. Use
|
||||
acpi_sleep=s3_mode on these.
|
||||
|
||||
(4) on some systems s3_bios kicks video into text mode, and
|
||||
acpi_sleep=s3_bios,s3_mode is needed.
|
||||
|
||||
(5) radeon systems, where X can soft-boot your video card. You'll need
|
||||
a new enough X, and a plain text console (no vesafb or radeonfb). See
|
||||
http://www.doesi.gmxhome.de/linux/tm800s3/s3.html for more information.
|
||||
Alternatively, you should use vbetool (6) instead.
|
||||
|
||||
(6) other radeon systems, where vbetool is enough to bring system back
|
||||
to life. It needs text console to be working. Do vbetool vbestate
|
||||
save > /tmp/delme; echo 3 > /proc/acpi/sleep; vbetool post; vbetool
|
||||
vbestate restore < /tmp/delme; setfont <whatever>, and your video
|
||||
should work.
|
||||
|
||||
(7) on some systems, it is possible to boot most of kernel, and then
|
||||
POSTing bios works. Ole Rohne has patch to do just that at
|
||||
http://dev.gentoo.org/~marineam/patch-radeonfb-2.6.11-rc2-mm2.
|
||||
|
||||
(8) on some systems, you can use the video_post utility mentioned here:
|
||||
http://bugzilla.kernel.org/show_bug.cgi?id=3670. Do echo 3 > /sys/power/state
|
||||
&& /usr/sbin/video_post - which will initialize the display in console mode.
|
||||
If you are in X, you can switch to a virtual terminal and back to X using
|
||||
CTRL+ALT+F1 - CTRL+ALT+F7 to get the display working in graphical mode again.
|
||||
|
||||
Now, if you pass acpi_sleep=something, and it does not work with your
|
||||
bios, you'll get a hard crash during resume. Be careful. Also it is
|
||||
safest to do your experiments with plain old VGA console. The vesafb
|
||||
and radeonfb (etc) drivers have a tendency to crash the machine during
|
||||
resume.
|
||||
|
||||
You may have a system where none of above works. At that point you
|
||||
either invent another ugly hack that works, or write proper driver for
|
||||
your video card (good luck getting docs :-(). Maybe suspending from X
|
||||
(proper X, knowing your hardware, not XF68_FBcon) might have better
|
||||
chance of working.
|
||||
|
||||
Table of known working notebooks:
|
||||
|
||||
Model hack (or "how to do it")
|
||||
------------------------------------------------------------------------------
|
||||
Acer Aspire 1406LC ole's late BIOS init (7), turn off DRI
|
||||
Acer TM 230 s3_bios (2)
|
||||
Acer TM 242FX vbetool (6)
|
||||
Acer TM C110 video_post (8)
|
||||
Acer TM C300 vga=normal (only suspend on console, not in X), vbetool (6) or video_post (8)
|
||||
Acer TM 4052LCi s3_bios (2)
|
||||
Acer TM 636Lci s3_bios,s3_mode (4)
|
||||
Acer TM 650 (Radeon M7) vga=normal plus boot-radeon (5) gets text console back
|
||||
Acer TM 660 ??? (*)
|
||||
Acer TM 800 vga=normal, X patches, see webpage (5) or vbetool (6)
|
||||
Acer TM 803 vga=normal, X patches, see webpage (5) or vbetool (6)
|
||||
Acer TM 803LCi vga=normal, vbetool (6)
|
||||
Arima W730a vbetool needed (6)
|
||||
Asus L2400D s3_mode (3)(***) (S1 also works OK)
|
||||
Asus L3350M (SiS 740) (6)
|
||||
Asus L3800C (Radeon M7) s3_bios (2) (S1 also works OK)
|
||||
Asus M6887Ne vga=normal, s3_bios (2), use radeon driver instead of fglrx in x.org
|
||||
Athlon64 desktop prototype s3_bios (2)
|
||||
Compal CL-50 ??? (*)
|
||||
Compaq Armada E500 - P3-700 none (1) (S1 also works OK)
|
||||
Compaq Evo N620c vga=normal, s3_bios (2)
|
||||
Dell 600m, ATI R250 Lf none (1), but needs xorg-x11-6.8.1.902-1
|
||||
Dell D600, ATI RV250 vga=normal and X, or try vbestate (6)
|
||||
Dell D610 vga=normal and X (possibly vbestate (6) too, but not tested)
|
||||
Dell Inspiron 4000 ??? (*)
|
||||
Dell Inspiron 500m ??? (*)
|
||||
Dell Inspiron 510m ???
|
||||
Dell Inspiron 5150 vbetool needed (6)
|
||||
Dell Inspiron 600m ??? (*)
|
||||
Dell Inspiron 8200 ??? (*)
|
||||
Dell Inspiron 8500 ??? (*)
|
||||
Dell Inspiron 8600 ??? (*)
|
||||
eMachines athlon64 machines vbetool needed (6) (someone please get me model #s)
|
||||
HP NC6000 s3_bios, may not use radeonfb (2); or vbetool (6)
|
||||
HP NX7000 ??? (*)
|
||||
HP Pavilion ZD7000 vbetool post needed, need open-source nv driver for X
|
||||
HP Omnibook XE3 athlon version none (1)
|
||||
HP Omnibook XE3GC none (1), video is S3 Savage/IX-MV
|
||||
HP Omnibook XE3L-GF vbetool (6)
|
||||
HP Omnibook 5150 none (1), (S1 also works OK)
|
||||
IBM TP T20, model 2647-44G none (1), video is S3 Inc. 86C270-294 Savage/IX-MV, vesafb gets "interesting" but X work.
|
||||
IBM TP A31 / Type 2652-M5G s3_mode (3) [works ok with BIOS 1.04 2002-08-23, but not at all with BIOS 1.11 2004-11-05 :-(]
|
||||
IBM TP R32 / Type 2658-MMG none (1)
|
||||
IBM TP R40 2722B3G ??? (*)
|
||||
IBM TP R50p / Type 1832-22U s3_bios (2)
|
||||
IBM TP R51 none (1)
|
||||
IBM TP T30 236681A ??? (*)
|
||||
IBM TP T40 / Type 2373-MU4 none (1)
|
||||
IBM TP T40p none (1)
|
||||
IBM TP R40p s3_bios (2)
|
||||
IBM TP T41p s3_bios (2), switch to X after resume
|
||||
IBM TP T42 s3_bios (2)
|
||||
IBM ThinkPad T42p (2373-GTG) s3_bios (2)
|
||||
IBM TP X20 ??? (*)
|
||||
IBM TP X30 s3_bios, s3_mode (4)
|
||||
IBM TP X31 / Type 2672-XXH none (1), use radeontool (http://fdd.com/software/radeon/) to turn off backlight.
|
||||
IBM TP X32 none (1), but backlight is on and video is trashed after long suspend. s3_bios,s3_mode (4) works too. Perhaps that gets better results?
|
||||
IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4)
|
||||
IBM TP 600e none(1), but a switch to console and back to X is needed
|
||||
Medion MD4220 ??? (*)
|
||||
Samsung P35 vbetool needed (6)
|
||||
Sharp PC-AR10 (ATI rage) none (1), backlight does not switch off
|
||||
Sony Vaio PCG-C1VRX/K s3_bios (2)
|
||||
Sony Vaio PCG-F403 ??? (*)
|
||||
Sony Vaio PCG-GRT995MP none (1), works with 'nv' X driver
|
||||
Sony Vaio PCG-GR7/K none (1), but needs radeonfb, use radeontool (http://fdd.com/software/radeon/) to turn off backlight.
|
||||
Sony Vaio PCG-N505SN ??? (*)
|
||||
Sony Vaio vgn-s260 X or boot-radeon can init it (5)
|
||||
Sony Vaio vgn-S580BH vga=normal, but suspend from X. Console will be blank unless you return to X.
|
||||
Sony Vaio vgn-FS115B s3_bios (2),s3_mode (4)
|
||||
Toshiba Libretto L5 none (1)
|
||||
Toshiba Libretto 100CT/110CT vbetool (6)
|
||||
Toshiba Portege 3020CT s3_mode (3)
|
||||
Toshiba Satellite 4030CDT s3_mode (3) (S1 also works OK)
|
||||
Toshiba Satellite 4080XCDT s3_mode (3) (S1 also works OK)
|
||||
Toshiba Satellite 4090XCDT ??? (*)
|
||||
Toshiba Satellite P10-554 s3_bios,s3_mode (4)(****)
|
||||
Toshiba M30 (2) xor X with nvidia driver using internal AGP
|
||||
Uniwill 244IIO ??? (*)
|
||||
|
||||
Known working desktop systems
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Mainboard Graphics card hack (or "how to do it")
|
||||
------------------------------------------------------------------------------
|
||||
Asus A7V8X nVidia RIVA TNT2 model 64 s3_bios,s3_mode (4)
|
||||
|
||||
|
||||
(*) from http://www.ubuntulinux.org/wiki/HoaryPMResults, not sure
|
||||
which options to use. If you know, please tell me.
|
||||
|
||||
(***) To be tested with a newer kernel.
|
||||
|
||||
(****) Not with SMP kernel, UP only.
|
||||
37
Documentation/power/video_extension.txt
Normal file
37
Documentation/power/video_extension.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
ACPI video extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This driver implement the ACPI Extensions For Display Adapters for
|
||||
integrated graphics devices on motherboard, as specified in ACPI 2.0
|
||||
Specification, Appendix B, allowing to perform some basic control like
|
||||
defining the video POST device, retrieving EDID information or to
|
||||
setup a video output, etc. Note that this is an ref. implementation
|
||||
only. It may or may not work for your integrated video device.
|
||||
|
||||
Interfaces exposed to userland through /proc/acpi/video:
|
||||
|
||||
VGA/info : display the supported video bus device capability like Video ROM, CRT/LCD/TV.
|
||||
VGA/ROM : Used to get a copy of the display devices' ROM data (up to 4k).
|
||||
VGA/POST_info : Used to determine what options are implemented.
|
||||
VGA/POST : Used to get/set POST device.
|
||||
VGA/DOS : Used to get/set ownership of output switching:
|
||||
Please refer ACPI spec B.4.1 _DOS
|
||||
VGA/CRT : CRT output
|
||||
VGA/LCD : LCD output
|
||||
VGA/TVO : TV output
|
||||
VGA/*/brightness : Used to get/set brightness of output device
|
||||
|
||||
Notify event through /proc/acpi/event:
|
||||
|
||||
#define ACPI_VIDEO_NOTIFY_SWITCH 0x80
|
||||
#define ACPI_VIDEO_NOTIFY_PROBE 0x81
|
||||
#define ACPI_VIDEO_NOTIFY_CYCLE 0x82
|
||||
#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
|
||||
#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
|
||||
|
||||
#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82
|
||||
#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83
|
||||
#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84
|
||||
#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85
|
||||
#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86
|
||||
|
||||
Reference in New Issue
Block a user