diff options
Diffstat (limited to 'Documentation/power')
-rw-r--r-- | Documentation/power/00-INDEX | 6 | ||||
-rw-r--r-- | Documentation/power/pm.txt | 257 | ||||
-rw-r--r-- | Documentation/power/pm_qos_interface.txt | 59 | ||||
-rw-r--r-- | Documentation/power/power_supply_class.txt | 169 |
4 files changed, 491 insertions, 0 deletions
diff --git a/Documentation/power/00-INDEX b/Documentation/power/00-INDEX index 8db4e41a052..a55d7f1c836 100644 --- a/Documentation/power/00-INDEX +++ b/Documentation/power/00-INDEX @@ -14,6 +14,12 @@ notifiers.txt - Registering suspend notifiers in device drivers pci.txt - How the PCI Subsystem Does Power Management +pm.txt + - info on Linux power management support. +pm_qos_interface.txt + - info on Linux PM Quality of Service interface +power_supply_class.txt + - Tells userspace about battery, UPS, AC or DC power supply properties s2ram.txt - How to get suspend to ram working (and debug it when it isn't) states.txt diff --git a/Documentation/power/pm.txt b/Documentation/power/pm.txt new file mode 100644 index 00000000000..be841507e43 --- /dev/null +++ b/Documentation/power/pm.txt @@ -0,0 +1,257 @@ + Linux Power Management Support + +This document briefly describes how to use power management with your +Linux system and how to add power management support to Linux drivers. + +APM or ACPI? +------------ +If you have a relatively recent x86 mobile, desktop, or server system, +odds are it supports either Advanced Power Management (APM) or +Advanced Configuration and Power Interface (ACPI). ACPI is the newer +of the two technologies and puts power management in the hands of the +operating system, allowing for more intelligent power management than +is possible with BIOS controlled APM. + +The best way to determine which, if either, your system supports is to +build a kernel with both ACPI and APM enabled (as of 2.3.x ACPI is +enabled by default). If a working ACPI implementation is found, the +ACPI driver will override and disable APM, otherwise the APM driver +will be used. + +No, sorry, you cannot have both ACPI and APM enabled and running at +once. Some people with broken ACPI or broken APM implementations +would like to use both to get a full set of working features, but you +simply cannot mix and match the two. Only one power management +interface can be in control of the machine at once. Think about it.. + +User-space Daemons +------------------ +Both APM and ACPI rely on user-space daemons, apmd and acpid +respectively, to be completely functional. Obtain both of these +daemons from your Linux distribution or from the Internet (see below) +and be sure that they are started sometime in the system boot process. +Go ahead and start both. If ACPI or APM is not available on your +system the associated daemon will exit gracefully. + + apmd: http://worldvisions.ca/~apenwarr/apmd/ + acpid: http://acpid.sf.net/ + +Driver Interface -- OBSOLETE, DO NOT USE! +----------------************************* + +Note: pm_register(), pm_access(), pm_dev_idle() and friends are +obsolete. Please do not use them. Instead you should properly hook +your driver into the driver model, and use its suspend()/resume() +callbacks to do this kind of stuff. + +If you are writing a new driver or maintaining an old driver, it +should include power management support. Without power management +support, a single driver may prevent a system with power management +capabilities from ever being able to suspend (safely). + +Overview: +1) Register each instance of a device with "pm_register" +2) Call "pm_access" before accessing the hardware. + (this will ensure that the hardware is awake and ready) +3) Your "pm_callback" is called before going into a + suspend state (ACPI D1-D3) or after resuming (ACPI D0) + from a suspend. +4) Call "pm_dev_idle" when the device is not being used + (optional but will improve device idle detection) +5) When unloaded, unregister the device with "pm_unregister" + +/* + * Description: Register a device with the power-management subsystem + * + * Parameters: + * type - device type (PCI device, system device, ...) + * id - instance number or unique identifier + * cback - request handler callback (suspend, resume, ...) + * + * Returns: Registered PM device or NULL on error + * + * Examples: + * dev = pm_register(PM_SYS_DEV, PM_SYS_VGA, vga_callback); + * + * struct pci_dev *pci_dev = pci_find_dev(...); + * dev = pm_register(PM_PCI_DEV, PM_PCI_ID(pci_dev), callback); + */ +struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback cback); + +/* + * Description: Unregister a device with the power management subsystem + * + * Parameters: + * dev - PM device previously returned from pm_register + */ +void pm_unregister(struct pm_dev *dev); + +/* + * Description: Unregister all devices with a matching callback function + * + * Parameters: + * cback - previously registered request callback + * + * Notes: Provided for easier porting from old APM interface + */ +void pm_unregister_all(pm_callback cback); + +/* + * Power management request callback + * + * Parameters: + * dev - PM device previously returned from pm_register + * rqst - request type + * data - data, if any, associated with the request + * + * Returns: 0 if the request is successful + * EINVAL if the request is not supported + * EBUSY if the device is now busy and cannot handle the request + * ENOMEM if the device was unable to handle the request due to memory + * + * Details: The device request callback will be called before the + * device/system enters a suspend state (ACPI D1-D3) or + * or after the device/system resumes from suspend (ACPI D0). + * For PM_SUSPEND, the ACPI D-state being entered is passed + * as the "data" argument to the callback. The device + * driver should save (PM_SUSPEND) or restore (PM_RESUME) + * device context when the request callback is called. + * + * Once a driver returns 0 (success) from a suspend + * request, it should not process any further requests or + * access the device hardware until a call to "pm_access" is made. + */ +typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data); + +Driver Details +-------------- +This is just a quick Q&A as a stopgap until a real driver writers' +power management guide is available. + +Q: When is a device suspended? + +Devices can be suspended based on direct user request (eg. laptop lid +closes), system power policy (eg. sleep after 30 minutes of console +inactivity), or device power policy (eg. power down device after 5 +minutes of inactivity) + +Q: Must a driver honor a suspend request? + +No, a driver can return -EBUSY from a suspend request and this +will stop the system from suspending. When a suspend request +fails, all suspended devices are resumed and the system continues +to run. Suspend can be retried at a later time. + +Q: Can the driver block suspend/resume requests? + +Yes, a driver can delay its return from a suspend or resume +request until the device is ready to handle requests. It +is advantageous to return as quickly as possible from a +request as suspend/resume are done serially. + +Q: What context is a suspend/resume initiated from? + +A suspend or resume is initiated from a kernel thread context. +It is safe to block, allocate memory, initiate requests +or anything else you can do within the kernel. + +Q: Will requests continue to arrive after a suspend? + +Possibly. It is the driver's responsibility to queue(*), +fail, or drop any requests that arrive after returning +success to a suspend request. It is important that the +driver not access its device until after it receives +a resume request as the device's bus may no longer +be active. + +(*) If a driver queues requests for processing after + resume be aware that the device, network, etc. + might be in a different state than at suspend time. + It's probably better to drop requests unless + the driver is a storage device. + +Q: Do I have to manage bus-specific power management registers + +No. It is the responsibility of the bus driver to manage +PCI, USB, etc. power management registers. The bus driver +or the power management subsystem will also enable any +wake-on functionality that the device has. + +Q: So, really, what do I need to do to support suspend/resume? + +You need to save any device context that would +be lost if the device was powered off and then restore +it at resume time. When ACPI is active, there are +three levels of device suspend states; D1, D2, and D3. +(The suspend state is passed as the "data" argument +to the device callback.) With D3, the device is powered +off and loses all context, D1 and D2 are shallower power +states and require less device context to be saved. To +play it safe, just save everything at suspend and restore +everything at resume. + +Q: Where do I store device context for suspend? + +Anywhere in memory, kmalloc a buffer or store it +in the device descriptor. You are guaranteed that the +contents of memory will be restored and accessible +before resume, even when the system suspends to disk. + +Q: What do I need to do for ACPI vs. APM vs. etc? + +Drivers need not be aware of the specific power management +technology that is active. They just need to be aware +of when the overlying power management system requests +that they suspend or resume. + +Q: What about device dependencies? + +When a driver registers a device, the power management +subsystem uses the information provided to build a +tree of device dependencies (eg. USB device X is on +USB controller Y which is on PCI bus Z) When power +management wants to suspend a device, it first sends +a suspend request to its driver, then the bus driver, +and so on up to the system bus. Device resumes +proceed in the opposite direction. + +Q: Who do I contact for additional information about + enabling power management for my specific driver/device? + +ACPI Development mailing list: linux-acpi@vger.kernel.org + +System Interface -- OBSOLETE, DO NOT USE! +----------------************************* +If you are providing new power management support to Linux (ie. +adding support for something like APM or ACPI), you should +communicate with drivers through the existing generic power +management interface. + +/* + * Send a request to all devices + * + * Parameters: + * rqst - request type + * data - data, if any, associated with the request + * + * Returns: 0 if the request is successful + * See "pm_callback" return for errors + * + * Details: Walk list of registered devices and call pm_send + * for each until complete or an error is encountered. + * If an error is encountered for a suspend request, + * return all devices to the state they were in before + * the suspend request. + */ +int pm_send_all(pm_request_t rqst, void *data); + +/* + * Find a matching device + * + * Parameters: + * type - device type (PCI device, system device, or 0 to match all devices) + * from - previous match or NULL to start from the beginning + * + * Returns: Matching device or NULL if none found + */ +struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from); diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt new file mode 100644 index 00000000000..49adb1a3351 --- /dev/null +++ b/Documentation/power/pm_qos_interface.txt @@ -0,0 +1,59 @@ +PM quality of Service interface. + +This interface provides a kernel and user mode interface for registering +performance expectations by drivers, subsystems and user space applications on +one of the parameters. + +Currently we have {cpu_dma_latency, network_latency, network_throughput} as the +initial set of pm_qos parameters. + +The infrastructure exposes multiple misc device nodes one per implemented +parameter. The set of parameters implement is defined by pm_qos_power_init() +and pm_qos_params.h. This is done because having the available parameters +being runtime configurable or changeable from a driver was seen as too easy to +abuse. + +For each parameter a list of performance requirements is maintained along with +an aggregated target value. The aggregated target value is updated with +changes to the requirement list or elements of the list. Typically the +aggregated target value is simply the max or min of the requirement values held +in the parameter list elements. + +From kernel mode the use of this interface is simple: +pm_qos_add_requirement(param_id, name, target_value): +Will insert a named element in the list for that identified PM_QOS parameter +with the target value. Upon change to this list the new target is recomputed +and any registered notifiers are called only if the target value is now +different. + +pm_qos_update_requirement(param_id, name, new_target_value): +Will search the list identified by the param_id for the named list element and +then update its target value, calling the notification tree if the aggregated +target is changed. with that name is already registered. + +pm_qos_remove_requirement(param_id, name): +Will search the identified list for the named element and remove it, after +removal it will update the aggregate target and call the notification tree if +the target was changed as a result of removing the named requirement. + + +From user mode: +Only processes can register a pm_qos requirement. To provide for automatic +cleanup for process the interface requires the process to register its +parameter requirements in the following way: + +To register the default pm_qos target for the specific parameter, the process +must open one of /dev/[cpu_dma_latency, network_latency, network_throughput] + +As long as the device node is held open that process has a registered +requirement on the parameter. The name of the requirement is "process_<PID>" +derived from the current->pid from within the open system call. + +To change the requested target value the process needs to write a s32 value to +the open device node. This translates to a pm_qos_update_requirement call. + +To remove the user mode request for a target value simply close the device +node. + + + diff --git a/Documentation/power/power_supply_class.txt b/Documentation/power/power_supply_class.txt new file mode 100644 index 00000000000..a8686e5a685 --- /dev/null +++ b/Documentation/power/power_supply_class.txt @@ -0,0 +1,169 @@ +Linux power supply class +======================== + +Synopsis +~~~~~~~~ +Power supply class used to represent battery, UPS, AC or DC power supply +properties to user-space. + +It defines core set of attributes, which should be applicable to (almost) +every power supply out there. Attributes are available via sysfs and uevent +interfaces. + +Each attribute has well defined meaning, up to unit of measure used. While +the attributes provided are believed to be universally applicable to any +power supply, specific monitoring hardware may not be able to provide them +all, so any of them may be skipped. + +Power supply class is extensible, and allows to define drivers own attributes. +The core attribute set is subject to the standard Linux evolution (i.e. +if it will be found that some attribute is applicable to many power supply +types or their drivers, it can be added to the core set). + +It also integrates with LED framework, for the purpose of providing +typically expected feedback of battery charging/fully charged status and +AC/USB power supply online status. (Note that specific details of the +indication (including whether to use it at all) are fully controllable by +user and/or specific machine defaults, per design principles of LED +framework). + + +Attributes/properties +~~~~~~~~~~~~~~~~~~~~~ +Power supply class has predefined set of attributes, this eliminates code +duplication across drivers. Power supply class insist on reusing its +predefined attributes *and* their units. + +So, userspace gets predictable set of attributes and their units for any +kind of power supply, and can process/present them to a user in consistent +manner. Results for different power supplies and machines are also directly +comparable. + +See drivers/power/ds2760_battery.c and drivers/power/pda_power.c for the +example how to declare and handle attributes. + + +Units +~~~~~ +Quoting include/linux/power_supply.h: + + All voltages, currents, charges, energies, time and temperatures in µV, + µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise + stated. It's driver's job to convert its raw values to units in which + this class operates. + + +Attributes/properties detailed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +~ ~ ~ ~ ~ ~ ~ Charge/Energy/Capacity - how to not confuse ~ ~ ~ ~ ~ ~ ~ +~ ~ +~ Because both "charge" (µAh) and "energy" (µWh) represents "capacity" ~ +~ of battery, this class distinguish these terms. Don't mix them! ~ +~ ~ +~ CHARGE_* attributes represents capacity in µAh only. ~ +~ ENERGY_* attributes represents capacity in µWh only. ~ +~ CAPACITY attribute represents capacity in *percents*, from 0 to 100. ~ +~ ~ +~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ + +Postfixes: +_AVG - *hardware* averaged value, use it if your hardware is really able to +report averaged values. +_NOW - momentary/instantaneous values. + +STATUS - this attribute represents operating status (charging, full, +discharging (i.e. powering a load), etc.). This corresponds to +BATTERY_STATUS_* values, as defined in battery.h. + +HEALTH - represents health of the battery, values corresponds to +POWER_SUPPLY_HEALTH_*, defined in battery.h. + +VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN - design values for maximal and +minimal power supply voltages. Maximal/minimal means values of voltages +when battery considered "full"/"empty" at normal conditions. Yes, there is +no direct relation between voltage and battery capacity, but some dumb +batteries use voltage for very approximated calculation of capacity. +Battery driver also can use this attribute just to inform userspace +about maximal and minimal voltage thresholds of a given battery. + +VOLTAGE_MAX, VOLTAGE_MIN - same as _DESIGN voltage values except that +these ones should be used if hardware could only guess (measure and +retain) the thresholds of a given power supply. + +CHARGE_FULL_DESIGN, CHARGE_EMPTY_DESIGN - design charge values, when +battery considered full/empty. + +ENERGY_FULL_DESIGN, ENERGY_EMPTY_DESIGN - same as above but for energy. + +CHARGE_FULL, CHARGE_EMPTY - These attributes means "last remembered value +of charge when battery became full/empty". It also could mean "value of +charge when battery considered full/empty at given conditions (temperature, +age)". I.e. these attributes represents real thresholds, not design values. + +ENERGY_FULL, ENERGY_EMPTY - same as above but for energy. + +CAPACITY - capacity in percents. + +TEMP - temperature of the power supply. +TEMP_AMBIENT - ambient temperature. + +TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e. +while battery powers a load) +TIME_TO_FULL - seconds left for battery to be considered full (i.e. +while battery is charging) + + +Battery <-> external power supply interaction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Often power supplies are acting as supplies and supplicants at the same +time. Batteries are good example. So, batteries usually care if they're +externally powered or not. + +For that case, power supply class implements notification mechanism for +batteries. + +External power supply (AC) lists supplicants (batteries) names in +"supplied_to" struct member, and each power_supply_changed() call +issued by external power supply will notify supplicants via +external_power_changed callback. + + +QA +~~ +Q: Where is POWER_SUPPLY_PROP_XYZ attribute? +A: If you cannot find attribute suitable for your driver needs, feel free + to add it and send patch along with your driver. + + The attributes available currently are the ones currently provided by the + drivers written. + + Good candidates to add in future: model/part#, cycle_time, manufacturer, + etc. + + +Q: I have some very specific attribute (e.g. battery color), should I add + this attribute to standard ones? +A: Most likely, no. Such attribute can be placed in the driver itself, if + it is useful. Of course, if the attribute in question applicable to + large set of batteries, provided by many drivers, and/or comes from + some general battery specification/standard, it may be a candidate to + be added to the core attribute set. + + +Q: Suppose, my battery monitoring chip/firmware does not provides capacity + in percents, but provides charge_{now,full,empty}. Should I calculate + percentage capacity manually, inside the driver, and register CAPACITY + attribute? The same question about time_to_empty/time_to_full. +A: Most likely, no. This class is designed to export properties which are + directly measurable by the specific hardware available. + + Inferring not available properties using some heuristics or mathematical + model is not subject of work for a battery driver. Such functionality + should be factored out, and in fact, apm_power, the driver to serve + legacy APM API on top of power supply class, uses a simple heuristic of + approximating remaining battery capacity based on its charge, current, + voltage and so on. But full-fledged battery model is likely not subject + for kernel at all, as it would require floating point calculation to deal + with things like differential equations and Kalman filters. This is + better be handled by batteryd/libbattery, yet to be written. |