Creation of Cybook 2416 (actually Gen4) repository

This commit is contained in:
mlt
2009-12-18 17:10:00 +00:00
committed by godzil
commit 76f20f4d40
13791 changed files with 6812321 additions and 0 deletions

View 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.

View 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.

View 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
View 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

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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