Commit 151f4e2b authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab Committed by Bjorn Helgaas

docs: power: convert docs to ReST and rename to *.rst

Convert the PM documents to ReST, in order to allow them to
build with Sphinx.

The conversion is actually:
  - add blank lines and indentation in order to identify paragraphs;
  - fix tables markups;
  - add some lists markups;
  - mark literal blocks;
  - adjust title markups.

At its new index.rst, let's add a :orphan: while this is not linked to
the main index.rst file, in order to avoid build warnings.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarMark Brown <broonie@kernel.org>
Acked-by: default avatarSrivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu>
parent 9595aee2
......@@ -5,7 +5,7 @@ Contact: linux-pm@vger.kernel.org
Description:
The powercap/ class sub directory belongs to the power cap
subsystem. Refer to
Documentation/power/powercap/powercap.txt for details.
Documentation/power/powercap/powercap.rst for details.
What: /sys/class/powercap/<control type>
Date: September 2013
......
......@@ -13,7 +13,7 @@
For ARM64, ONLY "acpi=off", "acpi=on" or "acpi=force"
are available
See also Documentation/power/runtime_pm.txt, pci=noacpi
See also Documentation/power/runtime_pm.rst, pci=noacpi
acpi_apic_instance= [ACPI, IOAPIC]
Format: <int>
......@@ -223,7 +223,7 @@
acpi_sleep= [HW,ACPI] Sleep options
Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
old_ordering, nonvs, sci_force_enable, nobl }
See Documentation/power/video.txt for information on
See Documentation/power/video.rst for information on
s3_bios and s3_mode.
s3_beep is for debugging; it makes the PC's speaker beep
as soon as the kernel's real-mode entry point is called.
......@@ -4108,7 +4108,7 @@
Specify the offset from the beginning of the partition
given by "resume=" at which the swap header is located,
in <PAGE_SIZE> units (needed only for swap files).
See Documentation/power/swsusp-and-swap-files.txt
See Documentation/power/swsusp-and-swap-files.rst
resumedelay= [HIBERNATION] Delay (in seconds) to pause before attempting to
read the resume files
......
......@@ -95,7 +95,7 @@ flags - flags of the cpufreq driver
3. CPUFreq Table Generation with Operating Performance Point (OPP)
==================================================================
For details about OPP, see Documentation/power/opp.txt
For details about OPP, see Documentation/power/opp.rst
dev_pm_opp_init_cpufreq_table -
This function provides a ready to use conversion routine to translate
......
......@@ -225,7 +225,7 @@ system-wide transition to a sleep state even though its :c:member:`runtime_auto`
flag is clear.
For more information about the runtime power management framework, refer to
:file:`Documentation/power/runtime_pm.txt`.
:file:`Documentation/power/runtime_pm.rst`.
Calling Drivers to Enter and Leave System Sleep States
......@@ -728,7 +728,7 @@ it into account in any way.
Devices may be defined as IRQ-safe which indicates to the PM core that their
runtime PM callbacks may be invoked with disabled interrupts (see
:file:`Documentation/power/runtime_pm.txt` for more information). If an
:file:`Documentation/power/runtime_pm.rst` for more information). If an
IRQ-safe device belongs to a PM domain, the runtime PM of the domain will be
disallowed, unless the domain itself is defined as IRQ-safe. However, it
makes sense to define a PM domain as IRQ-safe only if all the devices in it
......@@ -795,7 +795,7 @@ so on) and the final state of the device must reflect the "active" runtime PM
status in that case.
During system-wide resume from a sleep state it's easiest to put devices into
the full-power state, as explained in :file:`Documentation/power/runtime_pm.txt`.
the full-power state, as explained in :file:`Documentation/power/runtime_pm.rst`.
[Refer to that document for more information regarding this particular issue as
well as for information on the device runtime power management framework in
general.]
......
......@@ -46,7 +46,7 @@ device is turned off while the system as a whole remains running, we
call it a "dynamic suspend" (also known as a "runtime suspend" or
"selective suspend"). This document concentrates mostly on how
dynamic PM is implemented in the USB subsystem, although system PM is
covered to some extent (see ``Documentation/power/*.txt`` for more
covered to some extent (see ``Documentation/power/*.rst`` for more
information about system PM).
System PM support is present only if the kernel was built with
......
============
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
......@@ -28,5 +30,7 @@ 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://ftp.debian.org/pool/main/a/apmd/
acpid: http://acpid.sf.net/
===== =======================================
apmd http://ftp.debian.org/pool/main/a/apmd/
acpid http://acpid.sf.net/
===== =======================================
=================================
Debugging hibernation and suspend
=================================
(C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
1. Testing hibernation (aka suspend to disk or STD)
===================================================
To check if hibernation works, you can try to hibernate in the "reboot" mode:
To check if hibernation works, you can try to hibernate in the "reboot" mode::
# echo reboot > /sys/power/disk
# echo disk > /sys/power/state
# echo reboot > /sys/power/disk
# echo disk > /sys/power/state
and the system should create a hibernation image, reboot, resume and get back to
the command prompt where you have started the transition. If that happens,
......@@ -15,20 +19,21 @@ test at least a couple of times in a row for confidence. [This is necessary,
because some problems only show up on a second attempt at suspending and
resuming the system.] Moreover, hibernating in the "reboot" and "shutdown"
modes causes the PM core to skip some platform-related callbacks which on ACPI
systems might be necessary to make hibernation work. Thus, if your machine fails
to hibernate or resume in the "reboot" mode, you should try the "platform" mode:
systems might be necessary to make hibernation work. Thus, if your machine
fails to hibernate or resume in the "reboot" mode, you should try the
"platform" mode::
# echo platform > /sys/power/disk
# echo disk > /sys/power/state
# echo platform > /sys/power/disk
# echo disk > /sys/power/state
which is the default and recommended mode of hibernation.
Unfortunately, the "platform" mode of hibernation does not work on some systems
with broken BIOSes. In such cases the "shutdown" mode of hibernation might
work:
work::
# echo shutdown > /sys/power/disk
# echo disk > /sys/power/state
# echo shutdown > /sys/power/disk
# echo disk > /sys/power/state
(it is similar to the "reboot" mode, but it requires you to press the power
button to make the system resume).
......@@ -37,6 +42,7 @@ If neither "platform" nor "shutdown" hibernation mode works, you will need to
identify what goes wrong.
a) Test modes of hibernation
----------------------------
To find out why hibernation fails on your system, you can use a special testing
facility available if the kernel is compiled with CONFIG_PM_DEBUG set. Then,
......@@ -44,36 +50,38 @@ there is the file /sys/power/pm_test that can be used to make the hibernation
core run in a test mode. There are 5 test modes available:
freezer
- test the freezing of processes
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform
global control methods(*)
- test the freezing of processes, suspending of devices and platform
global control methods [1]_
processors
- test the freezing of processes, suspending of devices, platform
global control methods(*) and the disabling of nonboot CPUs
- test the freezing of processes, suspending of devices, platform
global control methods [1]_ and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods(*), the disabling of nonboot CPUs and suspending of
platform/system devices
- test the freezing of processes, suspending of devices, platform global
control methods\ [1]_, the disabling of nonboot CPUs and suspending
of platform/system devices
.. [1]
(*) the platform global control methods are only available on ACPI systems
the platform global control methods are only available on ACPI systems
and are only tested if the hibernation mode is set to "platform"
To use one of them it is necessary to write the corresponding string to
/sys/power/pm_test (eg. "devices" to test the freezing of processes and
suspending devices) and issue the standard hibernation commands. For example,
to use the "devices" test mode along with the "platform" mode of hibernation,
you should do the following:
you should do the following::
# echo devices > /sys/power/pm_test
# echo platform > /sys/power/disk
# echo disk > /sys/power/state
# echo devices > /sys/power/pm_test
# echo platform > /sys/power/disk
# echo disk > /sys/power/state
Then, the kernel will try to freeze processes, suspend devices, wait a few
seconds (5 by default, but configurable by the suspend.pm_test_delay module
......@@ -108,11 +116,12 @@ If the "devices" test fails, most likely there is a driver that cannot suspend
or resume its device (in the latter case the system may hang or become unstable
after the test, so please take that into consideration). To find this driver,
you can carry out a binary search according to the rules:
- if the test fails, unload a half of the drivers currently loaded and repeat
(that would probably involve rebooting the system, so always note what drivers
have been loaded before the test),
(that would probably involve rebooting the system, so always note what drivers
have been loaded before the test),
- if the test succeeds, load a half of the drivers you have unloaded most
recently and repeat.
recently and repeat.
Once you have found the failing driver (there can be more than just one of
them), you have to unload it every time before hibernation. In that case please
......@@ -146,6 +155,7 @@ indicates a serious problem that very well may be related to the hardware, but
please report it anyway.
b) Testing minimal configuration
--------------------------------
If all of the hibernation test modes work, you can boot the system with the
"init=/bin/bash" command line parameter and attempt to hibernate in the
......@@ -165,14 +175,15 @@ Again, if you find the offending module(s), it(they) must be unloaded every time
before hibernation, and please report the problem with it(them).
c) Using the "test_resume" hibernation option
---------------------------------------------
/sys/power/disk generally tells the kernel what to do after creating a
hibernation image. One of the available options is "test_resume" which
causes the just created image to be used for immediate restoration. Namely,
after doing:
after doing::
# echo test_resume > /sys/power/disk
# echo disk > /sys/power/state
# echo test_resume > /sys/power/disk
# echo disk > /sys/power/state
a hibernation image will be created and a resume from it will be triggered
immediately without involving the platform firmware in any way.
......@@ -190,6 +201,7 @@ to resume may be related to the differences between the restore and image
kernels.
d) Advanced debugging
---------------------
In case that hibernation does not work on your system even in the minimal
configuration and compiling more drivers as modules is not practical or some
......@@ -200,9 +212,10 @@ kernel messages using the serial console. This may provide you with some
information about the reasons of the suspend (resume) failure. Alternatively,
it may be possible to use a FireWire port for debugging with firescope
(http://v3.sk/~lkundrak/firescope/). On x86 it is also possible to
use the PM_TRACE mechanism documented in Documentation/power/s2ram.txt .
use the PM_TRACE mechanism documented in Documentation/power/s2ram.rst .
2. Testing suspend to RAM (STR)
===============================
To verify that the STR works, it is generally more convenient to use the s2ram
tool available from http://suspend.sf.net and documented at
......@@ -230,7 +243,8 @@ you will have to unload them every time before an STR transition (ie. before
you run s2ram), and please report the problems with them.
There is a debugfs entry which shows the suspend to RAM statistics. Here is an
example of its output.
example of its output::
# mount -t debugfs none /sys/kernel/debug
# cat /sys/kernel/debug/suspend_stats
success: 20
......@@ -248,6 +262,7 @@ example of its output.
-16
last_failed_step: suspend
suspend
Field success means the success number of suspend to RAM, and field fail means
the failure number. Others are the failure number of different steps of suspend
to RAM. suspend_stats just lists the last 2 failed devices, error number and
......
===============
Charger Manager
===============
(C) 2011 MyungJoo Ham <myungjoo.ham@samsung.com>, GPL
Charger Manager provides in-kernel battery charger management that
......@@ -55,41 +58,39 @@ Charger Manager supports the following:
notification to users with UEVENT.
2. Global Charger-Manager Data related with suspend_again
========================================================
=========================================================
In order to setup Charger Manager with suspend-again feature
(in-suspend monitoring), the user should provide charger_global_desc
with setup_charger_manager(struct charger_global_desc *).
with setup_charger_manager(`struct charger_global_desc *`).
This charger_global_desc data for in-suspend monitoring is global
as the name suggests. Thus, the user needs to provide only once even
if there are multiple batteries. If there are multiple batteries, the
multiple instances of Charger Manager share the same charger_global_desc
and it will manage in-suspend monitoring for all instances of Charger Manager.
The user needs to provide all the three entries properly in order to activate
in-suspend monitoring:
struct charger_global_desc {
The user needs to provide all the three entries to `struct charger_global_desc`
properly in order to activate in-suspend monitoring:
char *rtc_name;
: The name of rtc (e.g., "rtc0") used to wakeup the system from
`char *rtc_name;`
The name of rtc (e.g., "rtc0") used to wakeup the system from
suspend for Charger Manager. The alarm interrupt (AIE) of the rtc
should be able to wake up the system from suspend. Charger Manager
saves and restores the alarm value and use the previously-defined
alarm if it is going to go off earlier than Charger Manager so that
Charger Manager does not interfere with previously-defined alarms.
bool (*rtc_only_wakeup)(void);
: This callback should let CM know whether
`bool (*rtc_only_wakeup)(void);`
This callback should let CM know whether
the wakeup-from-suspend is caused only by the alarm of "rtc" in the
same struct. If there is any other wakeup source triggered the
wakeup, it should return false. If the "rtc" is the only wakeup
reason, it should return true.
bool assume_timer_stops_in_suspend;
: if true, Charger Manager assumes that
`bool assume_timer_stops_in_suspend;`
if true, Charger Manager assumes that
the timer (CM uses jiffies as timer) stops during suspend. Then, CM
assumes that the suspend-duration is same as the alarm length.
};
3. How to setup suspend_again
=============================
......@@ -109,26 +110,28 @@ if the system was woken up by Charger Manager and the polling
=============================================
For each battery charged independently from other batteries (if a series of
batteries are charged by a single charger, they are counted as one independent
battery), an instance of Charger Manager is attached to it.
battery), an instance of Charger Manager is attached to it. The following
struct charger_desc {
struct charger_desc elements:
char *psy_name;
: The power-supply-class name of the battery. Default is
`char *psy_name;`
The power-supply-class name of the battery. Default is
"battery" if psy_name is NULL. Users can access the psy entries
at "/sys/class/power_supply/[psy_name]/".
enum polling_modes polling_mode;
: CM_POLL_DISABLE: do not poll this battery.
CM_POLL_ALWAYS: always poll this battery.
CM_POLL_EXTERNAL_POWER_ONLY: poll this battery if and only if
an external power source is attached.
CM_POLL_CHARGING_ONLY: poll this battery if and only if the
battery is being charged.
unsigned int fullbatt_vchkdrop_ms;
unsigned int fullbatt_vchkdrop_uV;
: If both have non-zero values, Charger Manager will check the
`enum polling_modes polling_mode;`
CM_POLL_DISABLE:
do not poll this battery.
CM_POLL_ALWAYS:
always poll this battery.
CM_POLL_EXTERNAL_POWER_ONLY:
poll this battery if and only if an external power
source is attached.
CM_POLL_CHARGING_ONLY:
poll this battery if and only if the battery is being charged.
`unsigned int fullbatt_vchkdrop_ms; / unsigned int fullbatt_vchkdrop_uV;`
If both have non-zero values, Charger Manager will check the
battery voltage drop fullbatt_vchkdrop_ms after the battery is fully
charged. If the voltage drop is over fullbatt_vchkdrop_uV, Charger
Manager will try to recharge the battery by disabling and enabling
......@@ -136,50 +139,52 @@ unsigned int fullbatt_vchkdrop_uV;
condition) is needed to be implemented with hardware interrupts from
fuel gauges or charger devices/chips.
unsigned int fullbatt_uV;
: If specified with a non-zero value, Charger Manager assumes
`unsigned int fullbatt_uV;`
If specified with a non-zero value, Charger Manager assumes
that the battery is full (capacity = 100) if the battery is not being
charged and the battery voltage is equal to or greater than
fullbatt_uV.
unsigned int polling_interval_ms;
: Required polling interval in ms. Charger Manager will poll
`unsigned int polling_interval_ms;`
Required polling interval in ms. Charger Manager will poll
this battery every polling_interval_ms or more frequently.
enum data_source battery_present;
: CM_BATTERY_PRESENT: assume that the battery exists.
CM_NO_BATTERY: assume that the battery does not exists.
CM_FUEL_GAUGE: get battery presence information from fuel gauge.
CM_CHARGER_STAT: get battery presence from chargers.
char **psy_charger_stat;
: An array ending with NULL that has power-supply-class names of
`enum data_source battery_present;`
CM_BATTERY_PRESENT:
assume that the battery exists.
CM_NO_BATTERY:
assume that the battery does not exists.
CM_FUEL_GAUGE:
get battery presence information from fuel gauge.
CM_CHARGER_STAT:
get battery presence from chargers.
`char **psy_charger_stat;`
An array ending with NULL that has power-supply-class names of
chargers. Each power-supply-class should provide "PRESENT" (if
battery_present is "CM_CHARGER_STAT"), "ONLINE" (shows whether an
external power source is attached or not), and "STATUS" (shows whether
the battery is {"FULL" or not FULL} or {"FULL", "Charging",
"Discharging", "NotCharging"}).
int num_charger_regulators;
struct regulator_bulk_data *charger_regulators;
: Regulators representing the chargers in the form for
`int num_charger_regulators; / struct regulator_bulk_data *charger_regulators;`
Regulators representing the chargers in the form for
regulator framework's bulk functions.
char *psy_fuel_gauge;
: Power-supply-class name of the fuel gauge.
`char *psy_fuel_gauge;`
Power-supply-class name of the fuel gauge.
int (*temperature_out_of_range)(int *mC);
bool measure_battery_temp;
: This callback returns 0 if the temperature is safe for charging,
`int (*temperature_out_of_range)(int *mC); / bool measure_battery_temp;`
This callback returns 0 if the temperature is safe for charging,
a positive number if it is too hot to charge, and a negative number
if it is too cold to charge. With the variable mC, the callback returns
the temperature in 1/1000 of centigrade.
The source of temperature can be battery or ambient one according to
the value of measure_battery_temp.
};
5. Notify Charger-Manager of charger events: cm_notify_event()
=========================================================
==============================================================
If there is an charger event is required to notify
Charger Manager, a charger device driver that triggers the event can call
cm_notify_event(psy, type, msg) to notify the corresponding Charger Manager.
......
====================================================
Testing suspend and resume support in device drivers
====================================================
(C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
1. Preparing the test system
============================
Unfortunately, to effectively test the support for the system-wide suspend and
resume transitions in a driver, it is necessary to suspend and resume a fully
......@@ -14,19 +18,20 @@ the machine's BIOS.
Of course, for this purpose the test system has to be known to suspend and
resume without the driver being tested. Thus, if possible, you should first
resolve all suspend/resume-related problems in the test system before you start
testing the new driver. Please see Documentation/power/basic-pm-debugging.txt
testing the new driver. Please see Documentation/power/basic-pm-debugging.rst
for more information about the debugging of suspend/resume functionality.
2. Testing the driver
=====================
Once you have resolved the suspend/resume-related problems with your test system
without the new driver, you are ready to test it:
a) Build the driver as a module, load it and try the test modes of hibernation
(see: Documentation/power/basic-pm-debugging.txt, 1).
(see: Documentation/power/basic-pm-debugging.rst, 1).
b) Load the driver and attempt to hibernate in the "reboot", "shutdown" and
"platform" modes (see: Documentation/power/basic-pm-debugging.txt, 1).
"platform" modes (see: Documentation/power/basic-pm-debugging.rst, 1).
c) Compile the driver directly into the kernel and try the test modes of
hibernation.
......@@ -34,12 +39,12 @@ c) Compile the driver directly into the kernel and try the test modes of
d) Attempt to hibernate with the driver compiled directly into the kernel
in the "reboot", "shutdown" and "platform" modes.
e) Try the test modes of suspend (see: Documentation/power/basic-pm-debugging.txt,
e) Try the test modes of suspend (see: Documentation/power/basic-pm-debugging.rst,
2). [As far as the STR tests are concerned, it should not matter whether or
not the driver is built as a module.]
f) Attempt to suspend to RAM using the s2ram tool with the driver loaded
(see: Documentation/power/basic-pm-debugging.txt, 2).
(see: Documentation/power/basic-pm-debugging.rst, 2).
Each of the above tests should be repeated several times and the STD tests
should be mixed with the STR tests. If any of them fails, the driver cannot be
......
====================
Energy Model of CPUs
====================
====================
Energy Model of CPUs
====================
1. Overview
-----------
......@@ -20,7 +20,7 @@ kernel, hence enabling to avoid redundant work.
The figure below depicts an example of drivers (Arm-specific here, but the
approach is applicable to any architecture) providing power costs to the EM
framework, and interested clients reading the data from it.
framework, and interested clients reading the data from it::
+---------------+ +-----------------+ +---------------+
| Thermal (IPA) | | Scheduler (EAS) | | Other |
......@@ -58,15 +58,17 @@ micro-architectures.
2. Core APIs
------------
2.1 Config options
2.1 Config options
^^^^^^^^^^^^^^^^^^
CONFIG_ENERGY_MODEL must be enabled to use the EM framework.
2.2 Registration of performance domains
2.2 Registration of performance domains
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Drivers are expected to register performance domains into the EM framework by
calling the following API:
calling the following API::
int em_register_perf_domain(cpumask_t *span, unsigned int nr_states,
struct em_data_callback *cb);
......@@ -80,7 +82,8 @@ callback, and kernel/power/energy_model.c for further documentation on this
API.
2.3 Accessing performance domains
2.3 Accessing performance domains
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Subsystems interested in the energy model of a CPU can retrieve it using the
em_cpu_get() API. The energy model tables are allocated once upon creation of
......@@ -99,46 +102,46 @@ More details about the above APIs can be found in include/linux/energy_model.h.
This section provides a simple example of a CPUFreq driver registering a
performance domain in the Energy Model framework using the (fake) 'foo'
protocol. The driver implements an est_power() function to be provided to the
EM framework.
EM framework::
-> drivers/cpufreq/foo_cpufreq.c
01 static int est_power(unsigned long *mW, unsigned long *KHz, int cpu)
02 {
03 long freq, power;
04
05 /* Use the 'foo' protocol to ceil the frequency */
06 freq = foo_get_freq_ceil(cpu, *KHz);
07 if (freq < 0);
08 return freq;
09
10 /* Estimate the power cost for the CPU at the relevant freq. */
11 power = foo_estimate_power(cpu, freq);
12 if (power < 0);
13 return power;
14
15 /* Return the values to the EM framework */
16 *mW = power;
17 *KHz = freq;
18
19 return 0;
20 }
21
22 static int foo_cpufreq_init(struct cpufreq_policy *policy)
23 {
24 struct em_data_callback em_cb = EM_DATA_CB(est_power);
25 int nr_opp, ret;
26
27 /* Do the actual CPUFreq init work ... */
28 ret = do_foo_cpufreq_init(policy);
29 if (ret)
30 return ret;
31
32 /* Find the number of OPPs for this policy */
33 nr_opp = foo_get_nr_opp(policy);
34
35 /* And register the new performance domain */
36 em_register_perf_domain(policy->cpus, nr_opp, &em_cb);
37
38 return 0;
39 }
01 static int est_power(unsigned long *mW, unsigned long *KHz, int cpu)
02 {
03 long freq, power;
04
05 /* Use the 'foo' protocol to ceil the frequency */
06 freq = foo_get_freq_ceil(cpu, *KHz);
07 if (freq < 0);
08 return freq;
09
10 /* Estimate the power cost for the CPU at the relevant freq. */
11 power = foo_estimate_power(cpu, freq);
12 if (power < 0);
13 return power;
14
15 /* Return the values to the EM framework */
16 *mW = power;
17 *KHz = freq;
18
19 return 0;
20 }
21
22 static int foo_cpufreq_init(struct cpufreq_policy *policy)
23 {
24 struct em_data_callback em_cb = EM_DATA_CB(est_power);
25 int nr_opp, ret;
26
27 /* Do the actual CPUFreq init work ... */
28 ret = do_foo_cpufreq_init(policy);
29 if (ret)
30 return ret;
31
32 /* Find the number of OPPs for this policy */
33 nr_opp = foo_get_nr_opp(policy);
34
35 /* And register the new performance domain */
36 em_register_perf_domain(policy->cpus, nr_opp, &em_cb);
37
38 return 0;
39 }
=================
Freezing of tasks
(C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
=================
(C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
I. What is the freezing of tasks?
=================================
The freezing of tasks is a mechanism by which user space processes and some
kernel threads are controlled during hibernation or system-wide suspend (on some
architectures).
II. How does it work?
=====================
There are three per-task flags used for that, PF_NOFREEZE, PF_FROZEN
and PF_FREEZER_SKIP (the last one is auxiliary). The tasks that have
......@@ -41,7 +46,7 @@ explicitly in suitable places or use the wait_event_freezable() or
wait_event_freezable_timeout() macros (defined in include/linux/freezer.h)
that combine interruptible sleep with checking if the task is to be frozen and
calling try_to_freeze(). The main loop of a freezable kernel thread may look
like the following one:
like the following one::
set_freezable();
do {
......@@ -65,7 +70,7 @@ order to clear the PF_FROZEN flag for each frozen task. Then, the tasks that
have been frozen leave __refrigerator() and continue running.
Rationale behind the functions dealing with freezing and thawing of tasks:
Rationale behind the functions dealing with freezing and thawing of tasks
-------------------------------------------------------------------------
freeze_processes():
......@@ -86,6 +91,7 @@ thaw_processes():
III. Which kernel threads are freezable?
========================================
Kernel threads are not freezable by default. However, a kernel thread may clear
PF_NOFREEZE for itself by calling set_freezable() (the resetting of PF_NOFREEZE
......@@ -93,37 +99,39 @@ directly is not allowed). From this point it is regarded as freezable
and must call try_to_freeze() in a suitable place.
IV. Why do we do that?
======================
Generally speaking, there is a couple of reasons to use the freezing of tasks:
1. The principal reason is to prevent filesystems from being damaged after
hibernation. At the moment we have no simple means of checkpointing
filesystems, so if there are any modifications made to filesystem data and/or
metadata on disks, we cannot bring them back to the state from before the
modifications. At the same time each hibernation image contains some
filesystem-related information that must be consistent with the state of the
on-disk data and metadata after the system memory state has been restored from
the image (otherwise the filesystems will be damaged in a nasty way, usually
making them almost impossible to repair). We therefore freeze tasks that might
cause the on-disk filesystems' data and metadata to be modified after the
hibernation image has been created and before the system is finally powered off.
The majority of these are user space processes, but if any of the kernel threads
may cause something like this to happen, they have to be freezable.
hibernation. At the moment we have no simple means of checkpointing
filesystems, so if there are any modifications made to filesystem data and/or
metadata on disks, we cannot bring them back to the state from before the
modifications. At the same time each hibernation image contains some
filesystem-related information that must be consistent with the state of the
on-disk data and metadata after the system memory state has been restored
from the image (otherwise the filesystems will be damaged in a nasty way,
usually making them almost impossible to repair). We therefore freeze
tasks that might cause the on-disk filesystems' data and metadata to be
modified after the hibernation image has been created and before the
system is finally powered off. The majority of these are user space
processes, but if any of the kernel threads may cause something like this
to happen, they have to be freezable.
2. Next, to create the hibernation image we need to free a sufficient amount of
memory (approximately 50% of available RAM) and we need to do that before
devices are deactivated, because we generally need them for swapping out. Then,
after the memory for the image has been freed, we don't want tasks to allocate
additional memory and we prevent them from doing that by freezing them earlier.
[Of course, this also means that device drivers should not allocate substantial
amounts of memory from their .suspend() callbacks before hibernation, but this
is a separate issue.]
memory (approximately 50% of available RAM) and we need to do that before
devices are deactivated, because we generally need them for swapping out.
Then, after the memory for the image has been freed, we don't want tasks
to allocate additional memory and we prevent them from doing that by
freezing them earlier. [Of course, this also means that device drivers
should not allocate substantial amounts of memory from their .suspend()
callbacks before hibernation, but this is a separate issue.]
3. The third reason is to prevent user space processes and some kernel threads
from interfering with the suspending and resuming of devices. A user space
process running on a second CPU while we are suspending devices may, for
example, be troublesome and without the freezing of tasks we would need some
safeguards against race conditions that might occur in such a case.
from interfering with the suspending and resuming of devices. A user space
process running on a second CPU while we are suspending devices may, for
example, be troublesome and without the freezing of tasks we would need some
safeguards against race conditions that might occur in such a case.
Although Linus Torvalds doesn't like the freezing of tasks, he said this in one
of the discussions on LKML (http://lkml.org/lkml/2007/4/27/608):
......@@ -132,7 +140,7 @@ of the discussions on LKML (http://lkml.org/lkml/2007/4/27/608):
Linus: In many ways, 'at all'.
I _do_ realize the IO request queue issues, and that we cannot actually do
I **do** realize the IO request queue issues, and that we cannot actually do
s2ram with some devices in the middle of a DMA. So we want to be able to
avoid *that*, there's no question about that. And I suspect that stopping
user threads and then waiting for a sync is practically one of the easier
......@@ -150,17 +158,18 @@ thawed after the driver's .resume() callback has run, so it won't be accessing
the device while it's suspended.
4. Another reason for freezing tasks is to prevent user space processes from
realizing that hibernation (or suspend) operation takes place. Ideally, user
space processes should not notice that such a system-wide operation has occurred
and should continue running without any problems after the restore (or resume
from suspend). Unfortunately, in the most general case this is quite difficult
to achieve without the freezing of tasks. Consider, for example, a process
that depends on all CPUs being online while it's running. Since we need to
disable nonboot CPUs during the hibernation, if this process is not frozen, it
may notice that the number of CPUs has changed and may start to work incorrectly
because of that.
realizing that hibernation (or suspend) operation takes place. Ideally, user
space processes should not notice that such a system-wide operation has
occurred and should continue running without any problems after the restore
(or resume from suspend). Unfortunately, in the most general case this
is quite difficult to achieve without the freezing of tasks. Consider,
for example, a process that depends on all CPUs being online while it's
running. Since we need to disable nonboot CPUs during the hibernation,
if this process is not frozen, it may notice that the number of CPUs has
changed and may start to work incorrectly because of that.
V. Are there any problems related to the freezing of tasks?
===========================================================
Yes, there are.
......@@ -172,11 +181,12 @@ may be undesirable. That's why kernel threads are not freezable by default.
Second, there are the following two problems related to the freezing of user
space processes:
1. Putting processes into an uninterruptible sleep distorts the load average.
2. Now that we have FUSE, plus the framework for doing device drivers in
userspace, it gets even more complicated because some userspace processes are
now doing the sorts of things that kernel threads do
(https://lists.linux-foundation.org/pipermail/linux-pm/2007-May/012309.html).
userspace, it gets even more complicated because some userspace processes are
now doing the sorts of things that kernel threads do
(https://lists.linux-foundation.org/pipermail/linux-pm/2007-May/012309.html).
The problem 1. seems to be fixable, although it hasn't been fixed so far. The
other one is more serious, but it seems that we can work around it by using
......@@ -201,6 +211,7 @@ requested early enough using the suspend notifier API described in
Documentation/driver-api/pm/notifiers.rst.
VI. Are there any precautions to be taken to prevent freezing failures?
=======================================================================
Yes, there are.
......@@ -226,6 +237,8 @@ So, to summarize, use [un]lock_system_sleep() instead of directly using
mutex_[un]lock(&system_transition_mutex). That would prevent freezing failures.
V. Miscellaneous
================
/sys/power/pm_freeze_timeout controls how long it will cost at most to freeze
all user space processes or all freezable kernel threads, in unit of millisecond.
The default value is 20000, with range of unsigned integer.
:orphan:
================
Power Management
================
.. toctree::
:maxdepth: 1
apm-acpi
basic-pm-debugging
charger-manager
drivers-testing
energy-model
freezing-of-tasks
interface
opp
pci
pm_qos_interface
power_supply_class
runtime_pm
s2ram
suspend-and-cpuhotplug
suspend-and-interrupts
swsusp-and-swap-files
swsusp-dmcrypt
swsusp
video
tricks
userland-swsusp
powercap/powercap
regulator/consumer
regulator/design
regulator/machine
regulator/overview
regulator/regulator
.. only:: subproject and html
Indices
=======
* :ref:`genindex`
===========================================
Power Management Interface for System Sleep
===========================================
Copyright (c) 2016 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com>
......@@ -11,10 +13,10 @@ mounted at /sys).
Reading from it returns a list of supported sleep states, encoded as:
'freeze' (Suspend-to-Idle)
'standby' (Power-On Suspend)
'mem' (Suspend-to-RAM)
'disk' (Suspend-to-Disk)
- 'freeze' (Suspend-to-Idle)
- 'standby' (Power-On Suspend)
- 'mem' (Suspend-to-RAM)
- 'disk' (Suspend-to-Disk)
Suspend-to-Idle is always supported. Suspend-to-Disk is always supported
too as long the kernel has been configured to support hibernation at all
......@@ -32,18 +34,18 @@ Specifically, it tells the kernel what to do after creating a hibernation image.
Reading from it returns a list of supported options encoded as:
'platform' (put the system into sleep using a platform-provided method)
'shutdown' (shut the system down)
'reboot' (reboot the system)
'suspend' (trigger a Suspend-to-RAM transition)
'test_resume' (resume-after-hibernation test mode)
- 'platform' (put the system into sleep using a platform-provided method)
- 'shutdown' (shut the system down)
- 'reboot' (reboot the system)
- 'suspend' (trigger a Suspend-to-RAM transition)
- 'test_resume' (resume-after-hibernation test mode)
The currently selected option is printed in square brackets.
The 'platform' option is only available if the platform provides a special
mechanism to put the system to sleep after creating a hibernation image (ACPI
does that, for example). The 'suspend' option is available if Suspend-to-RAM
is supported. Refer to Documentation/power/basic-pm-debugging.txt for the
is supported. Refer to Documentation/power/basic-pm-debugging.rst for the
description of the 'test_resume' option.
To select an option, write the string representing it to /sys/power/disk.
......@@ -71,7 +73,7 @@ If /sys/power/pm_trace contains '1', the fingerprint of each suspend/resume
event point in turn will be stored in the RTC memory (overwriting the actual
RTC information), so it will survive a system crash if one occurs right after
storing it and it can be used later to identify the driver that caused the crash
to happen (see Documentation/power/s2ram.txt for more information).
to happen (see Documentation/power/s2ram.rst for more information).
Initially it contains '0' which may be changed to '1' by writing a string
representing a nonzero integer into it.
PM Quality Of Service Interface.
===============================
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
......@@ -11,6 +13,7 @@ memory_bandwidth.
constraints and PM QoS flags.
Each parameters have defined units:
* latency: usec
* timeout: usec
* throughput: kbs (kilo bit / sec)
......@@ -18,6 +21,7 @@ Each parameters have defined units:
1. PM QoS framework
===================
The infrastructure exposes multiple misc device nodes one per implemented
parameter. The set of parameters implement is defined by pm_qos_power_init()
......@@ -37,38 +41,39 @@ reading the aggregated value does not require any locking mechanism.
From kernel mode the use of this interface is simple:
void pm_qos_add_request(handle, param_class, target_value):
Will insert an element into the list for that identified PM QoS class 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.
Clients of pm_qos need to save the returned handle for future use in other
pm_qos API functions.
Will insert an element into the list for that identified PM QoS class 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.
Clients of pm_qos need to save the returned handle for future use in other
pm_qos API functions.
void pm_qos_update_request(handle, new_target_value):
Will update the list element pointed to by the handle with the new target value
and recompute the new aggregated target, calling the notification tree if the
target is changed.
Will update the list element pointed to by the handle with the new target value
and recompute the new aggregated target, calling the notification tree if the
target is changed.
void pm_qos_remove_request(handle):
Will remove the element. After removal it will update the aggregate target and
call the notification tree if the target was changed as a result of removing
the request.
Will remove the element. After removal it will update the aggregate target and
call the notification tree if the target was changed as a result of removing
the request.
int pm_qos_request(param_class):
Returns the aggregated value for a given PM QoS class.
Returns the aggregated value for a given PM QoS class.
int pm_qos_request_active(handle):
Returns if the request is still active, i.e. it has not been removed from a
PM QoS class constraints list.
Returns if the request is still active, i.e. it has not been removed from a
PM QoS class constraints list.
int pm_qos_add_notifier(param_class, notifier):
Adds a notification callback function to the PM QoS class. The callback is
called when the aggregated value for the PM QoS class is changed.
Adds a notification callback function to the PM QoS class. The callback is
called when the aggregated value for the PM QoS class is changed.
int pm_qos_remove_notifier(int param_class, notifier):
Removes the notification callback function for the PM QoS class.
Removes the notification callback function for the PM QoS class.
From user mode:
Only processes can register a pm_qos request. To provide for automatic
cleanup of a process, the interface requires the process to register its
parameter requests in the following way:
......@@ -89,6 +94,7 @@ node.
2. PM QoS per-device latency and flags framework
================================================
For each device, there are three lists of PM QoS requests. Two of them are
maintained along with the aggregated targets of resume latency and active
......@@ -107,73 +113,80 @@ the aggregated value does not require any locking mechanism.
From kernel mode the use of this interface is the following:
int dev_pm_qos_add_request(device, handle, type, value):
Will insert an element into the list for that identified device 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.
Clients of dev_pm_qos need to save the handle for future use in other
dev_pm_qos API functions.
Will insert an element into the list for that identified device 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.
Clients of dev_pm_qos need to save the handle for future use in other
dev_pm_qos API functions.
int dev_pm_qos_update_request(handle, new_value):
Will update the list element pointed to by the handle with the new target value
and recompute the new aggregated target, calling the notification trees if the
target is changed.
Will update the list element pointed to by the handle with the new target
value and recompute the new aggregated target, calling the notification
trees if the target is changed.
int dev_pm_qos_remove_request(handle):
Will remove the element. After removal it will update the aggregate target and
call the notification trees if the target was changed as a result of removing
the request.
Will remove the element. After removal it will update the aggregate target
and call the notification trees if the target was changed as a result of
removing the request.
s32 dev_pm_qos_read_value(device):
Returns the aggregated value for a given device's constraints list.
Returns the aggregated value for a given device's constraints list.
enum pm_qos_flags_status dev_pm_qos_flags(device, mask)
Check PM QoS flags of the given device against the given mask of flags.
The meaning of the return values is as follows:
PM_QOS_FLAGS_ALL: All flags from the mask are set
PM_QOS_FLAGS_SOME: Some flags from the mask are set
PM_QOS_FLAGS_NONE: No flags from the mask are set
PM_QOS_FLAGS_UNDEFINED: The device's PM QoS structure has not been
initialized or the list of requests is empty.
Check PM QoS flags of the given device against the given mask of flags.
The meaning of the return values is as follows:
PM_QOS_FLAGS_ALL:
All flags from the mask are set
PM_QOS_FLAGS_SOME:
Some flags from the mask are set
PM_QOS_FLAGS_NONE:
No flags from the mask are set
PM_QOS_FLAGS_UNDEFINED:
The device's PM QoS structure has not been initialized
or the list of requests is empty.
int dev_pm_qos_add_ancestor_request(dev, handle, type, value)
Add a PM QoS request for the first direct ancestor of the given device whose
power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests)
or whose power.set_latency_tolerance callback pointer is not NULL (for
DEV_PM_QOS_LATENCY_TOLERANCE requests).
Add a PM QoS request for the first direct ancestor of the given device whose
power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests)
or whose power.set_latency_tolerance callback pointer is not NULL (for
DEV_PM_QOS_LATENCY_TOLERANCE requests).
int dev_pm_qos_expose_latency_limit(device, value)
Add a request to the device's PM QoS list of resume latency constraints and
create a sysfs attribute pm_qos_resume_latency_us under the device's power
directory allowing user space to manipulate that request.
Add a request to the device's PM QoS list of resume latency constraints and
create a sysfs attribute pm_qos_resume_latency_us under the device's power
directory allowing user space to manipulate that request.
void dev_pm_qos_hide_latency_limit(device)
Drop the request added by dev_pm_qos_expose_latency_limit() from the device's
PM QoS list of resume latency constraints and remove sysfs attribute
pm_qos_resume_latency_us from the device's power directory.
Drop the request added by dev_pm_qos_expose_latency_limit() from the device's
PM QoS list of resume latency constraints and remove sysfs attribute
pm_qos_resume_latency_us from the device's power directory.
int dev_pm_qos_expose_flags(device, value)
Add a request to the device's PM QoS list of flags and create sysfs attribute
pm_qos_no_power_off under the device's power directory allowing user space to
change the value of the PM_QOS_FLAG_NO_POWER_OFF flag.
Add a request to the device's PM QoS list of flags and create sysfs attribute
pm_qos_no_power_off under the device's power directory allowing user space to
change the value of the PM_QOS_FLAG_NO_POWER_OFF flag.
void dev_pm_qos_hide_flags(device)
Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS list
of flags and remove sysfs attribute pm_qos_no_power_off from the device's power
directory.
Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS list
of flags and remove sysfs attribute pm_qos_no_power_off from the device's power
directory.
Notification mechanisms:
The per-device PM QoS framework has a per-device notification tree.
int dev_pm_qos_add_notifier(device, notifier):
Adds a notification callback function for the device.
The callback is called when the aggregated value of the device constraints list
is changed (for resume latency device PM QoS only).
Adds a notification callback function for the device.
The callback is called when the aggregated value of the device constraints list
is changed (for resume latency device PM QoS only).
int dev_pm_qos_remove_notifier(device, notifier):
Removes the notification callback function for the device.
Removes the notification callback function for the device.
Active state latency tolerance
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This device PM QoS type is used to support systems in which hardware may switch
to energy-saving operation modes on the fly. In those systems, if the operation
......
==========================
Regulator API design notes
==========================
......@@ -14,7 +15,9 @@ Safety
have different power requirements, and not all components with power
requirements are visible to software.
=> The API should make no changes to the hardware state unless it has
.. note::
The API should make no changes to the hardware state unless it has
specific knowledge that these changes are safe to perform on this
particular system.
......@@ -28,6 +31,8 @@ Consumer use cases
- Many of the power supplies in the system will be shared between many
different consumers.
=> The consumer API should be structured so that these use cases are
.. note::
The consumer API should be structured so that these use cases are
very easy to handle and so that consumers will work with shared
supplies without any additional effort.
==================================
Regulator Machine Driver Interface
===================================
==================================
The regulator machine driver interface is intended for board/machine specific
initialisation code to configure the regulator subsystem.
Consider the following machine :-
Consider the following machine::
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
......@@ -13,31 +14,31 @@ Consider the following machine :-
The drivers for consumers A & B must be mapped to the correct regulator in
order to control their power supplies. This mapping can be achieved in machine
initialisation code by creating a struct regulator_consumer_supply for
each regulator.
each regulator::
struct regulator_consumer_supply {
struct regulator_consumer_supply {
const char *dev_name; /* consumer dev_name() */
const char *supply; /* consumer supply - e.g. "vcc" */
};
};
e.g. for the machine above
e.g. for the machine above::
static struct regulator_consumer_supply regulator1_consumers[] = {
static struct regulator_consumer_supply regulator1_consumers[] = {
REGULATOR_SUPPLY("Vcc", "consumer B"),
};
};
static struct regulator_consumer_supply regulator2_consumers[] = {
static struct regulator_consumer_supply regulator2_consumers[] = {
REGULATOR_SUPPLY("Vcc", "consumer A"),
};
};
This maps Regulator-1 to the 'Vcc' supply for Consumer B and maps Regulator-2
to the 'Vcc' supply for Consumer A.
Constraints can now be registered by defining a struct regulator_init_data
for each regulator power domain. This structure also maps the consumers
to their supply regulators :-
to their supply regulators::
static struct regulator_init_data regulator1_data = {
static struct regulator_init_data regulator1_data = {
.constraints = {
.name = "Regulator-1",
.min_uV = 3300000,
......@@ -46,7 +47,7 @@ static struct regulator_init_data regulator1_data = {
},
.num_consumer_supplies = ARRAY_SIZE(regulator1_consumers),
.consumer_supplies = regulator1_consumers,
};
};
The name field should be set to something that is usefully descriptive
for the board for configuration of supplies for other regulators and
......@@ -57,9 +58,9 @@ name is provided then the subsystem will choose one.
Regulator-1 supplies power to Regulator-2. This relationship must be registered
with the core so that Regulator-1 is also enabled when Consumer A enables its
supply (Regulator-2). The supply regulator is set by the supply_regulator
field below and co:-
field below and co::
static struct regulator_init_data regulator2_data = {
static struct regulator_init_data regulator2_data = {
.supply_regulator = "Regulator-1",
.constraints = {
.min_uV = 1800000,
......@@ -69,11 +70,11 @@ static struct regulator_init_data regulator2_data = {
},
.num_consumer_supplies = ARRAY_SIZE(regulator2_consumers),
.consumer_supplies = regulator2_consumers,
};
};
Finally the regulator devices must be registered in the usual manner.
Finally the regulator devices must be registered in the usual manner::
static struct platform_device regulator_devices[] = {
static struct platform_device regulator_devices[] = {
{
.name = "regulator",
.id = DCDC_1,
......@@ -88,9 +89,9 @@ static struct platform_device regulator_devices[] = {
.platform_data = &regulator2_data,
},
},
};
/* register regulator 1 device */
platform_device_register(&regulator_devices[0]);
};
/* register regulator 1 device */
platform_device_register(&regulator_devices[0]);
/* register regulator 2 device */
platform_device_register(&regulator_devices[1]);
/* register regulator 2 device */
platform_device_register(&regulator_devices[1]);
=============================================
Linux voltage and current regulator framework
=============================================
......@@ -13,26 +14,30 @@ regulators (where voltage output is controllable) and current sinks (where
current limit is controllable).
(C) 2008 Wolfson Microelectronics PLC.
Author: Liam Girdwood <lrg@slimlogic.co.uk>
Nomenclature
============
Some terms used in this document:-
Some terms used in this document:
o Regulator - Electronic device that supplies power to other devices.
- Regulator
- Electronic device that supplies power to other devices.
Most regulators can enable and disable their output while
some can control their output voltage and or current.
Input Voltage -> Regulator -> Output Voltage
o PMIC - Power Management IC. An IC that contains numerous regulators
and often contains other subsystems.
- PMIC
- Power Management IC. An IC that contains numerous
regulators and often contains other subsystems.
o Consumer - Electronic device that is supplied power by a regulator.
- Consumer
- Electronic device that is supplied power by a regulator.
Consumers can be classified into two types:-
Static: consumer does not change its supply voltage or
......@@ -44,11 +49,12 @@ Some terms used in this document:-
current limit to meet operation demands.
o Power Domain - Electronic circuit that is supplied its input power by the
- Power Domain
- Electronic circuit that is supplied its input power by the
output power of a regulator, switch or by another power
domain.
The supply regulator may be behind a switch(s). i.e.
The supply regulator may be behind a switch(s). i.e.::
Regulator -+-> Switch-1 -+-> Switch-2 --> [Consumer A]
| |
......@@ -58,16 +64,16 @@ Some terms used in this document:-
That is one regulator and three power domains:
Domain 1: Switch-1, Consumers D & E.
Domain 2: Switch-2, Consumers B & C.
Domain 3: Consumer A.
- Domain 1: Switch-1, Consumers D & E.
- Domain 2: Switch-2, Consumers B & C.
- Domain 3: Consumer A.
and this represents a "supplies" relationship:
Domain-1 --> Domain-2 --> Domain-3.
A power domain may have regulators that are supplied power
by other regulators. i.e.
by other regulators. i.e.::
Regulator-1 -+-> Regulator-2 -+-> [Consumer A]
|
......@@ -75,15 +81,16 @@ Some terms used in this document:-
This gives us two regulators and two power domains:
Domain 1: Regulator-2, Consumer B.
Domain 2: Consumer A.
- Domain 1: Regulator-2, Consumer B.
- Domain 2: Consumer A.
and a "supplies" relationship:
Domain-1 --> Domain-2
o Constraints - Constraints are used to define power levels for performance
- Constraints
- Constraints are used to define power levels for performance
and hardware protection. Constraints exist at three levels:
Regulator Level: This is defined by the regulator hardware
......@@ -141,7 +148,7 @@ relevant to non SoC devices and is split into the following four interfaces:-
limit. This also compiles out if not in use so drivers can be reused in
systems with no regulator based power control.
See Documentation/power/regulator/consumer.txt
See Documentation/power/regulator/consumer.rst
2. Regulator driver interface.
......@@ -149,7 +156,7 @@ relevant to non SoC devices and is split into the following four interfaces:-
operations to the core. It also has a notifier call chain for propagating
regulator events to clients.
See Documentation/power/regulator/regulator.txt
See Documentation/power/regulator/regulator.rst
3. Machine interface.
......@@ -160,7 +167,7 @@ relevant to non SoC devices and is split into the following four interfaces:-
allows the creation of a regulator tree whereby some regulators are
supplied by others (similar to a clock tree).
See Documentation/power/regulator/machine.txt
See Documentation/power/regulator/machine.rst
4. Userspace ABI.
......
==========================
Regulator Driver Interface
==========================
......@@ -8,23 +9,24 @@ regulator drivers to register their services with the core framework.
Registration
============
Drivers can register a regulator by calling :-
Drivers can register a regulator by calling::
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
const struct regulator_config *config);
This will register the regulator's capabilities and operations to the regulator
core.
Regulators can be unregistered by calling :-
Regulators can be unregistered by calling::
void regulator_unregister(struct regulator_dev *rdev);
void regulator_unregister(struct regulator_dev *rdev);
Regulator Events
================
Regulators can send events (e.g. overtemperature, undervoltage, etc) to
consumer drivers by calling :-
consumer drivers by calling::
int regulator_notifier_call_chain(struct regulator_dev *rdev,
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data);
How to get s2ram working
~~~~~~~~~~~~~~~~~~~~~~~~
2006 Linus Torvalds
2006 Pavel Machek
========================
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.
......@@ -12,8 +14,8 @@
3) You can use Linus' TRACE_RESUME infrastructure, described below.
Using TRACE_RESUME
~~~~~~~~~~~~~~~~~~
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
......@@ -27,7 +29,7 @@ machine that doesn't boot) is:
- enable PM_DEBUG, and PM_TRACE
- use a script like this:
- use a script like this::
#!/bin/sh
sync
......@@ -38,7 +40,7 @@ machine that doesn't boot) is:
- 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
like::
Magic number: 4:156:725
hash matches drivers/base/power/resume.c:28
......@@ -52,7 +54,7 @@ machine that doesn't boot) is:
If no device matches the hash (or any matches appear to be false positives),
the culprit may be a device from a loadable kernel module that is not loaded
until after the hash is checked. You can check the hash against the current
devices again after more modules are loaded using sysfs:
devices again after more modules are loaded using sysfs::
cat /sys/power/pm_trace_dev_match
......
====================================================================
Interaction of Suspend code (S3) with the CPU hotplug infrastructure
====================================================================
(C) 2011 - 2014 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
(C) 2011 - 2014 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
I. How does the regular CPU hotplug code differ from how the Suspend-to-RAM
infrastructure uses it internally? And where do they share common code?
I. Differences between CPU hotplug and Suspend-to-RAM
======================================================
How does the regular CPU hotplug code differ from how the Suspend-to-RAM
infrastructure uses it internally? And where do they share common code?
Well, a picture is worth a thousand words... So ASCII art follows :-)
......@@ -16,13 +21,13 @@ of describing where they take different paths and where they share code.
What happens when regular CPU hotplug and Suspend-to-RAM race with each other
is not depicted here.]
On a high level, the suspend-resume cycle goes like this:
On a high level, the suspend-resume cycle goes like this::
|Freeze| -> |Disable nonboot| -> |Do suspend| -> |Enable nonboot| -> |Thaw |
|tasks | | cpus | | | | cpus | |tasks|
|Freeze| -> |Disable nonboot| -> |Do suspend| -> |Enable nonboot| -> |Thaw |
|tasks | | cpus | | | | cpus | |tasks|
More details follow:
More details follow::
Suspend call path
-----------------
......@@ -87,7 +92,9 @@ More details follow:
Resuming back is likewise, with the counterparts being (in the order of
execution during resume):
* enable_nonboot_cpus() which involves:
* enable_nonboot_cpus() which involves::
| Acquire cpu_add_remove_lock
| Decrease cpu_hotplug_disabled, thereby enabling regular cpu hotplug
| Call _cpu_up() [for all those cpus in the frozen_cpus mask, in a loop]
......@@ -103,6 +110,8 @@ It is to be noted here that the system_transition_mutex lock is acquired at the
beginning, when we are just starting out to suspend, and then released only
after the entire cycle is complete (i.e., suspend + resume).
::
Regular CPU hotplug call path
......@@ -152,16 +161,16 @@ with the 'tasks_frozen' argument set to 1.
Important files and functions/entry points:
------------------------------------------
-------------------------------------------
kernel/power/process.c : freeze_processes(), thaw_processes()
kernel/power/suspend.c : suspend_prepare(), suspend_enter(), suspend_finish()
kernel/cpu.c: cpu_[up|down](), _cpu_[up|down](), [disable|enable]_nonboot_cpus()
- kernel/power/process.c : freeze_processes(), thaw_processes()
- kernel/power/suspend.c : suspend_prepare(), suspend_enter(), suspend_finish()
- kernel/cpu.c: cpu_[up|down](), _cpu_[up|down](), [disable|enable]_nonboot_cpus()
II. What are the issues involved in CPU hotplug?
-------------------------------------------
------------------------------------------------
There are some interesting situations involving CPU hotplug and microcode
update on the CPUs, as discussed below:
......@@ -243,8 +252,11 @@ d. Handling microcode update during suspend/hibernate:
cycles).
III. Are there any known problems when regular CPU hotplug and suspend race
with each other?
III. Known problems
===================
Are there any known problems when regular CPU hotplug and suspend race
with each other?
Yes, they are listed below:
......
====================================
System Suspend and Device Interrupts
====================================
Copyright (C) 2014 Intel Corp.
Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
......
===============================================
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
......@@ -21,20 +24,20 @@ units.
In order to use a swap file with swsusp, you need to:
1) Create the swap file and make it active, eg.
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>
# 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:
3) Add the following parameters to the kernel command line::
resume=<swap_file_partition> resume_offset=<swap_file_offset>
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
......@@ -46,7 +49,7 @@ 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
Documentation/power/userland-swsusp.rst (this is the only method to suspend
to a swap file allowing the resume to be initiated from an initrd or initramfs
image).
......
=======================================
How to use dm-crypt and swsusp together
=======================================
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 have read Documentation/power/swsusp.rst and understand it.
You did read Documentation/admin-guide/initrd.rst and know how an initrd works.
You know how to create or how to modify an initrd.
......@@ -29,23 +31,23 @@ 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:
it will always look like the following::
brw------- 1 root root 254, 0 Jul 28 13:37 /dev/mapper/swap0
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:
resume partition, so your kernel .config contains::
CONFIG_PM_STD_PARTITION="/dev/mapper/swap0"
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:
lines::
image=/boot/vmlinuz
initrd=/boot/initrd.gz
label=linux
append="root=/dev/ram0 init=/linuxrc rw"
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
......@@ -53,33 +55,33 @@ 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:
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 /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
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
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
......@@ -92,27 +94,27 @@ do
break
fi
usleep 500000
done
killproc /sbin/cardmgr
dmesg -n 6
if [ $mapped = 1 ]
then
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
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?
......
This diff is collapsed.
This diff is collapsed.
swsusp/S3 tricks
~~~~~~~~~~~~~~~~
================
swsusp/S3 tricks
================
Pavel Machek <pavel@ucw.cz>
If you want to trick swsusp/S3 into working, you might want to try:
......
=====================================================
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.
......@@ -30,13 +33,16 @@ called.
The ioctl() commands recognized by the device are:
SNAPSHOT_FREEZE - freeze user space processes (the current process is
SNAPSHOT_FREEZE
freeze user space processes (the current process is
not frozen); this is required for SNAPSHOT_CREATE_IMAGE
and SNAPSHOT_ATOMIC_RESTORE to succeed
SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE
SNAPSHOT_UNFREEZE
thaw user space processes frozen by SNAPSHOT_FREEZE
SNAPSHOT_CREATE_IMAGE - create a snapshot of the system memory; the
SNAPSHOT_CREATE_IMAGE
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
......@@ -45,48 +51,59 @@ SNAPSHOT_CREATE_IMAGE - create a snapshot of the system memory; the
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
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_FREE
free memory allocated for the snapshot image
SNAPSHOT_PREF_IMAGE_SIZE - set the preferred maximum size of the image
SNAPSHOT_PREF_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_GET_IMAGE_SIZE - return the actual size of the hibernation image
SNAPSHOT_GET_IMAGE_SIZE
return the actual size of the hibernation image
SNAPSHOT_AVAIL_SWAP_SIZE - return the amount of available swap in bytes (the
SNAPSHOT_AVAIL_SWAP_SIZE
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_ALLOC_SWAP_PAGE - allocate a swap page from the resume partition
SNAPSHOT_ALLOC_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 by
SNAPSHOT_FREE_SWAP_PAGES
free all swap pages allocated by
SNAPSHOT_ALLOC_SWAP_PAGE
SNAPSHOT_SET_SWAP_AREA - set the resume partition and the offset (in <PAGE_SIZE>
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/suspend_ioctls.h,
containing the resume device specification and the offset); for swap
partitions the offset is always 0, but it is different from zero for
swap files (see Documentation/power/swsusp-and-swap-files.txt for
swap files (see Documentation/power/swsusp-and-swap-files.rst for
details).
SNAPSHOT_PLATFORM_SUPPORT - enable/disable the hibernation platform support,
SNAPSHOT_PLATFORM_SUPPORT
enable/disable the hibernation platform support,
depending on the argument value (enable, if the argument is nonzero)
SNAPSHOT_POWER_OFF - make the kernel transition the system to the hibernation
SNAPSHOT_POWER_OFF
make the kernel transition the system to the hibernation
state (eg. ACPI S4) using the platform (eg. ACPI) driver
SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to
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
......@@ -98,10 +115,11 @@ SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to
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 across page boundaries are impossible (ie. if you 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)
**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.
......@@ -143,8 +161,10 @@ preferably using mlockall(), before calling SNAPSHOT_FREEZE.
The suspending utility MUST check the value stored by SNAPSHOT_CREATE_IMAGE
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
......@@ -158,6 +178,7 @@ in accordance with it:
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,
......
......@@ -117,7 +117,7 @@ PM support:
implemented") error. You should also try to make sure that your
driver uses as little power as possible when it's not doing
anything. For the driver testing instructions see
Documentation/power/drivers-testing.txt and for a relatively
Documentation/power/drivers-testing.rst and for a relatively
complete overview of the power management issues related to
drivers see :ref:`Documentation/driver-api/pm/devices.rst <driverapi_pm_devices>`.
......
......@@ -22,7 +22,7 @@ the highest.
The actual EM used by EAS is _not_ maintained by the scheduler, but by a
dedicated framework. For details about this framework and what it provides,
please refer to its documentation (see Documentation/power/energy-model.txt).
please refer to its documentation (see Documentation/power/energy-model.rst).
2. Background and Terminology
......@@ -81,7 +81,7 @@ through the arch_scale_cpu_capacity() callback.
The rest of platform knowledge used by EAS is directly read from the Energy
Model (EM) framework. The EM of a platform is composed of a power cost table
per 'performance domain' in the system (see Documentation/power/energy-model.txt
per 'performance domain' in the system (see Documentation/power/energy-model.rst
for futher details about performance domains).
The scheduler manages references to the EM objects in the topology code when the
......@@ -352,7 +352,7 @@ could be amended in the future if proven otherwise.
EAS uses the EM of a platform to estimate the impact of scheduling decisions on
energy. So, your platform must provide power cost tables to the EM framework in
order to make EAS start. To do so, please refer to documentation of the
independent EM framework in Documentation/power/energy-model.txt.
independent EM framework in Documentation/power/energy-model.rst.
Please also note that the scheduling domains need to be re-built after the
EM has been registered in order to start EAS.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment