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.
Unified · Split
| @@ -5,7 +5,7 @@ Contact: linux-pm@vger.kernel.org · 4 unmodified lines | ||
| 5 | 5 | Description: |
| 6 | 6 | The powercap/ class sub directory belongs to the power cap |
| 7 | 7 | subsystem. Refer to |
| 8 | − Documentation/power/powercap/powercap.txt for details. | |
| 8 | + Documentation/power/powercap/powercap.rst for details. | |
| 9 | 9 | |
| 10 | 10 | What: /sys/class/powercap/<control type> |
| 11 | 11 | Date: September 2013 |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | For ARM64, ONLY "acpi=off", "acpi=on" or "acpi=force" |
| 14 | 14 | are available |
| 15 | 15 | |
| 16 | − See also Documentation/power/runtime_pm.txt, pci=noacpi | |
| 16 | + See also Documentation/power/runtime_pm.rst, pci=noacpi | |
| 17 | 17 | |
| 18 | 18 | acpi_apic_instance= [ACPI, IOAPIC] |
| 19 | 19 | Format: <int> |
| @@ -223,7 +223,7 @@ · 203 unmodified lines | ||
| 223 | 223 | acpi_sleep= [HW,ACPI] Sleep options |
| 224 | 224 | Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, |
| 225 | 225 | old_ordering, nonvs, sci_force_enable, nobl } |
| 226 | − See Documentation/power/video.txt for information on | |
| 226 | + See Documentation/power/video.rst for information on | |
| 227 | 227 | s3_bios and s3_mode. |
| 228 | 228 | s3_beep is for debugging; it makes the PC's speaker beep |
| 229 | 229 | as soon as the kernel's real-mode entry point is called. |
| @@ -4108,7 +4108,7 @@ · 3878 unmodified lines | ||
| 4108 | 4108 | Specify the offset from the beginning of the partition |
| 4109 | 4109 | given by "resume=" at which the swap header is located, |
| 4110 | 4110 | in <PAGE_SIZE> units (needed only for swap files). |
| 4111 | − See Documentation/power/swsusp-and-swap-files.txt | |
| 4111 | + See Documentation/power/swsusp-and-swap-files.rst | |
| 4112 | 4112 | |
| 4113 | 4113 | resumedelay= [HIBERNATION] Delay (in seconds) to pause before attempting to |
| 4114 | 4114 | read the resume files |
| @@ -95,7 +95,7 @@ flags - flags of the cpufreq driver · 94 unmodified lines | ||
| 95 | 95 | |
| 96 | 96 | 3. CPUFreq Table Generation with Operating Performance Point (OPP) |
| 97 | 97 | ================================================================== |
| 98 | −For details about OPP, see Documentation/power/opp.txt | |
| 98 | +For details about OPP, see Documentation/power/opp.rst | |
| 99 | 99 | |
| 100 | 100 | dev_pm_opp_init_cpufreq_table - |
| 101 | 101 | 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` · 224 unmodified lines | ||
| 225 | 225 | flag is clear. |
| 226 | 226 | |
| 227 | 227 | For more information about the runtime power management framework, refer to |
| 228 | −:file:`Documentation/power/runtime_pm.txt`. | |
| 228 | +:file:`Documentation/power/runtime_pm.rst`. | |
| 229 | 229 | |
| 230 | 230 | |
| 231 | 231 | Calling Drivers to Enter and Leave System Sleep States |
| @@ -728,7 +728,7 @@ it into account in any way. · 496 unmodified lines | ||
| 728 | 728 | |
| 729 | 729 | Devices may be defined as IRQ-safe which indicates to the PM core that their |
| 730 | 730 | runtime PM callbacks may be invoked with disabled interrupts (see |
| 731 | −:file:`Documentation/power/runtime_pm.txt` for more information). If an | |
| 731 | +:file:`Documentation/power/runtime_pm.rst` for more information). If an | |
| 732 | 732 | IRQ-safe device belongs to a PM domain, the runtime PM of the domain will be |
| 733 | 733 | disallowed, unless the domain itself is defined as IRQ-safe. However, it |
| 734 | 734 | 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 · 60 unmodified lines | ||
| 795 | 795 | status in that case. |
| 796 | 796 | |
| 797 | 797 | During system-wide resume from a sleep state it's easiest to put devices into |
| 798 | −the full-power state, as explained in :file:`Documentation/power/runtime_pm.txt`. | |
| 798 | +the full-power state, as explained in :file:`Documentation/power/runtime_pm.rst`. | |
| 799 | 799 | [Refer to that document for more information regarding this particular issue as |
| 800 | 800 | well as for information on the device runtime power management framework in |
| 801 | 801 | general.] |
| @@ -46,7 +46,7 @@ device is turned off while the system as a whole remains running, we · 45 unmodified lines | ||
| 46 | 46 | call it a "dynamic suspend" (also known as a "runtime suspend" or |
| 47 | 47 | "selective suspend"). This document concentrates mostly on how |
| 48 | 48 | dynamic PM is implemented in the USB subsystem, although system PM is |
| 49 | −covered to some extent (see ``Documentation/power/*.txt`` for more | |
| 49 | +covered to some extent (see ``Documentation/power/*.rst`` for more | |
| 50 | 50 | information about system PM). |
| 51 | 51 | |
| 52 | 52 | System PM support is present only if the kernel was built with |
| @@ -1,5 +1,7 @@ | ||
| 1 | +============ | |
| 1 | 2 | APM or ACPI? |
| 2 | −------------ | |
| 3 | +============ | |
| 4 | + | |
| 3 | 5 | If you have a relatively recent x86 mobile, desktop, or server system, |
| 4 | 6 | odds are it supports either Advanced Power Management (APM) or |
| 5 | 7 | 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. · 22 unmodified lines | ||
| 28 | 30 | Go ahead and start both. If ACPI or APM is not available on your |
| 29 | 31 | system the associated daemon will exit gracefully. |
| 30 | 32 | |
| 31 | − apmd: http://ftp.debian.org/pool/main/a/apmd/ | |
| 32 | − acpid: http://acpid.sf.net/ | |
| 33 | + ===== ======================================= | |
| 34 | + apmd http://ftp.debian.org/pool/main/a/apmd/ | |
| 35 | + acpid http://acpid.sf.net/ | |
| 36 | + ===== ======================================= | |
| @@ -1,12 +1,16 @@ | ||
| 1 | +================================= | |
| 1 | 2 | Debugging hibernation and suspend |
| 3 | +================================= | |
| 4 | + | |
| 2 | 5 | (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL |
| 3 | 6 | |
| 4 | 7 | 1. Testing hibernation (aka suspend to disk or STD) |
| 8 | +=================================================== | |
| 5 | 9 | |
| 6 | −To check if hibernation works, you can try to hibernate in the "reboot" mode: | |
| 10 | +To check if hibernation works, you can try to hibernate in the "reboot" mode:: | |
| 7 | 11 | |
| 8 | −# echo reboot > /sys/power/disk | |
| 9 | −# echo disk > /sys/power/state | |
| 12 | + # echo reboot > /sys/power/disk | |
| 13 | + # echo disk > /sys/power/state | |
| 10 | 14 | |
| 11 | 15 | and the system should create a hibernation image, reboot, resume and get back to |
| 12 | 16 | 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, · 2 unmodified lines | ||
| 15 | 19 | because some problems only show up on a second attempt at suspending and |
| 16 | 20 | resuming the system.] Moreover, hibernating in the "reboot" and "shutdown" |
| 17 | 21 | modes causes the PM core to skip some platform-related callbacks which on ACPI |
| 18 | −systems might be necessary to make hibernation work. Thus, if your machine fails | |
| 19 | −to hibernate or resume in the "reboot" mode, you should try the "platform" mode: | |
| 22 | +systems might be necessary to make hibernation work. Thus, if your machine | |
| 23 | +fails to hibernate or resume in the "reboot" mode, you should try the | |
| 24 | +"platform" mode:: | |
| 20 | 25 | |
| 21 | −# echo platform > /sys/power/disk | |
| 22 | −# echo disk > /sys/power/state | |
| 26 | + # echo platform > /sys/power/disk | |
| 27 | + # echo disk > /sys/power/state | |
| 23 | 28 | |
| 24 | 29 | which is the default and recommended mode of hibernation. |
| 25 | 30 | |
| 26 | 31 | Unfortunately, the "platform" mode of hibernation does not work on some systems |
| 27 | 32 | with broken BIOSes. In such cases the "shutdown" mode of hibernation might |
| 28 | −work: | |
| 33 | +work:: | |
| 29 | 34 | |
| 30 | −# echo shutdown > /sys/power/disk | |
| 31 | −# echo disk > /sys/power/state | |
| 35 | + # echo shutdown > /sys/power/disk | |
| 36 | + # echo disk > /sys/power/state | |
| 32 | 37 | |
| 33 | 38 | (it is similar to the "reboot" mode, but it requires you to press the power |
| 34 | 39 | button to make the system resume). |
| @@ -37,6 +42,7 @@ If neither "platform" nor "shutdown" hibernation mode works, you will need to · 2 unmodified lines | ||
| 37 | 42 | identify what goes wrong. |
| 38 | 43 | |
| 39 | 44 | a) Test modes of hibernation |
| 45 | +---------------------------- | |
| 40 | 46 | |
| 41 | 47 | To find out why hibernation fails on your system, you can use a special testing |
| 42 | 48 | 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 · 1 unmodified line | ||
| 44 | 50 | core run in a test mode. There are 5 test modes available: |
| 45 | 51 | |
| 46 | 52 | freezer |
| 47 | −- test the freezing of processes | |
| 53 | + - test the freezing of processes | |
| 48 | 54 | |
| 49 | 55 | devices |
| 50 | −- test the freezing of processes and suspending of devices | |
| 56 | + - test the freezing of processes and suspending of devices | |
| 51 | 57 | |
| 52 | 58 | platform |
| 53 | −- test the freezing of processes, suspending of devices and platform | |
| 54 | − global control methods(*) | |
| 59 | + - test the freezing of processes, suspending of devices and platform | |
| 60 | + global control methods [1]_ | |
| 55 | 61 | |
| 56 | 62 | processors |
| 57 | −- test the freezing of processes, suspending of devices, platform | |
| 58 | − global control methods(*) and the disabling of nonboot CPUs | |
| 63 | + - test the freezing of processes, suspending of devices, platform | |
| 64 | + global control methods [1]_ and the disabling of nonboot CPUs | |
| 59 | 65 | |
| 60 | 66 | core |
| 61 | −- test the freezing of processes, suspending of devices, platform global | |
| 62 | − control methods(*), the disabling of nonboot CPUs and suspending of | |
| 63 | − platform/system devices | |
| 67 | + - test the freezing of processes, suspending of devices, platform global | |
| 68 | + control methods\ [1]_, the disabling of nonboot CPUs and suspending | |
| 69 | + of platform/system devices | |
| 70 | + | |
| 71 | +.. [1] | |
| 64 | 72 | |
| 65 | −(*) the platform global control methods are only available on ACPI systems | |
| 73 | + the platform global control methods are only available on ACPI systems | |
| 66 | 74 | and are only tested if the hibernation mode is set to "platform" |
| 67 | 75 | |
| 68 | 76 | To use one of them it is necessary to write the corresponding string to |
| 69 | 77 | /sys/power/pm_test (eg. "devices" to test the freezing of processes and |
| 70 | 78 | suspending devices) and issue the standard hibernation commands. For example, |
| 71 | 79 | to use the "devices" test mode along with the "platform" mode of hibernation, |
| 72 | −you should do the following: | |
| 80 | +you should do the following:: | |
| 73 | 81 | |
| 74 | −# echo devices > /sys/power/pm_test | |
| 75 | −# echo platform > /sys/power/disk | |
| 76 | −# echo disk > /sys/power/state | |
| 82 | + # echo devices > /sys/power/pm_test | |
| 83 | + # echo platform > /sys/power/disk | |
| 84 | + # echo disk > /sys/power/state | |
| 77 | 85 | |
| 78 | 86 | Then, the kernel will try to freeze processes, suspend devices, wait a few |
| 79 | 87 | 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 · 28 unmodified lines | ||
| 108 | 116 | or resume its device (in the latter case the system may hang or become unstable |
| 109 | 117 | after the test, so please take that into consideration). To find this driver, |
| 110 | 118 | you can carry out a binary search according to the rules: |
| 119 | + | |
| 111 | 120 | - if the test fails, unload a half of the drivers currently loaded and repeat |
| 112 | −(that would probably involve rebooting the system, so always note what drivers | |
| 113 | −have been loaded before the test), | |
| 121 | + (that would probably involve rebooting the system, so always note what drivers | |
| 122 | + have been loaded before the test), | |
| 114 | 123 | - if the test succeeds, load a half of the drivers you have unloaded most |
| 115 | −recently and repeat. | |
| 124 | + recently and repeat. | |
| 116 | 125 | |
| 117 | 126 | Once you have found the failing driver (there can be more than just one of |
| 118 | 127 | 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 · 27 unmodified lines | ||
| 146 | 155 | please report it anyway. |
| 147 | 156 | |
| 148 | 157 | b) Testing minimal configuration |
| 158 | +-------------------------------- | |
| 149 | 159 | |
| 150 | 160 | If all of the hibernation test modes work, you can boot the system with the |
| 151 | 161 | "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 · 13 unmodified lines | ||
| 165 | 175 | before hibernation, and please report the problem with it(them). |
| 166 | 176 | |
| 167 | 177 | c) Using the "test_resume" hibernation option |
| 178 | +--------------------------------------------- | |
| 168 | 179 | |
| 169 | 180 | /sys/power/disk generally tells the kernel what to do after creating a |
| 170 | 181 | hibernation image. One of the available options is "test_resume" which |
| 171 | 182 | causes the just created image to be used for immediate restoration. Namely, |
| 172 | −after doing: | |
| 183 | +after doing:: | |
| 173 | 184 | |
| 174 | −# echo test_resume > /sys/power/disk | |
| 175 | −# echo disk > /sys/power/state | |
| 185 | + # echo test_resume > /sys/power/disk | |
| 186 | + # echo disk > /sys/power/state | |
| 176 | 187 | |
| 177 | 188 | a hibernation image will be created and a resume from it will be triggered |
| 178 | 189 | 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 · 11 unmodified lines | ||
| 190 | 201 | kernels. |
| 191 | 202 | |
| 192 | 203 | d) Advanced debugging |
| 204 | +--------------------- | |
| 193 | 205 | |
| 194 | 206 | In case that hibernation does not work on your system even in the minimal |
| 195 | 207 | 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 · 4 unmodified lines | ||
| 200 | 212 | information about the reasons of the suspend (resume) failure. Alternatively, |
| 201 | 213 | it may be possible to use a FireWire port for debugging with firescope |
| 202 | 214 | (http://v3.sk/~lkundrak/firescope/). On x86 it is also possible to |
| 203 | −use the PM_TRACE mechanism documented in Documentation/power/s2ram.txt . | |
| 215 | +use the PM_TRACE mechanism documented in Documentation/power/s2ram.rst . | |
| 204 | 216 | |
| 205 | 217 | 2. Testing suspend to RAM (STR) |
| 218 | +=============================== | |
| 206 | 219 | |
| 207 | 220 | To verify that the STR works, it is generally more convenient to use the s2ram |
| 208 | 221 | 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 · 21 unmodified lines | ||
| 230 | 243 | you run s2ram), and please report the problems with them. |
| 231 | 244 | |
| 232 | 245 | There is a debugfs entry which shows the suspend to RAM statistics. Here is an |
| 233 | −example of its output. | |
| 246 | +example of its output:: | |
| 247 | + | |
| 234 | 248 | # mount -t debugfs none /sys/kernel/debug |
| 235 | 249 | # cat /sys/kernel/debug/suspend_stats |
| 236 | 250 | success: 20 |
| @@ -248,6 +262,7 @@ example of its output. · 11 unmodified lines | ||
| 248 | 262 | -16 |
| 249 | 263 | last_failed_step: suspend |
| 250 | 264 | suspend |
| 265 | + | |
| 251 | 266 | Field success means the success number of suspend to RAM, and field fail means |
| 252 | 267 | the failure number. Others are the failure number of different steps of suspend |
| 253 | 268 | to RAM. suspend_stats just lists the last 2 failed devices, error number and |
| @@ -1,4 +1,7 @@ | ||
| 1 | +=============== | |
| 1 | 2 | Charger Manager |
| 3 | +=============== | |
| 4 | + | |
| 2 | 5 | (C) 2011 MyungJoo Ham <myungjoo.ham@samsung.com>, GPL |
| 3 | 6 | |
| 4 | 7 | Charger Manager provides in-kernel battery charger management that |
| @@ -55,41 +58,39 @@ Charger Manager supports the following: · 50 unmodified lines | ||
| 55 | 58 | notification to users with UEVENT. |
| 56 | 59 | |
| 57 | 60 | 2. Global Charger-Manager Data related with suspend_again |
| 58 | −======================================================== | |
| 61 | +========================================================= | |
| 59 | 62 | In order to setup Charger Manager with suspend-again feature |
| 60 | 63 | (in-suspend monitoring), the user should provide charger_global_desc |
| 61 | −with setup_charger_manager(struct charger_global_desc *). | |
| 64 | +with setup_charger_manager(`struct charger_global_desc *`). | |
| 62 | 65 | This charger_global_desc data for in-suspend monitoring is global |
| 63 | 66 | as the name suggests. Thus, the user needs to provide only once even |
| 64 | 67 | if there are multiple batteries. If there are multiple batteries, the |
| 65 | 68 | multiple instances of Charger Manager share the same charger_global_desc |
| 66 | 69 | and it will manage in-suspend monitoring for all instances of Charger Manager. |
| 67 | 70 | |
| 68 | −The user needs to provide all the three entries properly in order to activate | |
| 69 | −in-suspend monitoring: | |
| 70 | − | |
| 71 | −struct charger_global_desc { | |
| 71 | +The user needs to provide all the three entries to `struct charger_global_desc` | |
| 72 | +properly in order to activate in-suspend monitoring: | |
| 72 | 73 | |
| 73 | −char *rtc_name; | |
| 74 | − : The name of rtc (e.g., "rtc0") used to wakeup the system from | |
| 74 | +`char *rtc_name;` | |
| 75 | + The name of rtc (e.g., "rtc0") used to wakeup the system from | |
| 75 | 76 | suspend for Charger Manager. The alarm interrupt (AIE) of the rtc |
| 76 | 77 | should be able to wake up the system from suspend. Charger Manager |
| 77 | 78 | saves and restores the alarm value and use the previously-defined |
| 78 | 79 | alarm if it is going to go off earlier than Charger Manager so that |
| 79 | 80 | Charger Manager does not interfere with previously-defined alarms. |
| 80 | 81 | |
| 81 | −bool (*rtc_only_wakeup)(void); | |
| 82 | − : This callback should let CM know whether | |
| 82 | +`bool (*rtc_only_wakeup)(void);` | |
| 83 | + This callback should let CM know whether | |
| 83 | 84 | the wakeup-from-suspend is caused only by the alarm of "rtc" in the |
| 84 | 85 | same struct. If there is any other wakeup source triggered the |
| 85 | 86 | wakeup, it should return false. If the "rtc" is the only wakeup |
| 86 | 87 | reason, it should return true. |
| 87 | 88 | |
| 88 | −bool assume_timer_stops_in_suspend; | |
| 89 | − : if true, Charger Manager assumes that | |
| 89 | +`bool assume_timer_stops_in_suspend;` | |
| 90 | + if true, Charger Manager assumes that | |
| 90 | 91 | the timer (CM uses jiffies as timer) stops during suspend. Then, CM |
| 91 | 92 | assumes that the suspend-duration is same as the alarm length. |
| 92 | −}; | |
| 93 | + | |
| 93 | 94 | |
| 94 | 95 | 3. How to setup suspend_again |
| 95 | 96 | ============================= |
| @@ -109,26 +110,28 @@ if the system was woken up by Charger Manager and the polling · 13 unmodified lines | ||
| 109 | 110 | ============================================= |
| 110 | 111 | For each battery charged independently from other batteries (if a series of |
| 111 | 112 | batteries are charged by a single charger, they are counted as one independent |
| 112 | −battery), an instance of Charger Manager is attached to it. | |
| 113 | +battery), an instance of Charger Manager is attached to it. The following | |
| 113 | 114 | |
| 114 | −struct charger_desc { | |
| 115 | +struct charger_desc elements: | |
| 115 | 116 | |
| 116 | −char *psy_name; | |
| 117 | − : The power-supply-class name of the battery. Default is | |
| 117 | +`char *psy_name;` | |
| 118 | + The power-supply-class name of the battery. Default is | |
| 118 | 119 | "battery" if psy_name is NULL. Users can access the psy entries |
| 119 | 120 | at "/sys/class/power_supply/[psy_name]/". |
| 120 | 121 | |
| 121 | −enum polling_modes polling_mode; | |
| 122 | − : CM_POLL_DISABLE: do not poll this battery. | |
| 123 | − CM_POLL_ALWAYS: always poll this battery. | |
| 124 | − CM_POLL_EXTERNAL_POWER_ONLY: poll this battery if and only if | |
| 125 | − an external power source is attached. | |
| 126 | − CM_POLL_CHARGING_ONLY: poll this battery if and only if the | |
| 127 | − battery is being charged. | |
| 128 | − | |
| 129 | −unsigned int fullbatt_vchkdrop_ms; | |
| 130 | −unsigned int fullbatt_vchkdrop_uV; | |
| 131 | − : If both have non-zero values, Charger Manager will check the | |
| 122 | +`enum polling_modes polling_mode;` | |
| 123 | + CM_POLL_DISABLE: | |
| 124 | + do not poll this battery. | |
| 125 | + CM_POLL_ALWAYS: | |
| 126 | + always poll this battery. | |
| 127 | + CM_POLL_EXTERNAL_POWER_ONLY: | |
| 128 | + poll this battery if and only if an external power | |
| 129 | + source is attached. | |
| 130 | + CM_POLL_CHARGING_ONLY: | |
| 131 | + poll this battery if and only if the battery is being charged. | |
| 132 | + | |
| 133 | +`unsigned int fullbatt_vchkdrop_ms; / unsigned int fullbatt_vchkdrop_uV;` | |
| 134 | + If both have non-zero values, Charger Manager will check the | |
| 132 | 135 | battery voltage drop fullbatt_vchkdrop_ms after the battery is fully |
| 133 | 136 | charged. If the voltage drop is over fullbatt_vchkdrop_uV, Charger |
| 134 | 137 | Manager will try to recharge the battery by disabling and enabling |
| @@ -136,50 +139,52 @@ unsigned int fullbatt_vchkdrop_uV; · 1 unmodified line | ||
| 136 | 139 | condition) is needed to be implemented with hardware interrupts from |
| 137 | 140 | fuel gauges or charger devices/chips. |
| 138 | 141 | |
| 139 | −unsigned int fullbatt_uV; | |
| 140 | − : If specified with a non-zero value, Charger Manager assumes | |
| 142 | +`unsigned int fullbatt_uV;` | |
| 143 | + If specified with a non-zero value, Charger Manager assumes | |
| 141 | 144 | that the battery is full (capacity = 100) if the battery is not being |
| 142 | 145 | charged and the battery voltage is equal to or greater than |
| 143 | 146 | fullbatt_uV. |
| 144 | 147 | |
| 145 | −unsigned int polling_interval_ms; | |
| 146 | − : Required polling interval in ms. Charger Manager will poll | |
| 148 | +`unsigned int polling_interval_ms;` | |
| 149 | + Required polling interval in ms. Charger Manager will poll | |
| 147 | 150 | this battery every polling_interval_ms or more frequently. |
| 148 | 151 | |
| 149 | −enum data_source battery_present; | |
| 150 | − : CM_BATTERY_PRESENT: assume that the battery exists. | |
| 151 | − CM_NO_BATTERY: assume that the battery does not exists. | |
| 152 | − CM_FUEL_GAUGE: get battery presence information from fuel gauge. | |
| 153 | − CM_CHARGER_STAT: get battery presence from chargers. | |
| 154 | − | |
| 155 | −char **psy_charger_stat; | |
| 156 | − : An array ending with NULL that has power-supply-class names of | |
| 152 | +`enum data_source battery_present;` | |
| 153 | + CM_BATTERY_PRESENT: | |
| 154 | + assume that the battery exists. | |
| 155 | + CM_NO_BATTERY: | |
| 156 | + assume that the battery does not exists. | |
| 157 | + CM_FUEL_GAUGE: | |
| 158 | + get battery presence information from fuel gauge. | |
| 159 | + CM_CHARGER_STAT: | |
| 160 | + get battery presence from chargers. | |
| 161 | + | |
| 162 | +`char **psy_charger_stat;` | |
| 163 | + An array ending with NULL that has power-supply-class names of | |
| 157 | 164 | chargers. Each power-supply-class should provide "PRESENT" (if |
| 158 | 165 | battery_present is "CM_CHARGER_STAT"), "ONLINE" (shows whether an |
| 159 | 166 | external power source is attached or not), and "STATUS" (shows whether |
| 160 | 167 | the battery is {"FULL" or not FULL} or {"FULL", "Charging", |
| 161 | 168 | "Discharging", "NotCharging"}). |
| 162 | 169 | |
| 163 | −int num_charger_regulators; | |
| 164 | −struct regulator_bulk_data *charger_regulators; | |
| 165 | − : Regulators representing the chargers in the form for | |
| 170 | +`int num_charger_regulators; / struct regulator_bulk_data *charger_regulators;` | |
| 171 | + Regulators representing the chargers in the form for | |
| 166 | 172 | regulator framework's bulk functions. |
| 167 | 173 | |
| 168 | −char *psy_fuel_gauge; | |
| 169 | − : Power-supply-class name of the fuel gauge. | |
| 174 | +`char *psy_fuel_gauge;` | |
| 175 | + Power-supply-class name of the fuel gauge. | |
| 170 | 176 | |
| 171 | −int (*temperature_out_of_range)(int *mC); | |
| 172 | −bool measure_battery_temp; | |
| 173 | − : This callback returns 0 if the temperature is safe for charging, | |
| 177 | +`int (*temperature_out_of_range)(int *mC); / bool measure_battery_temp;` | |
| 178 | + This callback returns 0 if the temperature is safe for charging, | |
| 174 | 179 | a positive number if it is too hot to charge, and a negative number |
| 175 | 180 | if it is too cold to charge. With the variable mC, the callback returns |
| 176 | 181 | the temperature in 1/1000 of centigrade. |
| 177 | 182 | The source of temperature can be battery or ambient one according to |
| 178 | 183 | the value of measure_battery_temp. |
| 179 | −}; | |
| 184 | + | |
| 180 | 185 | |
| 181 | 186 | 5. Notify Charger-Manager of charger events: cm_notify_event() |
| 182 | −========================================================= | |
| 187 | +============================================================== | |
| 183 | 188 | If there is an charger event is required to notify |
| 184 | 189 | Charger Manager, a charger device driver that triggers the event can call |
| 185 | 190 | cm_notify_event(psy, type, msg) to notify the corresponding Charger Manager. |
| @@ -1,7 +1,11 @@ | ||
| 1 | +==================================================== | |
| 1 | 2 | Testing suspend and resume support in device drivers |
| 3 | +==================================================== | |
| 4 | + | |
| 2 | 5 | (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL |
| 3 | 6 | |
| 4 | 7 | 1. Preparing the test system |
| 8 | +============================ | |
| 5 | 9 | |
| 6 | 10 | Unfortunately, to effectively test the support for the system-wide suspend and |
| 7 | 11 | resume transitions in a driver, it is necessary to suspend and resume a fully |
| @@ -14,19 +18,20 @@ the machine's BIOS. · 6 unmodified lines | ||
| 14 | 18 | Of course, for this purpose the test system has to be known to suspend and |
| 15 | 19 | resume without the driver being tested. Thus, if possible, you should first |
| 16 | 20 | resolve all suspend/resume-related problems in the test system before you start |
| 17 | −testing the new driver. Please see Documentation/power/basic-pm-debugging.txt | |
| 21 | +testing the new driver. Please see Documentation/power/basic-pm-debugging.rst | |
| 18 | 22 | for more information about the debugging of suspend/resume functionality. |
| 19 | 23 | |
| 20 | 24 | 2. Testing the driver |
| 25 | +===================== | |
| 21 | 26 | |
| 22 | 27 | Once you have resolved the suspend/resume-related problems with your test system |
| 23 | 28 | without the new driver, you are ready to test it: |
| 24 | 29 | |
| 25 | 30 | a) Build the driver as a module, load it and try the test modes of hibernation |
| 26 | − (see: Documentation/power/basic-pm-debugging.txt, 1). | |
| 31 | + (see: Documentation/power/basic-pm-debugging.rst, 1). | |
| 27 | 32 | |
| 28 | 33 | b) Load the driver and attempt to hibernate in the "reboot", "shutdown" and |
| 29 | − "platform" modes (see: Documentation/power/basic-pm-debugging.txt, 1). | |
| 34 | + "platform" modes (see: Documentation/power/basic-pm-debugging.rst, 1). | |
| 30 | 35 | |
| 31 | 36 | c) Compile the driver directly into the kernel and try the test modes of |
| 32 | 37 | hibernation. |
| @@ -34,12 +39,12 @@ c) Compile the driver directly into the kernel and try the test modes of · 1 unmodified line | ||
| 34 | 39 | d) Attempt to hibernate with the driver compiled directly into the kernel |
| 35 | 40 | in the "reboot", "shutdown" and "platform" modes. |
| 36 | 41 | |
| 37 | −e) Try the test modes of suspend (see: Documentation/power/basic-pm-debugging.txt, | |
| 42 | +e) Try the test modes of suspend (see: Documentation/power/basic-pm-debugging.rst, | |
| 38 | 43 | 2). [As far as the STR tests are concerned, it should not matter whether or |
| 39 | 44 | not the driver is built as a module.] |
| 40 | 45 | |
| 41 | 46 | f) Attempt to suspend to RAM using the s2ram tool with the driver loaded |
| 42 | − (see: Documentation/power/basic-pm-debugging.txt, 2). | |
| 47 | + (see: Documentation/power/basic-pm-debugging.rst, 2). | |
| 43 | 48 | |
| 44 | 49 | Each of the above tests should be repeated several times and the STD tests |
| 45 | 50 | should be mixed with the STR tests. If any of them fails, the driver cannot be |
| @@ -1,6 +1,6 @@ | ||
| 1 | − ==================== | |
| 2 | − Energy Model of CPUs | |
| 3 | − ==================== | |
| 1 | +==================== | |
| 2 | +Energy Model of CPUs | |
| 3 | +==================== | |
| 4 | 4 | |
| 5 | 5 | 1. Overview |
| 6 | 6 | ----------- |
| @@ -20,7 +20,7 @@ kernel, hence enabling to avoid redundant work. · 13 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | The figure below depicts an example of drivers (Arm-specific here, but the |
| 22 | 22 | approach is applicable to any architecture) providing power costs to the EM |
| 23 | −framework, and interested clients reading the data from it. | |
| 23 | +framework, and interested clients reading the data from it:: | |
| 24 | 24 | |
| 25 | 25 | +---------------+ +-----------------+ +---------------+ |
| 26 | 26 | | Thermal (IPA) | | Scheduler (EAS) | | Other | |
| @@ -58,15 +58,17 @@ micro-architectures. · 31 unmodified lines | ||
| 58 | 58 | 2. Core APIs |
| 59 | 59 | ------------ |
| 60 | 60 | |
| 61 | − 2.1 Config options | |
| 61 | +2.1 Config options | |
| 62 | +^^^^^^^^^^^^^^^^^^ | |
| 62 | 63 | |
| 63 | 64 | CONFIG_ENERGY_MODEL must be enabled to use the EM framework. |
| 64 | 65 | |
| 65 | 66 | |
| 66 | − 2.2 Registration of performance domains | |
| 67 | +2.2 Registration of performance domains | |
| 68 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 67 | 69 | |
| 68 | 70 | Drivers are expected to register performance domains into the EM framework by |
| 69 | −calling the following API: | |
| 71 | +calling the following API:: | |
| 70 | 72 | |
| 71 | 73 | int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, |
| 72 | 74 | struct em_data_callback *cb); |
| @@ -80,7 +82,8 @@ callback, and kernel/power/energy_model.c for further documentation on this · 7 unmodified lines | ||
| 80 | 82 | API. |
| 81 | 83 | |
| 82 | 84 | |
| 83 | − 2.3 Accessing performance domains | |
| 85 | +2.3 Accessing performance domains | |
| 86 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 84 | 87 | |
| 85 | 88 | Subsystems interested in the energy model of a CPU can retrieve it using the |
| 86 | 89 | 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. · 12 unmodified lines | ||
| 99 | 102 | This section provides a simple example of a CPUFreq driver registering a |
| 100 | 103 | performance domain in the Energy Model framework using the (fake) 'foo' |
| 101 | 104 | protocol. The driver implements an est_power() function to be provided to the |
| 102 | −EM framework. | |
| 103 | − | |
| 104 | − -> drivers/cpufreq/foo_cpufreq.c | |
| 105 | − | |
| 106 | −01 static int est_power(unsigned long *mW, unsigned long *KHz, int cpu) | |
| 107 | −02 { | |
| 108 | −03 long freq, power; | |
| 109 | −04 | |
| 110 | −05 /* Use the 'foo' protocol to ceil the frequency */ | |
| 111 | −06 freq = foo_get_freq_ceil(cpu, *KHz); | |
| 112 | −07 if (freq < 0); | |
| 113 | −08 return freq; | |
| 114 | −09 | |
| 115 | −10 /* Estimate the power cost for the CPU at the relevant freq. */ | |
| 116 | −11 power = foo_estimate_power(cpu, freq); | |
| 117 | −12 if (power < 0); | |
| 118 | −13 return power; | |
| 119 | −14 | |
| 120 | −15 /* Return the values to the EM framework */ | |
| 121 | −16 *mW = power; | |
| 122 | −17 *KHz = freq; | |
| 123 | −18 | |
| 124 | −19 return 0; | |
| 125 | −20 } | |
| 126 | −21 | |
| 127 | −22 static int foo_cpufreq_init(struct cpufreq_policy *policy) | |
| 128 | −23 { | |
| 129 | −24 struct em_data_callback em_cb = EM_DATA_CB(est_power); | |
| 130 | −25 int nr_opp, ret; | |
| 131 | −26 | |
| 132 | −27 /* Do the actual CPUFreq init work ... */ | |
| 133 | −28 ret = do_foo_cpufreq_init(policy); | |
| 134 | −29 if (ret) | |
| 135 | −30 return ret; | |
| 136 | −31 | |
| 137 | −32 /* Find the number of OPPs for this policy */ | |
| 138 | −33 nr_opp = foo_get_nr_opp(policy); | |
| 139 | −34 | |
| 140 | −35 /* And register the new performance domain */ | |
| 141 | −36 em_register_perf_domain(policy->cpus, nr_opp, &em_cb); | |
| 142 | −37 | |
| 143 | −38 return 0; | |
| 144 | −39 } | |
| 105 | +EM framework:: | |
| 106 | + | |
| 107 | + -> drivers/cpufreq/foo_cpufreq.c | |
| 108 | + | |
| 109 | + 01 static int est_power(unsigned long *mW, unsigned long *KHz, int cpu) | |
| 110 | + 02 { | |
| 111 | + 03 long freq, power; | |
| 112 | + 04 | |
| 113 | + 05 /* Use the 'foo' protocol to ceil the frequency */ | |
| 114 | + 06 freq = foo_get_freq_ceil(cpu, *KHz); | |
| 115 | + 07 if (freq < 0); | |
| 116 | + 08 return freq; | |
| 117 | + 09 | |
| 118 | + 10 /* Estimate the power cost for the CPU at the relevant freq. */ | |
| 119 | + 11 power = foo_estimate_power(cpu, freq); | |
| 120 | + 12 if (power < 0); | |
| 121 | + 13 return power; | |
| 122 | + 14 | |
| 123 | + 15 /* Return the values to the EM framework */ | |
| 124 | + 16 *mW = power; | |
| 125 | + 17 *KHz = freq; | |
| 126 | + 18 | |
| 127 | + 19 return 0; | |
| 128 | + 20 } | |
| 129 | + 21 | |
| 130 | + 22 static int foo_cpufreq_init(struct cpufreq_policy *policy) | |
| 131 | + 23 { | |
| 132 | + 24 struct em_data_callback em_cb = EM_DATA_CB(est_power); | |
| 133 | + 25 int nr_opp, ret; | |
| 134 | + 26 | |
| 135 | + 27 /* Do the actual CPUFreq init work ... */ | |
| 136 | + 28 ret = do_foo_cpufreq_init(policy); | |
| 137 | + 29 if (ret) | |
| 138 | + 30 return ret; | |
| 139 | + 31 | |
| 140 | + 32 /* Find the number of OPPs for this policy */ | |
| 141 | + 33 nr_opp = foo_get_nr_opp(policy); | |
| 142 | + 34 | |
| 143 | + 35 /* And register the new performance domain */ | |
| 144 | + 36 em_register_perf_domain(policy->cpus, nr_opp, &em_cb); | |
| 145 | + 37 | |
| 146 | + 38 return 0; | |
| 147 | + 39 } | |
| @@ -1,13 +1,18 @@ | ||
| 1 | +================= | |
| 1 | 2 | Freezing of tasks |
| 2 | − (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL | |
| 3 | +================= | |
| 4 | + | |
| 5 | +(C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL | |
| 3 | 6 | |
| 4 | 7 | I. What is the freezing of tasks? |
| 8 | +================================= | |
| 5 | 9 | |
| 6 | 10 | The freezing of tasks is a mechanism by which user space processes and some |
| 7 | 11 | kernel threads are controlled during hibernation or system-wide suspend (on some |
| 8 | 12 | architectures). |
| 9 | 13 | |
| 10 | 14 | II. How does it work? |
| 15 | +===================== | |
| 11 | 16 | |
| 12 | 17 | There are three per-task flags used for that, PF_NOFREEZE, PF_FROZEN |
| 13 | 18 | 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 · 27 unmodified lines | ||
| 41 | 46 | wait_event_freezable_timeout() macros (defined in include/linux/freezer.h) |
| 42 | 47 | that combine interruptible sleep with checking if the task is to be frozen and |
| 43 | 48 | calling try_to_freeze(). The main loop of a freezable kernel thread may look |
| 44 | −like the following one: | |
| 49 | +like the following one:: | |
| 45 | 50 | |
| 46 | 51 | set_freezable(); |
| 47 | 52 | do { |
| @@ -65,7 +70,7 @@ order to clear the PF_FROZEN flag for each frozen task. Then, the tasks that · 17 unmodified lines | ||
| 65 | 70 | have been frozen leave __refrigerator() and continue running. |
| 66 | 71 | |
| 67 | 72 | |
| 68 | −Rationale behind the functions dealing with freezing and thawing of tasks: | |
| 73 | +Rationale behind the functions dealing with freezing and thawing of tasks | |
| 69 | 74 | ------------------------------------------------------------------------- |
| 70 | 75 | |
| 71 | 76 | freeze_processes(): |
| @@ -86,6 +91,7 @@ thaw_processes(): · 14 unmodified lines | ||
| 86 | 91 | |
| 87 | 92 | |
| 88 | 93 | III. Which kernel threads are freezable? |
| 94 | +======================================== | |
| 89 | 95 | |
| 90 | 96 | Kernel threads are not freezable by default. However, a kernel thread may clear |
| 91 | 97 | 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 · 1 unmodified line | ||
| 93 | 99 | and must call try_to_freeze() in a suitable place. |
| 94 | 100 | |
| 95 | 101 | IV. Why do we do that? |
| 102 | +====================== | |
| 96 | 103 | |
| 97 | 104 | Generally speaking, there is a couple of reasons to use the freezing of tasks: |
| 98 | 105 | |
| 99 | 106 | 1. The principal reason is to prevent filesystems from being damaged after |
| 100 | −hibernation. At the moment we have no simple means of checkpointing | |
| 101 | −filesystems, so if there are any modifications made to filesystem data and/or | |
| 102 | −metadata on disks, we cannot bring them back to the state from before the | |
| 103 | −modifications. At the same time each hibernation image contains some | |
| 104 | −filesystem-related information that must be consistent with the state of the | |
| 105 | −on-disk data and metadata after the system memory state has been restored from | |
| 106 | −the image (otherwise the filesystems will be damaged in a nasty way, usually | |
| 107 | −making them almost impossible to repair). We therefore freeze tasks that might | |
| 108 | −cause the on-disk filesystems' data and metadata to be modified after the | |
| 109 | −hibernation image has been created and before the system is finally powered off. | |
| 110 | −The majority of these are user space processes, but if any of the kernel threads | |
| 111 | −may cause something like this to happen, they have to be freezable. | |
| 107 | + hibernation. At the moment we have no simple means of checkpointing | |
| 108 | + filesystems, so if there are any modifications made to filesystem data and/or | |
| 109 | + metadata on disks, we cannot bring them back to the state from before the | |
| 110 | + modifications. At the same time each hibernation image contains some | |
| 111 | + filesystem-related information that must be consistent with the state of the | |
| 112 | + on-disk data and metadata after the system memory state has been restored | |
| 113 | + from the image (otherwise the filesystems will be damaged in a nasty way, | |
| 114 | + usually making them almost impossible to repair). We therefore freeze | |
| 115 | + tasks that might cause the on-disk filesystems' data and metadata to be | |
| 116 | + modified after the hibernation image has been created and before the | |
| 117 | + system is finally powered off. The majority of these are user space | |
| 118 | + processes, but if any of the kernel threads may cause something like this | |
| 119 | + to happen, they have to be freezable. | |
| 112 | 120 | |
| 113 | 121 | 2. Next, to create the hibernation image we need to free a sufficient amount of |
| 114 | −memory (approximately 50% of available RAM) and we need to do that before | |
| 115 | −devices are deactivated, because we generally need them for swapping out. Then, | |
| 116 | −after the memory for the image has been freed, we don't want tasks to allocate | |
| 117 | −additional memory and we prevent them from doing that by freezing them earlier. | |
| 118 | −[Of course, this also means that device drivers should not allocate substantial | |
| 119 | −amounts of memory from their .suspend() callbacks before hibernation, but this | |
| 120 | −is a separate issue.] | |
| 122 | + memory (approximately 50% of available RAM) and we need to do that before | |
| 123 | + devices are deactivated, because we generally need them for swapping out. | |
| 124 | + Then, after the memory for the image has been freed, we don't want tasks | |
| 125 | + to allocate additional memory and we prevent them from doing that by | |
| 126 | + freezing them earlier. [Of course, this also means that device drivers | |
| 127 | + should not allocate substantial amounts of memory from their .suspend() | |
| 128 | + callbacks before hibernation, but this is a separate issue.] | |
| 121 | 129 | |
| 122 | 130 | 3. The third reason is to prevent user space processes and some kernel threads |
| 123 | −from interfering with the suspending and resuming of devices. A user space | |
| 124 | −process running on a second CPU while we are suspending devices may, for | |
| 125 | −example, be troublesome and without the freezing of tasks we would need some | |
| 126 | −safeguards against race conditions that might occur in such a case. | |
| 131 | + from interfering with the suspending and resuming of devices. A user space | |
| 132 | + process running on a second CPU while we are suspending devices may, for | |
| 133 | + example, be troublesome and without the freezing of tasks we would need some | |
| 134 | + safeguards against race conditions that might occur in such a case. | |
| 127 | 135 | |
| 128 | 136 | Although Linus Torvalds doesn't like the freezing of tasks, he said this in one |
| 129 | 137 | 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): · 2 unmodified lines | ||
| 132 | 140 | |
| 133 | 141 | Linus: In many ways, 'at all'. |
| 134 | 142 | |
| 135 | −I _do_ realize the IO request queue issues, and that we cannot actually do | |
| 143 | +I **do** realize the IO request queue issues, and that we cannot actually do | |
| 136 | 144 | s2ram with some devices in the middle of a DMA. So we want to be able to |
| 137 | 145 | avoid *that*, there's no question about that. And I suspect that stopping |
| 138 | 146 | 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 · 11 unmodified lines | ||
| 150 | 158 | the device while it's suspended. |
| 151 | 159 | |
| 152 | 160 | 4. Another reason for freezing tasks is to prevent user space processes from |
| 153 | −realizing that hibernation (or suspend) operation takes place. Ideally, user | |
| 154 | −space processes should not notice that such a system-wide operation has occurred | |
| 155 | −and should continue running without any problems after the restore (or resume | |
| 156 | −from suspend). Unfortunately, in the most general case this is quite difficult | |
| 157 | −to achieve without the freezing of tasks. Consider, for example, a process | |
| 158 | −that depends on all CPUs being online while it's running. Since we need to | |
| 159 | −disable nonboot CPUs during the hibernation, if this process is not frozen, it | |
| 160 | −may notice that the number of CPUs has changed and may start to work incorrectly | |
| 161 | −because of that. | |
| 161 | + realizing that hibernation (or suspend) operation takes place. Ideally, user | |
| 162 | + space processes should not notice that such a system-wide operation has | |
| 163 | + occurred and should continue running without any problems after the restore | |
| 164 | + (or resume from suspend). Unfortunately, in the most general case this | |
| 165 | + is quite difficult to achieve without the freezing of tasks. Consider, | |
| 166 | + for example, a process that depends on all CPUs being online while it's | |
| 167 | + running. Since we need to disable nonboot CPUs during the hibernation, | |
| 168 | + if this process is not frozen, it may notice that the number of CPUs has | |
| 169 | + changed and may start to work incorrectly because of that. | |
| 162 | 170 | |
| 163 | 171 | V. Are there any problems related to the freezing of tasks? |
| 172 | +=========================================================== | |
| 164 | 173 | |
| 165 | 174 | Yes, there are. |
| 166 | 175 | |
| @@ -172,11 +181,12 @@ may be undesirable. That's why kernel threads are not freezable by default. · 5 unmodified lines | ||
| 172 | 181 | |
| 173 | 182 | Second, there are the following two problems related to the freezing of user |
| 174 | 183 | space processes: |
| 184 | + | |
| 175 | 185 | 1. Putting processes into an uninterruptible sleep distorts the load average. |
| 176 | 186 | 2. Now that we have FUSE, plus the framework for doing device drivers in |
| 177 | −userspace, it gets even more complicated because some userspace processes are | |
| 178 | −now doing the sorts of things that kernel threads do | |
| 179 | −(https://lists.linux-foundation.org/pipermail/linux-pm/2007-May/012309.html). | |
| 187 | + userspace, it gets even more complicated because some userspace processes are | |
| 188 | + now doing the sorts of things that kernel threads do | |
| 189 | + (https://lists.linux-foundation.org/pipermail/linux-pm/2007-May/012309.html). | |
| 180 | 190 | |
| 181 | 191 | The problem 1. seems to be fixable, although it hasn't been fixed so far. The |
| 182 | 192 | 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 · 18 unmodified lines | ||
| 201 | 211 | Documentation/driver-api/pm/notifiers.rst. |
| 202 | 212 | |
| 203 | 213 | VI. Are there any precautions to be taken to prevent freezing failures? |
| 214 | +======================================================================= | |
| 204 | 215 | |
| 205 | 216 | Yes, there are. |
| 206 | 217 | |
| @@ -226,6 +237,8 @@ So, to summarize, use [un]lock_system_sleep() instead of directly using · 19 unmodified lines | ||
| 226 | 237 | mutex_[un]lock(&system_transition_mutex). That would prevent freezing failures. |
| 227 | 238 | |
| 228 | 239 | V. Miscellaneous |
| 240 | +================ | |
| 241 | + | |
| 229 | 242 | /sys/power/pm_freeze_timeout controls how long it will cost at most to freeze |
| 230 | 243 | all user space processes or all freezable kernel threads, in unit of millisecond. |
| 231 | 244 | The default value is 20000, with range of unsigned integer. |
| @@ -0,0 +1,46 @@ | ||
| 1 | +:orphan: | |
| 2 | + | |
| 3 | +================ | |
| 4 | +Power Management | |
| 5 | +================ | |
| 6 | + | |
| 7 | +.. toctree:: | |
| 8 | + :maxdepth: 1 | |
| 9 | + | |
| 10 | + apm-acpi | |
| 11 | + basic-pm-debugging | |
| 12 | + charger-manager | |
| 13 | + drivers-testing | |
| 14 | + energy-model | |
| 15 | + freezing-of-tasks | |
| 16 | + interface | |
| 17 | + opp | |
| 18 | + pci | |
| 19 | + pm_qos_interface | |
| 20 | + power_supply_class | |
| 21 | + runtime_pm | |
| 22 | + s2ram | |
| 23 | + suspend-and-cpuhotplug | |
| 24 | + suspend-and-interrupts | |
| 25 | + swsusp-and-swap-files | |
| 26 | + swsusp-dmcrypt | |
| 27 | + swsusp | |
| 28 | + video | |
| 29 | + tricks | |
| 30 | + | |
| 31 | + userland-swsusp | |
| 32 | + | |
| 33 | + powercap/powercap | |
| 34 | + | |
| 35 | + regulator/consumer | |
| 36 | + regulator/design | |
| 37 | + regulator/machine | |
| 38 | + regulator/overview | |
| 39 | + regulator/regulator | |
| 40 | + | |
| 41 | +.. only:: subproject and html | |
| 42 | + | |
| 43 | + Indices | |
| 44 | + ======= | |
| 45 | + | |
| 46 | + * :ref:`genindex` | |
| @@ -1,4 +1,6 @@ | ||
| 1 | +=========================================== | |
| 1 | 2 | Power Management Interface for System Sleep |
| 3 | +=========================================== | |
| 2 | 4 | |
| 3 | 5 | Copyright (c) 2016 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| 4 | 6 | |
| @@ -11,10 +13,10 @@ mounted at /sys). · 6 unmodified lines | ||
| 11 | 13 | |
| 12 | 14 | Reading from it returns a list of supported sleep states, encoded as: |
| 13 | 15 | |
| 14 | −'freeze' (Suspend-to-Idle) | |
| 15 | −'standby' (Power-On Suspend) | |
| 16 | −'mem' (Suspend-to-RAM) | |
| 17 | −'disk' (Suspend-to-Disk) | |
| 16 | +- 'freeze' (Suspend-to-Idle) | |
| 17 | +- 'standby' (Power-On Suspend) | |
| 18 | +- 'mem' (Suspend-to-RAM) | |
| 19 | +- 'disk' (Suspend-to-Disk) | |
| 18 | 20 | |
| 19 | 21 | Suspend-to-Idle is always supported. Suspend-to-Disk is always supported |
| 20 | 22 | 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. · 11 unmodified lines | ||
| 32 | 34 | |
| 33 | 35 | Reading from it returns a list of supported options encoded as: |
| 34 | 36 | |
| 35 | −'platform' (put the system into sleep using a platform-provided method) | |
| 36 | −'shutdown' (shut the system down) | |
| 37 | −'reboot' (reboot the system) | |
| 38 | −'suspend' (trigger a Suspend-to-RAM transition) | |
| 39 | −'test_resume' (resume-after-hibernation test mode) | |
| 37 | +- 'platform' (put the system into sleep using a platform-provided method) | |
| 38 | +- 'shutdown' (shut the system down) | |
| 39 | +- 'reboot' (reboot the system) | |
| 40 | +- 'suspend' (trigger a Suspend-to-RAM transition) | |
| 41 | +- 'test_resume' (resume-after-hibernation test mode) | |
| 40 | 42 | |
| 41 | 43 | The currently selected option is printed in square brackets. |
| 42 | 44 | |
| 43 | 45 | The 'platform' option is only available if the platform provides a special |
| 44 | 46 | mechanism to put the system to sleep after creating a hibernation image (ACPI |
| 45 | 47 | does that, for example). The 'suspend' option is available if Suspend-to-RAM |
| 46 | −is supported. Refer to Documentation/power/basic-pm-debugging.txt for the | |
| 48 | +is supported. Refer to Documentation/power/basic-pm-debugging.rst for the | |
| 47 | 49 | description of the 'test_resume' option. |
| 48 | 50 | |
| 49 | 51 | 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 · 21 unmodified lines | ||
| 71 | 73 | event point in turn will be stored in the RTC memory (overwriting the actual |
| 72 | 74 | RTC information), so it will survive a system crash if one occurs right after |
| 73 | 75 | storing it and it can be used later to identify the driver that caused the crash |
| 74 | −to happen (see Documentation/power/s2ram.txt for more information). | |
| 76 | +to happen (see Documentation/power/s2ram.rst for more information). | |
| 75 | 77 | |
| 76 | 78 | Initially it contains '0' which may be changed to '1' by writing a string |
| 77 | 79 | representing a nonzero integer into it. |
| @@ -1,20 +1,23 @@ | ||
| 1 | +========================================== | |
| 1 | 2 | Operating Performance Points (OPP) Library |
| 2 | 3 | ========================================== |
| 3 | 4 | |
| 4 | 5 | (C) 2009-2010 Nishanth Menon <nm@ti.com>, Texas Instruments Incorporated |
| 5 | 6 | |
| 6 | −Contents | |
| 7 | −-------- | |
| 8 | −1. Introduction | |
| 9 | −2. Initial OPP List Registration | |
| 10 | −3. OPP Search Functions | |
| 11 | −4. OPP Availability Control Functions | |
| 12 | −5. OPP Data Retrieval Functions | |
| 13 | −6. Data Structures | |
| 7 | +.. Contents | |
| 8 | + | |
| 9 | + 1. Introduction | |
| 10 | + 2. Initial OPP List Registration | |
| 11 | + 3. OPP Search Functions | |
| 12 | + 4. OPP Availability Control Functions | |
| 13 | + 5. OPP Data Retrieval Functions | |
| 14 | + 6. Data Structures | |
| 14 | 15 | |
| 15 | 16 | 1. Introduction |
| 16 | 17 | =============== |
| 18 | + | |
| 17 | 19 | 1.1 What is an Operating Performance Point (OPP)? |
| 20 | +------------------------------------------------- | |
| 18 | 21 | |
| 19 | 22 | Complex SoCs of today consists of a multiple sub-modules working in conjunction. |
| 20 | 23 | In an operational system executing varied use cases, not all modules in the SoC |
| @@ -28,16 +31,19 @@ the device will support per domain are called Operating Performance Points or · 7 unmodified lines | ||
| 28 | 31 | OPPs. |
| 29 | 32 | |
| 30 | 33 | As an example: |
| 34 | + | |
| 31 | 35 | Let us consider an MPU device which supports the following: |
| 32 | 36 | {300MHz at minimum voltage of 1V}, {800MHz at minimum voltage of 1.2V}, |
| 33 | 37 | {1GHz at minimum voltage of 1.3V} |
| 34 | 38 | |
| 35 | 39 | We can represent these as three OPPs as the following {Hz, uV} tuples: |
| 36 | −{300000000, 1000000} | |
| 37 | −{800000000, 1200000} | |
| 38 | −{1000000000, 1300000} | |
| 40 | + | |
| 41 | +- {300000000, 1000000} | |
| 42 | +- {800000000, 1200000} | |
| 43 | +- {1000000000, 1300000} | |
| 39 | 44 | |
| 40 | 45 | 1.2 Operating Performance Points Library |
| 46 | +---------------------------------------- | |
| 41 | 47 | |
| 42 | 48 | OPP library provides a set of helper functions to organize and query the OPP |
| 43 | 49 | information. The library is located in drivers/base/power/opp.c and the header |
| @@ -46,9 +52,10 @@ CONFIG_PM_OPP from power management menuconfig menu. OPP library depends on · 2 unmodified lines | ||
| 46 | 52 | CONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to |
| 47 | 53 | optionally boot at a certain OPP without needing cpufreq. |
| 48 | 54 | |
| 49 | −Typical usage of the OPP library is as follows: | |
| 50 | −(users) -> registers a set of default OPPs -> (library) | |
| 51 | −SoC framework -> modifies on required cases certain OPPs -> OPP layer | |
| 55 | +Typical usage of the OPP library is as follows:: | |
| 56 | + | |
| 57 | + (users) -> registers a set of default OPPs -> (library) | |
| 58 | + SoC framework -> modifies on required cases certain OPPs -> OPP layer | |
| 52 | 59 | -> queries to search/retrieve information -> |
| 53 | 60 | |
| 54 | 61 | OPP layer expects each domain to be represented by a unique device pointer. SoC |
| @@ -57,8 +64,9 @@ list is expected to be an optimally small number typically around 5 per device. · 2 unmodified lines | ||
| 57 | 64 | This initial list contains a set of OPPs that the framework expects to be safely |
| 58 | 65 | enabled by default in the system. |
| 59 | 66 | |
| 60 | −Note on OPP Availability: | |
| 61 | −------------------------ | |
| 67 | +Note on OPP Availability | |
| 68 | +^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 69 | + | |
| 62 | 70 | As the system proceeds to operate, SoC framework may choose to make certain |
| 63 | 71 | OPPs available or not available on each device based on various external |
| 64 | 72 | factors. Example usage: Thermal management or other exceptional situations where |
| @@ -88,7 +96,8 @@ registering the OPPs is maintained by OPP library throughout the device · 23 unmodified lines | ||
| 88 | 96 | operation. The SoC framework can subsequently control the availability of the |
| 89 | 97 | OPPs dynamically using the dev_pm_opp_enable / disable functions. |
| 90 | 98 | |
| 91 | −dev_pm_opp_add - Add a new OPP for a specific domain represented by the device pointer. | |
| 99 | +dev_pm_opp_add | |
| 100 | + Add a new OPP for a specific domain represented by the device pointer. | |
| 92 | 101 | The OPP is defined using the frequency and voltage. Once added, the OPP |
| 93 | 102 | is assumed to be available and control of it's availability can be done |
| 94 | 103 | with the dev_pm_opp_enable/disable functions. OPP library internally stores |
| @@ -96,9 +105,11 @@ dev_pm_opp_add - Add a new OPP for a specific domain represented by the device p · 1 unmodified line | ||
| 96 | 105 | used by SoC framework to define a optimal list as per the demands of |
| 97 | 106 | SoC usage environment. |
| 98 | 107 | |
| 99 | − WARNING: Do not use this function in interrupt context. | |
| 108 | + WARNING: | |
| 109 | + Do not use this function in interrupt context. | |
| 110 | + | |
| 111 | + Example:: | |
| 100 | 112 | |
| 101 | − Example: | |
| 102 | 113 | soc_pm_init() |
| 103 | 114 | { |
| 104 | 115 | /* Do things */ |
| @@ -125,12 +136,15 @@ Callers of these functions shall call dev_pm_opp_put() after they have used the · 20 unmodified lines | ||
| 125 | 136 | OPP. Otherwise the memory for the OPP will never get freed and result in |
| 126 | 137 | memleak. |
| 127 | 138 | |
| 128 | −dev_pm_opp_find_freq_exact - Search for an OPP based on an *exact* frequency and | |
| 139 | +dev_pm_opp_find_freq_exact | |
| 140 | + Search for an OPP based on an *exact* frequency and | |
| 129 | 141 | availability. This function is especially useful to enable an OPP which |
| 130 | 142 | is not available by default. |
| 131 | 143 | Example: In a case when SoC framework detects a situation where a |
| 132 | 144 | higher frequency could be made available, it can use this function to |
| 133 | − find the OPP prior to call the dev_pm_opp_enable to actually make it available. | |
| 145 | + find the OPP prior to call the dev_pm_opp_enable to actually make | |
| 146 | + it available:: | |
| 147 | + | |
| 134 | 148 | opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); |
| 135 | 149 | dev_pm_opp_put(opp); |
| 136 | 150 | /* dont operate on the pointer.. just do a sanity check.. */ |
| @@ -141,27 +155,34 @@ dev_pm_opp_find_freq_exact - Search for an OPP based on an *exact* frequency and · 4 unmodified lines | ||
| 141 | 155 | dev_pm_opp_enable(dev,1000000000); |
| 142 | 156 | } |
| 143 | 157 | |
| 144 | − NOTE: This is the only search function that operates on OPPs which are | |
| 145 | − not available. | |
| 158 | + NOTE: | |
| 159 | + This is the only search function that operates on OPPs which are | |
| 160 | + not available. | |
| 146 | 161 | |
| 147 | −dev_pm_opp_find_freq_floor - Search for an available OPP which is *at most* the | |
| 162 | +dev_pm_opp_find_freq_floor | |
| 163 | + Search for an available OPP which is *at most* the | |
| 148 | 164 | provided frequency. This function is useful while searching for a lesser |
| 149 | 165 | match OR operating on OPP information in the order of decreasing |
| 150 | 166 | frequency. |
| 151 | − Example: To find the highest opp for a device: | |
| 167 | + Example: To find the highest opp for a device:: | |
| 168 | + | |
| 152 | 169 | freq = ULONG_MAX; |
| 153 | 170 | opp = dev_pm_opp_find_freq_floor(dev, &freq); |
| 154 | 171 | dev_pm_opp_put(opp); |
| 155 | 172 | |
| 156 | −dev_pm_opp_find_freq_ceil - Search for an available OPP which is *at least* the | |
| 173 | +dev_pm_opp_find_freq_ceil | |
| 174 | + Search for an available OPP which is *at least* the | |
| 157 | 175 | provided frequency. This function is useful while searching for a |
| 158 | 176 | higher match OR operating on OPP information in the order of increasing |
| 159 | 177 | frequency. |
| 160 | − Example 1: To find the lowest opp for a device: | |
| 178 | + Example 1: To find the lowest opp for a device:: | |
| 179 | + | |
| 161 | 180 | freq = 0; |
| 162 | 181 | opp = dev_pm_opp_find_freq_ceil(dev, &freq); |
| 163 | 182 | dev_pm_opp_put(opp); |
| 164 | − Example 2: A simplified implementation of a SoC cpufreq_driver->target: | |
| 183 | + | |
| 184 | + Example 2: A simplified implementation of a SoC cpufreq_driver->target:: | |
| 185 | + | |
| 165 | 186 | soc_cpufreq_target(..) |
| 166 | 187 | { |
| 167 | 188 | /* Do stuff like policy checks etc. */ |
| @@ -184,12 +205,15 @@ fine grained dynamic control of which sets of OPPs are operationally available. · 16 unmodified lines | ||
| 184 | 205 | These functions are intended to *temporarily* remove an OPP in conditions such |
| 185 | 206 | as thermal considerations (e.g. don't use OPPx until the temperature drops). |
| 186 | 207 | |
| 187 | −WARNING: Do not use these functions in interrupt context. | |
| 208 | +WARNING: | |
| 209 | + Do not use these functions in interrupt context. | |
| 188 | 210 | |
| 189 | −dev_pm_opp_enable - Make a OPP available for operation. | |
| 211 | +dev_pm_opp_enable | |
| 212 | + Make a OPP available for operation. | |
| 190 | 213 | Example: Lets say that 1GHz OPP is to be made available only if the |
| 191 | 214 | SoC temperature is lower than a certain threshold. The SoC framework |
| 192 | − implementation might choose to do something as follows: | |
| 215 | + implementation might choose to do something as follows:: | |
| 216 | + | |
| 193 | 217 | if (cur_temp < temp_low_thresh) { |
| 194 | 218 | /* Enable 1GHz if it was disabled */ |
| 195 | 219 | opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); |
| @@ -201,10 +225,12 @@ dev_pm_opp_enable - Make a OPP available for operation. · 5 unmodified lines | ||
| 201 | 225 | goto try_something_else; |
| 202 | 226 | } |
| 203 | 227 | |
| 204 | −dev_pm_opp_disable - Make an OPP to be not available for operation | |
| 228 | +dev_pm_opp_disable | |
| 229 | + Make an OPP to be not available for operation | |
| 205 | 230 | Example: Lets say that 1GHz OPP is to be disabled if the temperature |
| 206 | 231 | exceeds a threshold value. The SoC framework implementation might |
| 207 | − choose to do something as follows: | |
| 232 | + choose to do something as follows:: | |
| 233 | + | |
| 208 | 234 | if (cur_temp > temp_high_thresh) { |
| 209 | 235 | /* Disable 1GHz if it was enabled */ |
| 210 | 236 | opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true); |
| @@ -223,11 +249,13 @@ information from the OPP structure is necessary. Once an OPP pointer is · 12 unmodified lines | ||
| 223 | 249 | retrieved using the search functions, the following functions can be used by SoC |
| 224 | 250 | framework to retrieve the information represented inside the OPP layer. |
| 225 | 251 | |
| 226 | −dev_pm_opp_get_voltage - Retrieve the voltage represented by the opp pointer. | |
| 252 | +dev_pm_opp_get_voltage | |
| 253 | + Retrieve the voltage represented by the opp pointer. | |
| 227 | 254 | Example: At a cpufreq transition to a different frequency, SoC |
| 228 | 255 | framework requires to set the voltage represented by the OPP using |
| 229 | 256 | the regulator framework to the Power Management chip providing the |
| 230 | − voltage. | |
| 257 | + voltage:: | |
| 258 | + | |
| 231 | 259 | soc_switch_to_freq_voltage(freq) |
| 232 | 260 | { |
| 233 | 261 | /* do things */ |
| @@ -239,10 +267,12 @@ dev_pm_opp_get_voltage - Retrieve the voltage represented by the opp pointer. · 5 unmodified lines | ||
| 239 | 267 | /* do other things */ |
| 240 | 268 | } |
| 241 | 269 | |
| 242 | −dev_pm_opp_get_freq - Retrieve the freq represented by the opp pointer. | |
| 270 | +dev_pm_opp_get_freq | |
| 271 | + Retrieve the freq represented by the opp pointer. | |
| 243 | 272 | Example: Lets say the SoC framework uses a couple of helper functions |
| 244 | 273 | we could pass opp pointers instead of doing additional parameters to |
| 245 | − handle quiet a bit of data parameters. | |
| 274 | + handle quiet a bit of data parameters:: | |
| 275 | + | |
| 246 | 276 | soc_cpufreq_target(..) |
| 247 | 277 | { |
| 248 | 278 | /* do things.. */ |
| @@ -264,9 +294,11 @@ dev_pm_opp_get_freq - Retrieve the freq represented by the opp pointer. · 15 unmodified lines | ||
| 264 | 294 | /* do things.. */ |
| 265 | 295 | } |
| 266 | 296 | |
| 267 | −dev_pm_opp_get_opp_count - Retrieve the number of available opps for a device | |
| 297 | +dev_pm_opp_get_opp_count | |
| 298 | + Retrieve the number of available opps for a device | |
| 268 | 299 | Example: Lets say a co-processor in the SoC needs to know the available |
| 269 | − frequencies in a table, the main processor can notify as following: | |
| 300 | + frequencies in a table, the main processor can notify as following:: | |
| 301 | + | |
| 270 | 302 | soc_notify_coproc_available_frequencies() |
| 271 | 303 | { |
| 272 | 304 | /* Do things */ |
| @@ -289,54 +321,59 @@ dev_pm_opp_get_opp_count - Retrieve the number of available opps for a device · 16 unmodified lines | ||
| 289 | 321 | ================== |
| 290 | 322 | Typically an SoC contains multiple voltage domains which are variable. Each |
| 291 | 323 | domain is represented by a device pointer. The relationship to OPP can be |
| 292 | −represented as follows: | |
| 293 | −SoC | |
| 294 | − |- device 1 | |
| 295 | − | |- opp 1 (availability, freq, voltage) | |
| 296 | − | |- opp 2 .. | |
| 297 | − ... ... | |
| 298 | − | `- opp n .. | |
| 299 | − |- device 2 | |
| 300 | − ... | |
| 301 | − `- device m | |
| 324 | +represented as follows:: | |
| 325 | + | |
| 326 | + SoC | |
| 327 | + |- device 1 | |
| 328 | + | |- opp 1 (availability, freq, voltage) | |
| 329 | + | |- opp 2 .. | |
| 330 | + ... ... | |
| 331 | + | `- opp n .. | |
| 332 | + |- device 2 | |
| 333 | + ... | |
| 334 | + `- device m | |
| 302 | 335 | |
| 303 | 336 | OPP library maintains a internal list that the SoC framework populates and |
| 304 | 337 | accessed by various functions as described above. However, the structures |
| 305 | 338 | representing the actual OPPs and domains are internal to the OPP library itself |
| 306 | 339 | to allow for suitable abstraction reusable across systems. |
| 307 | 340 | |
| 308 | −struct dev_pm_opp - The internal data structure of OPP library which is used to | |
| 341 | +struct dev_pm_opp | |
| 342 | + The internal data structure of OPP library which is used to | |
| 309 | 343 | represent an OPP. In addition to the freq, voltage, availability |
| 310 | 344 | information, it also contains internal book keeping information required |
| 311 | 345 | for the OPP library to operate on. Pointer to this structure is |
| 312 | 346 | provided back to the users such as SoC framework to be used as a |
| 313 | 347 | identifier for OPP in the interactions with OPP layer. |
| 314 | 348 | |
| 315 | − WARNING: The struct dev_pm_opp pointer should not be parsed or modified by the | |
| 316 | − users. The defaults of for an instance is populated by dev_pm_opp_add, but the | |
| 317 | − availability of the OPP can be modified by dev_pm_opp_enable/disable functions. | |
| 349 | + WARNING: | |
| 350 | + The struct dev_pm_opp pointer should not be parsed or modified by the | |
| 351 | + users. The defaults of for an instance is populated by | |
| 352 | + dev_pm_opp_add, but the availability of the OPP can be modified | |
| 353 | + by dev_pm_opp_enable/disable functions. | |
| 318 | 354 | |
| 319 | −struct device - This is used to identify a domain to the OPP layer. The | |
| 355 | +struct device | |
| 356 | + This is used to identify a domain to the OPP layer. The | |
| 320 | 357 | nature of the device and it's implementation is left to the user of |
| 321 | 358 | OPP library such as the SoC framework. |
| 322 | 359 | |
| 323 | 360 | Overall, in a simplistic view, the data structure operations is represented as |
| 324 | −following: | |
| 361 | +following:: | |
| 325 | 362 | |
| 326 | −Initialization / modification: | |
| 327 | − +-----+ /- dev_pm_opp_enable | |
| 328 | −dev_pm_opp_add --> | opp | <------- | |
| 329 | − | +-----+ \- dev_pm_opp_disable | |
| 330 | − \-------> domain_info(device) | |
| 363 | + Initialization / modification: | |
| 364 | + +-----+ /- dev_pm_opp_enable | |
| 365 | + dev_pm_opp_add --> | opp | <------- | |
| 366 | + | +-----+ \- dev_pm_opp_disable | |
| 367 | + \-------> domain_info(device) | |
| 331 | 368 | |
| 332 | −Search functions: | |
| 333 | − /-- dev_pm_opp_find_freq_ceil ---\ +-----+ | |
| 334 | −domain_info<---- dev_pm_opp_find_freq_exact -----> | opp | | |
| 335 | − \-- dev_pm_opp_find_freq_floor ---/ +-----+ | |
| 369 | + Search functions: | |
| 370 | + /-- dev_pm_opp_find_freq_ceil ---\ +-----+ | |
| 371 | + domain_info<---- dev_pm_opp_find_freq_exact -----> | opp | | |
| 372 | + \-- dev_pm_opp_find_freq_floor ---/ +-----+ | |
| 336 | 373 | |
| 337 | −Retrieval functions: | |
| 338 | −+-----+ /- dev_pm_opp_get_voltage | |
| 339 | −| opp | <--- | |
| 340 | −+-----+ \- dev_pm_opp_get_freq | |
| 374 | + Retrieval functions: | |
| 375 | + +-----+ /- dev_pm_opp_get_voltage | |
| 376 | + | opp | <--- | |
| 377 | + +-----+ \- dev_pm_opp_get_freq | |
| 341 | 378 | |
| 342 | −domain_info <- dev_pm_opp_get_opp_count | |
| 379 | + domain_info <- dev_pm_opp_get_opp_count | |
| @@ -1,4 +1,6 @@ | ||
| 1 | +==================== | |
| 1 | 2 | PCI Power Management |
| 3 | +==================== | |
| 2 | 4 | |
| 3 | 5 | Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. |
| 4 | 6 | |
| @@ -9,14 +11,14 @@ management. Based on previous work by Patrick Mochel <mochel@transmeta.com> · 4 unmodified lines | ||
| 9 | 11 | This document only covers the aspects of power management specific to PCI |
| 10 | 12 | devices. For general description of the kernel's interfaces related to device |
| 11 | 13 | power management refer to Documentation/driver-api/pm/devices.rst and |
| 12 | −Documentation/power/runtime_pm.txt. | |
| 14 | +Documentation/power/runtime_pm.rst. | |
| 13 | 15 | |
| 14 | −--------------------------------------------------------------------------- | |
| 16 | +.. contents: | |
| 15 | 17 | |
| 16 | −1. Hardware and Platform Support for PCI Power Management | |
| 17 | −2. PCI Subsystem and Device Power Management | |
| 18 | −3. PCI Device Drivers and Power Management | |
| 19 | −4. Resources | |
| 18 | + 1. Hardware and Platform Support for PCI Power Management | |
| 19 | + 2. PCI Subsystem and Device Power Management | |
| 20 | + 3. PCI Device Drivers and Power Management | |
| 21 | + 4. Resources | |
| 20 | 22 | |
| 21 | 23 | |
| 22 | 24 | 1. Hardware and Platform Support for PCI Power Management |
| @@ -24,6 +26,7 @@ Documentation/power/runtime_pm.txt. · 1 unmodified line | ||
| 24 | 26 | |
| 25 | 27 | 1.1. Native and Platform-Based Power Management |
| 26 | 28 | ----------------------------------------------- |
| 29 | + | |
| 27 | 30 | In general, power management is a feature allowing one to save energy by putting |
| 28 | 31 | devices into states in which they draw less power (low-power states) at the |
| 29 | 32 | price of reduced functionality or performance. |
| @@ -67,6 +70,7 @@ mechanisms have to be used simultaneously to obtain the desired result. · 37 unmodified lines | ||
| 67 | 70 | |
| 68 | 71 | 1.2. Native PCI Power Management |
| 69 | 72 | -------------------------------- |
| 73 | + | |
| 70 | 74 | The PCI Bus Power Management Interface Specification (PCI PM Spec) was |
| 71 | 75 | introduced between the PCI 2.1 and PCI 2.2 Specifications. It defined a |
| 72 | 76 | standard interface for performing various operations related to power |
| @@ -134,6 +138,7 @@ sufficiently active to generate a wakeup signal. · 61 unmodified lines | ||
| 134 | 138 | |
| 135 | 139 | 1.3. ACPI Device Power Management |
| 136 | 140 | --------------------------------- |
| 141 | + | |
| 137 | 142 | The platform firmware support for the power management of PCI devices is |
| 138 | 143 | system-specific. However, if the system in question is compliant with the |
| 139 | 144 | Advanced Configuration and Power Interface (ACPI) Specification, like the |
| @@ -194,6 +199,7 @@ enabled for the device to be able to generate wakeup signals. · 54 unmodified lines | ||
| 194 | 199 | |
| 195 | 200 | 1.4. Wakeup Signaling |
| 196 | 201 | --------------------- |
| 202 | + | |
| 197 | 203 | Wakeup signals generated by PCI devices, either as native PCI PMEs, or as |
| 198 | 204 | a result of the execution of the _DSW (or _PSW) ACPI control method before |
| 199 | 205 | putting the device into a low-power state, have to be caught and handled as |
| @@ -265,14 +271,15 @@ the native PCI Express PME signaling cannot be used by the kernel in that case. · 65 unmodified lines | ||
| 265 | 271 | |
| 266 | 272 | 2.1. Device Power Management Callbacks |
| 267 | 273 | -------------------------------------- |
| 274 | + | |
| 268 | 275 | The PCI Subsystem participates in the power management of PCI devices in a |
| 269 | 276 | number of ways. First of all, it provides an intermediate code layer between |
| 270 | 277 | the device power management core (PM core) and PCI device drivers. |
| 271 | 278 | Specifically, the pm field of the PCI subsystem's struct bus_type object, |
| 272 | 279 | pci_bus_type, points to a struct dev_pm_ops object, pci_dev_pm_ops, containing |
| 273 | −pointers to several device power management callbacks: | |
| 280 | +pointers to several device power management callbacks:: | |
| 274 | 281 | |
| 275 | −const struct dev_pm_ops pci_dev_pm_ops = { | |
| 282 | + const struct dev_pm_ops pci_dev_pm_ops = { | |
| 276 | 283 | .prepare = pci_pm_prepare, |
| 277 | 284 | .complete = pci_pm_complete, |
| 278 | 285 | .suspend = pci_pm_suspend, |
| @@ -290,7 +297,7 @@ const struct dev_pm_ops pci_dev_pm_ops = { · 11 unmodified lines | ||
| 290 | 297 | .runtime_suspend = pci_pm_runtime_suspend, |
| 291 | 298 | .runtime_resume = pci_pm_runtime_resume, |
| 292 | 299 | .runtime_idle = pci_pm_runtime_idle, |
| 293 | −}; | |
| 300 | + }; | |
| 294 | 301 | |
| 295 | 302 | These callbacks are executed by the PM core in various situations related to |
| 296 | 303 | device power management and they, in turn, execute power management callbacks |
| @@ -299,9 +306,9 @@ involving some standard configuration registers of PCI devices that device · 2 unmodified lines | ||
| 299 | 306 | drivers need not know or care about. |
| 300 | 307 | |
| 301 | 308 | The structure representing a PCI device, struct pci_dev, contains several fields |
| 302 | −that these callbacks operate on: | |
| 309 | +that these callbacks operate on:: | |
| 303 | 310 | |
| 304 | −struct pci_dev { | |
| 311 | + struct pci_dev { | |
| 305 | 312 | ... |
| 306 | 313 | pci_power_t current_state; /* Current operating state. */ |
| 307 | 314 | int pm_cap; /* PM capability offset in the |
| @@ -315,13 +322,14 @@ struct pci_dev { · 7 unmodified lines | ||
| 315 | 322 | unsigned int wakeup_prepared:1; /* Device prepared for wake up */ |
| 316 | 323 | unsigned int d3_delay; /* D3->D0 transition time in ms */ |
| 317 | 324 | ... |
| 318 | −}; | |
| 325 | + }; | |
| 319 | 326 | |
| 320 | 327 | They also indirectly use some fields of the struct device that is embedded in |
| 321 | 328 | struct pci_dev. |
| 322 | 329 | |
| 323 | 330 | 2.2. Device Initialization |
| 324 | 331 | -------------------------- |
| 332 | + | |
| 325 | 333 | The PCI subsystem's first task related to device power management is to |
| 326 | 334 | prepare the device for power management and initialize the fields of struct |
| 327 | 335 | pci_dev used for this purpose. This happens in two functions defined in |
| @@ -348,10 +356,11 @@ during system-wide transitions to a sleep state and back to the working state. · 20 unmodified lines | ||
| 348 | 356 | |
| 349 | 357 | 2.3. Runtime Device Power Management |
| 350 | 358 | ------------------------------------ |
| 359 | + | |
| 351 | 360 | The PCI subsystem plays a vital role in the runtime power management of PCI |
| 352 | 361 | devices. For this purpose it uses the general runtime power management |
| 353 | −(runtime PM) framework described in Documentation/power/runtime_pm.txt. | |
| 354 | −Namely, it provides subsystem-level callbacks: | |
| 362 | +(runtime PM) framework described in Documentation/power/runtime_pm.rst. | |
| 363 | +Namely, it provides subsystem-level callbacks:: | |
| 355 | 364 | |
| 356 | 365 | pci_pm_runtime_suspend() |
| 357 | 366 | pci_pm_runtime_resume() |
| @@ -425,13 +434,14 @@ to the given subsystem before the next phase begins. These phases always run · 67 unmodified lines | ||
| 425 | 434 | after tasks have been frozen. |
| 426 | 435 | |
| 427 | 436 | 2.4.1. System Suspend |
| 437 | +^^^^^^^^^^^^^^^^^^^^^ | |
| 428 | 438 | |
| 429 | 439 | When the system is going into a sleep state in which the contents of memory will |
| 430 | 440 | be preserved, such as one of the ACPI sleep states S1-S3, the phases are: |
| 431 | 441 | |
| 432 | 442 | prepare, suspend, suspend_noirq. |
| 433 | 443 | |
| 434 | −The following PCI bus type's callbacks, respectively, are used in these phases: | |
| 444 | +The following PCI bus type's callbacks, respectively, are used in these phases:: | |
| 435 | 445 | |
| 436 | 446 | pci_pm_prepare() |
| 437 | 447 | pci_pm_suspend() |
| @@ -492,6 +502,7 @@ this purpose). PCI device drivers are not encouraged to do that, but in some · 54 unmodified lines | ||
| 492 | 502 | rare cases doing that in the driver may be the optimum approach. |
| 493 | 503 | |
| 494 | 504 | 2.4.2. System Resume |
| 505 | +^^^^^^^^^^^^^^^^^^^^ | |
| 495 | 506 | |
| 496 | 507 | When the system is undergoing a transition from a sleep state in which the |
| 497 | 508 | contents of memory have been preserved, such as one of the ACPI sleep states |
| @@ -500,7 +511,7 @@ S1-S3, into the working state (ACPI S0), the phases are: · 2 unmodified lines | ||
| 500 | 511 | resume_noirq, resume, complete. |
| 501 | 512 | |
| 502 | 513 | The following PCI bus type's callbacks, respectively, are executed in these |
| 503 | −phases: | |
| 514 | +phases:: | |
| 504 | 515 | |
| 505 | 516 | pci_pm_resume_noirq() |
| 506 | 517 | pci_pm_resume() |
| @@ -539,6 +550,7 @@ The pci_pm_complete() routine only executes the device driver's pm->complete() · 32 unmodified lines | ||
| 539 | 550 | callback, if defined. |
| 540 | 551 | |
| 541 | 552 | 2.4.3. System Hibernation |
| 553 | +^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 542 | 554 | |
| 543 | 555 | System hibernation is more complicated than system suspend, because it requires |
| 544 | 556 | a system image to be created and written into a persistent storage medium. The |
| @@ -551,7 +563,7 @@ to be free) in the following three phases: · 6 unmodified lines | ||
| 551 | 563 | |
| 552 | 564 | prepare, freeze, freeze_noirq |
| 553 | 565 | |
| 554 | −that correspond to the PCI bus type's callbacks: | |
| 566 | +that correspond to the PCI bus type's callbacks:: | |
| 555 | 567 | |
| 556 | 568 | pci_pm_prepare() |
| 557 | 569 | pci_pm_freeze() |
| @@ -580,7 +592,7 @@ back to the fully functional state and this is done in the following phases: · 22 unmodified lines | ||
| 580 | 592 | |
| 581 | 593 | thaw_noirq, thaw, complete |
| 582 | 594 | |
| 583 | −using the following PCI bus type's callbacks: | |
| 595 | +using the following PCI bus type's callbacks:: | |
| 584 | 596 | |
| 585 | 597 | pci_pm_thaw_noirq() |
| 586 | 598 | pci_pm_thaw() |
| @@ -608,7 +620,7 @@ three phases: · 21 unmodified lines | ||
| 608 | 620 | |
| 609 | 621 | where the prepare phase is exactly the same as for system suspend. The other |
| 610 | 622 | two phases are analogous to the suspend and suspend_noirq phases, respectively. |
| 611 | −The PCI subsystem-level callbacks they correspond to | |
| 623 | +The PCI subsystem-level callbacks they correspond to:: | |
| 612 | 624 | |
| 613 | 625 | pci_pm_poweroff() |
| 614 | 626 | pci_pm_poweroff_noirq() |
| @@ -618,6 +630,7 @@ although they don't attempt to save the device's standard configuration · 3 unmodified lines | ||
| 618 | 630 | registers. |
| 619 | 631 | |
| 620 | 632 | 2.4.4. System Restore |
| 633 | +^^^^^^^^^^^^^^^^^^^^^ | |
| 621 | 634 | |
| 622 | 635 | System restore requires a hibernation image to be loaded into memory and the |
| 623 | 636 | pre-hibernation memory contents to be restored before the pre-hibernation system |
| @@ -653,7 +666,7 @@ phases: · 29 unmodified lines | ||
| 653 | 666 | |
| 654 | 667 | The first two of these are analogous to the resume_noirq and resume phases |
| 655 | 668 | described above, respectively, and correspond to the following PCI subsystem |
| 656 | −callbacks: | |
| 669 | +callbacks:: | |
| 657 | 670 | |
| 658 | 671 | pci_pm_restore_noirq() |
| 659 | 672 | pci_pm_restore() |
| @@ -671,6 +684,7 @@ resume. · 11 unmodified lines | ||
| 671 | 684 | |
| 672 | 685 | 3.1. Power Management Callbacks |
| 673 | 686 | ------------------------------- |
| 687 | + | |
| 674 | 688 | PCI device drivers participate in power management by providing callbacks to be |
| 675 | 689 | executed by the PCI subsystem's power management routines described above and by |
| 676 | 690 | controlling the runtime power management of their devices. |
| @@ -698,6 +712,7 @@ defined, though, they are expected to behave as described in the following · 21 unmodified lines | ||
| 698 | 712 | subsections. |
| 699 | 713 | |
| 700 | 714 | 3.1.1. prepare() |
| 715 | +^^^^^^^^^^^^^^^^ | |
| 701 | 716 | |
| 702 | 717 | The prepare() callback is executed during system suspend, during hibernation |
| 703 | 718 | (when a hibernation image is about to be created), during power-off after |
| @@ -716,6 +731,7 @@ preallocated earlier, for example in a suspend/hibernate notifier as described · 12 unmodified lines | ||
| 716 | 731 | in Documentation/driver-api/pm/notifiers.rst). |
| 717 | 732 | |
| 718 | 733 | 3.1.2. suspend() |
| 734 | +^^^^^^^^^^^^^^^^ | |
| 719 | 735 | |
| 720 | 736 | The suspend() callback is only executed during system suspend, after prepare() |
| 721 | 737 | callbacks have been executed for all devices in the system. |
| @@ -742,6 +758,7 @@ operations relying on the driver's ability to handle interrupts should be · 20 unmodified lines | ||
| 742 | 758 | carried out in this callback. |
| 743 | 759 | |
| 744 | 760 | 3.1.3. suspend_noirq() |
| 761 | +^^^^^^^^^^^^^^^^^^^^^^ | |
| 745 | 762 | |
| 746 | 763 | The suspend_noirq() callback is only executed during system suspend, after |
| 747 | 764 | suspend() callbacks have been executed for all devices in the system and |
| @@ -753,6 +770,7 @@ suspend_noirq() can carry out operations that would cause race conditions to · 5 unmodified lines | ||
| 753 | 770 | arise if they were performed in suspend(). |
| 754 | 771 | |
| 755 | 772 | 3.1.4. freeze() |
| 773 | +^^^^^^^^^^^^^^^ | |
| 756 | 774 | |
| 757 | 775 | The freeze() callback is hibernation-specific and is executed in two situations, |
| 758 | 776 | during hibernation, after prepare() callbacks have been executed for all devices |
| @@ -770,6 +788,7 @@ or put it into a low-power state. Still, either it or freeze_noirq() should · 11 unmodified lines | ||
| 770 | 788 | save the device's standard configuration registers using pci_save_state(). |
| 771 | 789 | |
| 772 | 790 | 3.1.5. freeze_noirq() |
| 791 | +^^^^^^^^^^^^^^^^^^^^^ | |
| 773 | 792 | |
| 774 | 793 | The freeze_noirq() callback is hibernation-specific. It is executed during |
| 775 | 794 | hibernation, after prepare() and freeze() callbacks have been executed for all |
| @@ -786,6 +805,7 @@ The difference between freeze_noirq() and freeze() is analogous to the · 10 unmodified lines | ||
| 786 | 805 | difference between suspend_noirq() and suspend(). |
| 787 | 806 | |
| 788 | 807 | 3.1.6. poweroff() |
| 808 | +^^^^^^^^^^^^^^^^^ | |
| 789 | 809 | |
| 790 | 810 | The poweroff() callback is hibernation-specific. It is executed when the system |
| 791 | 811 | is about to be powered off after saving a hibernation image to a persistent |
| @@ -802,6 +822,7 @@ into a low-power state, respectively, but it need not save the device's standard · 10 unmodified lines | ||
| 802 | 822 | configuration registers. |
| 803 | 823 | |
| 804 | 824 | 3.1.7. poweroff_noirq() |
| 825 | +^^^^^^^^^^^^^^^^^^^^^^^ | |
| 805 | 826 | |
| 806 | 827 | The poweroff_noirq() callback is hibernation-specific. It is executed after |
| 807 | 828 | poweroff() callbacks have been executed for all devices in the system. |
| @@ -814,6 +835,7 @@ The difference between poweroff_noirq() and poweroff() is analogous to the · 6 unmodified lines | ||
| 814 | 835 | difference between suspend_noirq() and suspend(). |
| 815 | 836 | |
| 816 | 837 | 3.1.8. resume_noirq() |
| 838 | +^^^^^^^^^^^^^^^^^^^^^ | |
| 817 | 839 | |
| 818 | 840 | The resume_noirq() callback is only executed during system resume, after the |
| 819 | 841 | PM core has enabled the non-boot CPUs. The driver's interrupt handler will not |
| @@ -827,6 +849,7 @@ it should only be used for performing operations that would lead to race · 7 unmodified lines | ||
| 827 | 849 | conditions if carried out by resume(). |
| 828 | 850 | |
| 829 | 851 | 3.1.9. resume() |
| 852 | +^^^^^^^^^^^^^^^ | |
| 830 | 853 | |
| 831 | 854 | The resume() callback is only executed during system resume, after |
| 832 | 855 | resume_noirq() callbacks have been executed for all devices in the system and |
| @@ -837,6 +860,7 @@ device and bringing it back to the fully functional state. The device should be · 4 unmodified lines | ||
| 837 | 860 | able to process I/O in a usual way after resume() has returned. |
| 838 | 861 | |
| 839 | 862 | 3.1.10. thaw_noirq() |
| 863 | +^^^^^^^^^^^^^^^^^^^^ | |
| 840 | 864 | |
| 841 | 865 | The thaw_noirq() callback is hibernation-specific. It is executed after a |
| 842 | 866 | system image has been created and the non-boot CPUs have been enabled by the PM |
| @@ -851,6 +875,7 @@ freeze() and freeze_noirq(), so in general it does not need to modify the · 8 unmodified lines | ||
| 851 | 875 | contents of the device's registers. |
| 852 | 876 | |
| 853 | 877 | 3.1.11. thaw() |
| 878 | +^^^^^^^^^^^^^^ | |
| 854 | 879 | |
| 855 | 880 | The thaw() callback is hibernation-specific. It is executed after thaw_noirq() |
| 856 | 881 | callbacks have been executed for all devices in the system and after device |
| @@ -860,6 +885,7 @@ This callback is responsible for restoring the pre-freeze configuration of · 3 unmodified lines | ||
| 860 | 885 | the device, so that it will work in a usual way after thaw() has returned. |
| 861 | 886 | |
| 862 | 887 | 3.1.12. restore_noirq() |
| 888 | +^^^^^^^^^^^^^^^^^^^^^^^ | |
| 863 | 889 | |
| 864 | 890 | The restore_noirq() callback is hibernation-specific. It is executed in the |
| 865 | 891 | restore_noirq phase of hibernation, when the boot kernel has passed control to |
| @@ -875,6 +901,7 @@ For the vast majority of PCI device drivers there is no difference between · 9 unmodified lines | ||
| 875 | 901 | resume_noirq() and restore_noirq(). |
| 876 | 902 | |
| 877 | 903 | 3.1.13. restore() |
| 904 | +^^^^^^^^^^^^^^^^^ | |
| 878 | 905 | |
| 879 | 906 | The restore() callback is hibernation-specific. It is executed after |
| 880 | 907 | restore_noirq() callbacks have been executed for all devices in the system and |
| @@ -888,14 +915,17 @@ For the vast majority of PCI device drivers there is no difference between · 7 unmodified lines | ||
| 888 | 915 | resume() and restore(). |
| 889 | 916 | |
| 890 | 917 | 3.1.14. complete() |
| 918 | +^^^^^^^^^^^^^^^^^^ | |
| 891 | 919 | |
| 892 | 920 | The complete() callback is executed in the following situations: |
| 921 | + | |
| 893 | 922 | - during system resume, after resume() callbacks have been executed for all |
| 894 | 923 | devices, |
| 895 | 924 | - during hibernation, before saving the system image, after thaw() callbacks |
| 896 | 925 | have been executed for all devices, |
| 897 | 926 | - during system restore, when the system is going back to its pre-hibernation |
| 898 | 927 | state, after restore() callbacks have been executed for all devices. |
| 928 | + | |
| 899 | 929 | It also may be executed if the loading of a hibernation image into memory fails |
| 900 | 930 | (in that case it is run after thaw() callbacks have been executed for all |
| 901 | 931 | devices that have drivers in the boot kernel). |
| @@ -904,6 +934,7 @@ This callback is entirely optional, although it may be necessary if the · 2 unmodified lines | ||
| 904 | 934 | prepare() callback performs operations that need to be reversed. |
| 905 | 935 | |
| 906 | 936 | 3.1.15. runtime_suspend() |
| 937 | +^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 907 | 938 | |
| 908 | 939 | The runtime_suspend() callback is specific to device runtime power management |
| 909 | 940 | (runtime PM). It is executed by the PM core's runtime PM framework when the |
| @@ -915,6 +946,7 @@ put into a low-power state, but it must allow the PCI subsystem to perform all · 5 unmodified lines | ||
| 915 | 946 | of the PCI-specific actions necessary for suspending the device. |
| 916 | 947 | |
| 917 | 948 | 3.1.16. runtime_resume() |
| 949 | +^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 918 | 950 | |
| 919 | 951 | The runtime_resume() callback is specific to device runtime PM. It is executed |
| 920 | 952 | by the PM core's runtime PM framework when the device is about to be resumed |
| @@ -927,6 +959,7 @@ The device is expected to be able to process I/O in the usual way after · 6 unmodified lines | ||
| 927 | 959 | runtime_resume() has returned. |
| 928 | 960 | |
| 929 | 961 | 3.1.17. runtime_idle() |
| 962 | +^^^^^^^^^^^^^^^^^^^^^^ | |
| 930 | 963 | |
| 931 | 964 | The runtime_idle() callback is specific to device runtime PM. It is executed |
| 932 | 965 | by the PM core's runtime PM framework whenever it may be desirable to suspend |
| @@ -939,6 +972,7 @@ PCI subsystem will call pm_runtime_suspend() for the device, which in turn will · 6 unmodified lines | ||
| 939 | 972 | cause the driver's runtime_suspend() callback to be executed. |
| 940 | 973 | |
| 941 | 974 | 3.1.18. Pointing Multiple Callback Pointers to One Routine |
| 975 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 942 | 976 | |
| 943 | 977 | Although in principle each of the callbacks described in the previous |
| 944 | 978 | subsections can be defined as a separate function, it often is convenient to |
| @@ -962,6 +996,7 @@ dev_pm_ops to indicate that one suspend routine is to be pointed to by the · 17 unmodified lines | ||
| 962 | 996 | be pointed to by the .resume(), .thaw(), and .restore() members. |
| 963 | 997 | |
| 964 | 998 | 3.1.19. Driver Flags for Power Management |
| 999 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 965 | 1000 | |
| 966 | 1001 | The PM core allows device drivers to set flags that influence the handling of |
| 967 | 1002 | power management for the devices by the core itself and by middle layer code |
| @@ -1007,6 +1042,7 @@ it. · 39 unmodified lines | ||
| 1007 | 1042 | |
| 1008 | 1043 | 3.2. Device Runtime Power Management |
| 1009 | 1044 | ------------------------------------ |
| 1045 | + | |
| 1010 | 1046 | In addition to providing device power management callbacks PCI device drivers |
| 1011 | 1047 | are responsible for controlling the runtime power management (runtime PM) of |
| 1012 | 1048 | their devices. |
| @@ -1073,22 +1109,27 @@ device the PM core automatically queues a request to check if the device is · 60 unmodified lines | ||
| 1073 | 1109 | idle), device drivers are generally responsible for queuing power management |
| 1074 | 1110 | requests for their devices. For this purpose they should use the runtime PM |
| 1075 | 1111 | helper functions provided by the PM core, discussed in |
| 1076 | −Documentation/power/runtime_pm.txt. | |
| 1112 | +Documentation/power/runtime_pm.rst. | |
| 1077 | 1113 | |
| 1078 | 1114 | Devices can also be suspended and resumed synchronously, without placing a |
| 1079 | 1115 | request into pm_wq. In the majority of cases this also is done by their |
| 1080 | 1116 | drivers that use helper functions provided by the PM core for this purpose. |
| 1081 | 1117 | |
| 1082 | 1118 | For more information on the runtime PM of devices refer to |
| 1083 | −Documentation/power/runtime_pm.txt. | |
| 1119 | +Documentation/power/runtime_pm.rst. | |
| 1084 | 1120 | |
| 1085 | 1121 | |
| 1086 | 1122 | 4. Resources |
| 1087 | 1123 | ============ |
| 1088 | 1124 | |
| 1089 | 1125 | PCI Local Bus Specification, Rev. 3.0 |
| 1126 | + | |
| 1090 | 1127 | PCI Bus Power Management Interface Specification, Rev. 1.2 |
| 1128 | + | |
| 1091 | 1129 | Advanced Configuration and Power Interface (ACPI) Specification, Rev. 3.0b |
| 1130 | + | |
| 1092 | 1131 | PCI Express Base Specification, Rev. 2.0 |
| 1132 | + | |
| 1093 | 1133 | Documentation/driver-api/pm/devices.rst |
| 1094 | −Documentation/power/runtime_pm.txt | |
| 1134 | + | |
| 1135 | +Documentation/power/runtime_pm.rst | |
| @@ -1,4 +1,6 @@ | ||
| 1 | −PM Quality Of Service Interface. | |
| 1 | +=============================== | |
| 2 | +PM Quality Of Service Interface | |
| 3 | +=============================== | |
| 2 | 4 | |
| 3 | 5 | This interface provides a kernel and user mode interface for registering |
| 4 | 6 | performance expectations by drivers, subsystems and user space applications on |
| @@ -11,6 +13,7 @@ memory_bandwidth. · 6 unmodified lines | ||
| 11 | 13 | constraints and PM QoS flags. |
| 12 | 14 | |
| 13 | 15 | Each parameters have defined units: |
| 16 | + | |
| 14 | 17 | * latency: usec |
| 15 | 18 | * timeout: usec |
| 16 | 19 | * throughput: kbs (kilo bit / sec) |
| @@ -18,6 +21,7 @@ Each parameters have defined units: · 1 unmodified line | ||
| 18 | 21 | |
| 19 | 22 | |
| 20 | 23 | 1. PM QoS framework |
| 24 | +=================== | |
| 21 | 25 | |
| 22 | 26 | The infrastructure exposes multiple misc device nodes one per implemented |
| 23 | 27 | 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. · 13 unmodified lines | ||
| 37 | 41 | From kernel mode the use of this interface is simple: |
| 38 | 42 | |
| 39 | 43 | void pm_qos_add_request(handle, param_class, target_value): |
| 40 | −Will insert an element into the list for that identified PM QoS class with the | |
| 41 | −target value. Upon change to this list the new target is recomputed and any | |
| 42 | −registered notifiers are called only if the target value is now different. | |
| 43 | −Clients of pm_qos need to save the returned handle for future use in other | |
| 44 | −pm_qos API functions. | |
| 44 | + Will insert an element into the list for that identified PM QoS class with the | |
| 45 | + target value. Upon change to this list the new target is recomputed and any | |
| 46 | + registered notifiers are called only if the target value is now different. | |
| 47 | + Clients of pm_qos need to save the returned handle for future use in other | |
| 48 | + pm_qos API functions. | |
| 45 | 49 | |
| 46 | 50 | void pm_qos_update_request(handle, new_target_value): |
| 47 | −Will update the list element pointed to by the handle with the new target value | |
| 48 | −and recompute the new aggregated target, calling the notification tree if the | |
| 49 | −target is changed. | |
| 51 | + Will update the list element pointed to by the handle with the new target value | |
| 52 | + and recompute the new aggregated target, calling the notification tree if the | |
| 53 | + target is changed. | |
| 50 | 54 | |
| 51 | 55 | void pm_qos_remove_request(handle): |
| 52 | −Will remove the element. After removal it will update the aggregate target and | |
| 53 | −call the notification tree if the target was changed as a result of removing | |
| 54 | −the request. | |
| 56 | + Will remove the element. After removal it will update the aggregate target and | |
| 57 | + call the notification tree if the target was changed as a result of removing | |
| 58 | + the request. | |
| 55 | 59 | |
| 56 | 60 | int pm_qos_request(param_class): |
| 57 | −Returns the aggregated value for a given PM QoS class. | |
| 61 | + Returns the aggregated value for a given PM QoS class. | |
| 58 | 62 | |
| 59 | 63 | int pm_qos_request_active(handle): |
| 60 | −Returns if the request is still active, i.e. it has not been removed from a | |
| 61 | −PM QoS class constraints list. | |
| 64 | + Returns if the request is still active, i.e. it has not been removed from a | |
| 65 | + PM QoS class constraints list. | |
| 62 | 66 | |
| 63 | 67 | int pm_qos_add_notifier(param_class, notifier): |
| 64 | −Adds a notification callback function to the PM QoS class. The callback is | |
| 65 | −called when the aggregated value for the PM QoS class is changed. | |
| 68 | + Adds a notification callback function to the PM QoS class. The callback is | |
| 69 | + called when the aggregated value for the PM QoS class is changed. | |
| 66 | 70 | |
| 67 | 71 | int pm_qos_remove_notifier(int param_class, notifier): |
| 68 | −Removes the notification callback function for the PM QoS class. | |
| 72 | + Removes the notification callback function for the PM QoS class. | |
| 69 | 73 | |
| 70 | 74 | |
| 71 | 75 | From user mode: |
| 76 | + | |
| 72 | 77 | Only processes can register a pm_qos request. To provide for automatic |
| 73 | 78 | cleanup of a process, the interface requires the process to register its |
| 74 | 79 | parameter requests in the following way: |
| @@ -89,6 +94,7 @@ node. · 14 unmodified lines | ||
| 89 | 94 | |
| 90 | 95 | |
| 91 | 96 | 2. PM QoS per-device latency and flags framework |
| 97 | +================================================ | |
| 92 | 98 | |
| 93 | 99 | For each device, there are three lists of PM QoS requests. Two of them are |
| 94 | 100 | maintained along with the aggregated targets of resume latency and active |
| @@ -107,73 +113,80 @@ the aggregated value does not require any locking mechanism. · 12 unmodified lines | ||
| 107 | 113 | From kernel mode the use of this interface is the following: |
| 108 | 114 | |
| 109 | 115 | int dev_pm_qos_add_request(device, handle, type, value): |
| 110 | −Will insert an element into the list for that identified device with the | |
| 111 | −target value. Upon change to this list the new target is recomputed and any | |
| 112 | −registered notifiers are called only if the target value is now different. | |
| 113 | −Clients of dev_pm_qos need to save the handle for future use in other | |
| 114 | −dev_pm_qos API functions. | |
| 116 | + Will insert an element into the list for that identified device with the | |
| 117 | + target value. Upon change to this list the new target is recomputed and any | |
| 118 | + registered notifiers are called only if the target value is now different. | |
| 119 | + Clients of dev_pm_qos need to save the handle for future use in other | |
| 120 | + dev_pm_qos API functions. | |
| 115 | 121 | |
| 116 | 122 | int dev_pm_qos_update_request(handle, new_value): |
| 117 | −Will update the list element pointed to by the handle with the new target value | |
| 118 | −and recompute the new aggregated target, calling the notification trees if the | |
| 119 | −target is changed. | |
| 123 | + Will update the list element pointed to by the handle with the new target | |
| 124 | + value and recompute the new aggregated target, calling the notification | |
| 125 | + trees if the target is changed. | |
| 120 | 126 | |
| 121 | 127 | int dev_pm_qos_remove_request(handle): |
| 122 | −Will remove the element. After removal it will update the aggregate target and | |
| 123 | −call the notification trees if the target was changed as a result of removing | |
| 124 | −the request. | |
| 128 | + Will remove the element. After removal it will update the aggregate target | |
| 129 | + and call the notification trees if the target was changed as a result of | |
| 130 | + removing the request. | |
| 125 | 131 | |
| 126 | 132 | s32 dev_pm_qos_read_value(device): |
| 127 | −Returns the aggregated value for a given device's constraints list. | |
| 133 | + Returns the aggregated value for a given device's constraints list. | |
| 128 | 134 | |
| 129 | 135 | enum pm_qos_flags_status dev_pm_qos_flags(device, mask) |
| 130 | −Check PM QoS flags of the given device against the given mask of flags. | |
| 131 | −The meaning of the return values is as follows: | |
| 132 | − PM_QOS_FLAGS_ALL: All flags from the mask are set | |
| 133 | − PM_QOS_FLAGS_SOME: Some flags from the mask are set | |
| 134 | − PM_QOS_FLAGS_NONE: No flags from the mask are set | |
| 135 | − PM_QOS_FLAGS_UNDEFINED: The device's PM QoS structure has not been | |
| 136 | − initialized or the list of requests is empty. | |
| 136 | + Check PM QoS flags of the given device against the given mask of flags. | |
| 137 | + The meaning of the return values is as follows: | |
| 138 | + | |
| 139 | + PM_QOS_FLAGS_ALL: | |
| 140 | + All flags from the mask are set | |
| 141 | + PM_QOS_FLAGS_SOME: | |
| 142 | + Some flags from the mask are set | |
| 143 | + PM_QOS_FLAGS_NONE: | |
| 144 | + No flags from the mask are set | |
| 145 | + PM_QOS_FLAGS_UNDEFINED: | |
| 146 | + The device's PM QoS structure has not been initialized | |
| 147 | + or the list of requests is empty. | |
| 137 | 148 | |
| 138 | 149 | int dev_pm_qos_add_ancestor_request(dev, handle, type, value) |
| 139 | −Add a PM QoS request for the first direct ancestor of the given device whose | |
| 140 | −power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests) | |
| 141 | −or whose power.set_latency_tolerance callback pointer is not NULL (for | |
| 142 | −DEV_PM_QOS_LATENCY_TOLERANCE requests). | |
| 150 | + Add a PM QoS request for the first direct ancestor of the given device whose | |
| 151 | + power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests) | |
| 152 | + or whose power.set_latency_tolerance callback pointer is not NULL (for | |
| 153 | + DEV_PM_QOS_LATENCY_TOLERANCE requests). | |
| 143 | 154 | |
| 144 | 155 | int dev_pm_qos_expose_latency_limit(device, value) |
| 145 | −Add a request to the device's PM QoS list of resume latency constraints and | |
| 146 | −create a sysfs attribute pm_qos_resume_latency_us under the device's power | |
| 147 | −directory allowing user space to manipulate that request. | |
| 156 | + Add a request to the device's PM QoS list of resume latency constraints and | |
| 157 | + create a sysfs attribute pm_qos_resume_latency_us under the device's power | |
| 158 | + directory allowing user space to manipulate that request. | |
| 148 | 159 | |
| 149 | 160 | void dev_pm_qos_hide_latency_limit(device) |
| 150 | −Drop the request added by dev_pm_qos_expose_latency_limit() from the device's | |
| 151 | −PM QoS list of resume latency constraints and remove sysfs attribute | |
| 152 | −pm_qos_resume_latency_us from the device's power directory. | |
| 161 | + Drop the request added by dev_pm_qos_expose_latency_limit() from the device's | |
| 162 | + PM QoS list of resume latency constraints and remove sysfs attribute | |
| 163 | + pm_qos_resume_latency_us from the device's power directory. | |
| 153 | 164 | |
| 154 | 165 | int dev_pm_qos_expose_flags(device, value) |
| 155 | −Add a request to the device's PM QoS list of flags and create sysfs attribute | |
| 156 | −pm_qos_no_power_off under the device's power directory allowing user space to | |
| 157 | −change the value of the PM_QOS_FLAG_NO_POWER_OFF flag. | |
| 166 | + Add a request to the device's PM QoS list of flags and create sysfs attribute | |
| 167 | + pm_qos_no_power_off under the device's power directory allowing user space to | |
| 168 | + change the value of the PM_QOS_FLAG_NO_POWER_OFF flag. | |
| 158 | 169 | |
| 159 | 170 | void dev_pm_qos_hide_flags(device) |
| 160 | −Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS list | |
| 161 | −of flags and remove sysfs attribute pm_qos_no_power_off from the device's power | |
| 162 | −directory. | |
| 171 | + Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS list | |
| 172 | + of flags and remove sysfs attribute pm_qos_no_power_off from the device's power | |
| 173 | + directory. | |
| 163 | 174 | |
| 164 | 175 | Notification mechanisms: |
| 176 | + | |
| 165 | 177 | The per-device PM QoS framework has a per-device notification tree. |
| 166 | 178 | |
| 167 | 179 | int dev_pm_qos_add_notifier(device, notifier): |
| 168 | −Adds a notification callback function for the device. | |
| 169 | −The callback is called when the aggregated value of the device constraints list | |
| 170 | −is changed (for resume latency device PM QoS only). | |
| 180 | + Adds a notification callback function for the device. | |
| 181 | + The callback is called when the aggregated value of the device constraints list | |
| 182 | + is changed (for resume latency device PM QoS only). | |
| 171 | 183 | |
| 172 | 184 | int dev_pm_qos_remove_notifier(device, notifier): |
| 173 | −Removes the notification callback function for the device. | |
| 185 | + Removes the notification callback function for the device. | |
| 174 | 186 | |
| 175 | 187 | |
| 176 | 188 | Active state latency tolerance |
| 189 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 177 | 190 | |
| 178 | 191 | This device PM QoS type is used to support systems in which hardware may switch |
| 179 | 192 | to energy-saving operation modes on the fly. In those systems, if the operation |
| @@ -0,0 +1,282 @@ | ||
| 1 | +======================== | |
| 2 | +Linux power supply class | |
| 3 | +======================== | |
| 4 | + | |
| 5 | +Synopsis | |
| 6 | +~~~~~~~~ | |
| 7 | +Power supply class used to represent battery, UPS, AC or DC power supply | |
| 8 | +properties to user-space. | |
| 9 | + | |
| 10 | +It defines core set of attributes, which should be applicable to (almost) | |
| 11 | +every power supply out there. Attributes are available via sysfs and uevent | |
| 12 | +interfaces. | |
| 13 | + | |
| 14 | +Each attribute has well defined meaning, up to unit of measure used. While | |
| 15 | +the attributes provided are believed to be universally applicable to any | |
| 16 | +power supply, specific monitoring hardware may not be able to provide them | |
| 17 | +all, so any of them may be skipped. | |
| 18 | + | |
| 19 | +Power supply class is extensible, and allows to define drivers own attributes. | |
| 20 | +The core attribute set is subject to the standard Linux evolution (i.e. | |
| 21 | +if it will be found that some attribute is applicable to many power supply | |
| 22 | +types or their drivers, it can be added to the core set). | |
| 23 | + | |
| 24 | +It also integrates with LED framework, for the purpose of providing | |
| 25 | +typically expected feedback of battery charging/fully charged status and | |
| 26 | +AC/USB power supply online status. (Note that specific details of the | |
| 27 | +indication (including whether to use it at all) are fully controllable by | |
| 28 | +user and/or specific machine defaults, per design principles of LED | |
| 29 | +framework). | |
| 30 | + | |
| 31 | + | |
| 32 | +Attributes/properties | |
| 33 | +~~~~~~~~~~~~~~~~~~~~~ | |
| 34 | +Power supply class has predefined set of attributes, this eliminates code | |
| 35 | +duplication across drivers. Power supply class insist on reusing its | |
| 36 | +predefined attributes *and* their units. | |
| 37 | + | |
| 38 | +So, userspace gets predictable set of attributes and their units for any | |
| 39 | +kind of power supply, and can process/present them to a user in consistent | |
| 40 | +manner. Results for different power supplies and machines are also directly | |
| 41 | +comparable. | |
| 42 | + | |
| 43 | +See drivers/power/supply/ds2760_battery.c and drivers/power/supply/pda_power.c | |
| 44 | +for the example how to declare and handle attributes. | |
| 45 | + | |
| 46 | + | |
| 47 | +Units | |
| 48 | +~~~~~ | |
| 49 | +Quoting include/linux/power_supply.h: | |
| 50 | + | |
| 51 | + All voltages, currents, charges, energies, time and temperatures in µV, | |
| 52 | + µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise | |
| 53 | + stated. It's driver's job to convert its raw values to units in which | |
| 54 | + this class operates. | |
| 55 | + | |
| 56 | + | |
| 57 | +Attributes/properties detailed | |
| 58 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 59 | + | |
| 60 | ++--------------------------------------------------------------------------+ | |
| 61 | +| **Charge/Energy/Capacity - how to not confuse** | | |
| 62 | ++--------------------------------------------------------------------------+ | |
| 63 | +| **Because both "charge" (µAh) and "energy" (µWh) represents "capacity" | | |
| 64 | +| of battery, this class distinguish these terms. Don't mix them!** | | |
| 65 | +| | | |
| 66 | +| - `CHARGE_*` | | |
| 67 | +| attributes represents capacity in µAh only. | | |
| 68 | +| - `ENERGY_*` | | |
| 69 | +| attributes represents capacity in µWh only. | | |
| 70 | +| - `CAPACITY` | | |
| 71 | +| attribute represents capacity in *percents*, from 0 to 100. | | |
| 72 | ++--------------------------------------------------------------------------+ | |
| 73 | + | |
| 74 | +Postfixes: | |
| 75 | + | |
| 76 | +_AVG | |
| 77 | + *hardware* averaged value, use it if your hardware is really able to | |
| 78 | + report averaged values. | |
| 79 | +_NOW | |
| 80 | + momentary/instantaneous values. | |
| 81 | + | |
| 82 | +STATUS | |
| 83 | + this attribute represents operating status (charging, full, | |
| 84 | + discharging (i.e. powering a load), etc.). This corresponds to | |
| 85 | + `BATTERY_STATUS_*` values, as defined in battery.h. | |
| 86 | + | |
| 87 | +CHARGE_TYPE | |
| 88 | + batteries can typically charge at different rates. | |
| 89 | + This defines trickle and fast charges. For batteries that | |
| 90 | + are already charged or discharging, 'n/a' can be displayed (or | |
| 91 | + 'unknown', if the status is not known). | |
| 92 | + | |
| 93 | +AUTHENTIC | |
| 94 | + indicates the power supply (battery or charger) connected | |
| 95 | + to the platform is authentic(1) or non authentic(0). | |
| 96 | + | |
| 97 | +HEALTH | |
| 98 | + represents health of the battery, values corresponds to | |
| 99 | + POWER_SUPPLY_HEALTH_*, defined in battery.h. | |
| 100 | + | |
| 101 | +VOLTAGE_OCV | |
| 102 | + open circuit voltage of the battery. | |
| 103 | + | |
| 104 | +VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN | |
| 105 | + design values for maximal and minimal power supply voltages. | |
| 106 | + Maximal/minimal means values of voltages when battery considered | |
| 107 | + "full"/"empty" at normal conditions. Yes, there is no direct relation | |
| 108 | + between voltage and battery capacity, but some dumb | |
| 109 | + batteries use voltage for very approximated calculation of capacity. | |
| 110 | + Battery driver also can use this attribute just to inform userspace | |
| 111 | + about maximal and minimal voltage thresholds of a given battery. | |
| 112 | + | |
| 113 | +VOLTAGE_MAX, VOLTAGE_MIN | |
| 114 | + same as _DESIGN voltage values except that these ones should be used | |
| 115 | + if hardware could only guess (measure and retain) the thresholds of a | |
| 116 | + given power supply. | |
| 117 | + | |
| 118 | +VOLTAGE_BOOT | |
| 119 | + Reports the voltage measured during boot | |
| 120 | + | |
| 121 | +CURRENT_BOOT | |
| 122 | + Reports the current measured during boot | |
| 123 | + | |
| 124 | +CHARGE_FULL_DESIGN, CHARGE_EMPTY_DESIGN | |
| 125 | + design charge values, when battery considered full/empty. | |
| 126 | + | |
| 127 | +ENERGY_FULL_DESIGN, ENERGY_EMPTY_DESIGN | |
| 128 | + same as above but for energy. | |
| 129 | + | |
| 130 | +CHARGE_FULL, CHARGE_EMPTY | |
| 131 | + These attributes means "last remembered value of charge when battery | |
| 132 | + became full/empty". It also could mean "value of charge when battery | |
| 133 | + considered full/empty at given conditions (temperature, age)". | |
| 134 | + I.e. these attributes represents real thresholds, not design values. | |
| 135 | + | |
| 136 | +ENERGY_FULL, ENERGY_EMPTY | |
| 137 | + same as above but for energy. | |
| 138 | + | |
| 139 | +CHARGE_COUNTER | |
| 140 | + the current charge counter (in µAh). This could easily | |
| 141 | + be negative; there is no empty or full value. It is only useful for | |
| 142 | + relative, time-based measurements. | |
| 143 | + | |
| 144 | +PRECHARGE_CURRENT | |
| 145 | + the maximum charge current during precharge phase of charge cycle | |
| 146 | + (typically 20% of battery capacity). | |
| 147 | + | |
| 148 | +CHARGE_TERM_CURRENT | |
| 149 | + Charge termination current. The charge cycle terminates when battery | |
| 150 | + voltage is above recharge threshold, and charge current is below | |
| 151 | + this setting (typically 10% of battery capacity). | |
| 152 | + | |
| 153 | +CONSTANT_CHARGE_CURRENT | |
| 154 | + constant charge current programmed by charger. | |
| 155 | + | |
| 156 | + | |
| 157 | +CONSTANT_CHARGE_CURRENT_MAX | |
| 158 | + maximum charge current supported by the power supply object. | |
| 159 | + | |
| 160 | +CONSTANT_CHARGE_VOLTAGE | |
| 161 | + constant charge voltage programmed by charger. | |
| 162 | +CONSTANT_CHARGE_VOLTAGE_MAX | |
| 163 | + maximum charge voltage supported by the power supply object. | |
| 164 | + | |
| 165 | +INPUT_CURRENT_LIMIT | |
| 166 | + input current limit programmed by charger. Indicates | |
| 167 | + the current drawn from a charging source. | |
| 168 | + | |
| 169 | +CHARGE_CONTROL_LIMIT | |
| 170 | + current charge control limit setting | |
| 171 | +CHARGE_CONTROL_LIMIT_MAX | |
| 172 | + maximum charge control limit setting | |
| 173 | + | |
| 174 | +CALIBRATE | |
| 175 | + battery or coulomb counter calibration status | |
| 176 | + | |
| 177 | +CAPACITY | |
| 178 | + capacity in percents. | |
| 179 | +CAPACITY_ALERT_MIN | |
| 180 | + minimum capacity alert value in percents. | |
| 181 | +CAPACITY_ALERT_MAX | |
| 182 | + maximum capacity alert value in percents. | |
| 183 | +CAPACITY_LEVEL | |
| 184 | + capacity level. This corresponds to POWER_SUPPLY_CAPACITY_LEVEL_*. | |
| 185 | + | |
| 186 | +TEMP | |
| 187 | + temperature of the power supply. | |
| 188 | +TEMP_ALERT_MIN | |
| 189 | + minimum battery temperature alert. | |
| 190 | +TEMP_ALERT_MAX | |
| 191 | + maximum battery temperature alert. | |
| 192 | +TEMP_AMBIENT | |
| 193 | + ambient temperature. | |
| 194 | +TEMP_AMBIENT_ALERT_MIN | |
| 195 | + minimum ambient temperature alert. | |
| 196 | +TEMP_AMBIENT_ALERT_MAX | |
| 197 | + maximum ambient temperature alert. | |
| 198 | +TEMP_MIN | |
| 199 | + minimum operatable temperature | |
| 200 | +TEMP_MAX | |
| 201 | + maximum operatable temperature | |
| 202 | + | |
| 203 | +TIME_TO_EMPTY | |
| 204 | + seconds left for battery to be considered empty | |
| 205 | + (i.e. while battery powers a load) | |
| 206 | +TIME_TO_FULL | |
| 207 | + seconds left for battery to be considered full | |
| 208 | + (i.e. while battery is charging) | |
| 209 | + | |
| 210 | + | |
| 211 | +Battery <-> external power supply interaction | |
| 212 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 213 | +Often power supplies are acting as supplies and supplicants at the same | |
| 214 | +time. Batteries are good example. So, batteries usually care if they're | |
| 215 | +externally powered or not. | |
| 216 | + | |
| 217 | +For that case, power supply class implements notification mechanism for | |
| 218 | +batteries. | |
| 219 | + | |
| 220 | +External power supply (AC) lists supplicants (batteries) names in | |
| 221 | +"supplied_to" struct member, and each power_supply_changed() call | |
| 222 | +issued by external power supply will notify supplicants via | |
| 223 | +external_power_changed callback. | |
| 224 | + | |
| 225 | + | |
| 226 | +Devicetree battery characteristics | |
| 227 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 228 | +Drivers should call power_supply_get_battery_info() to obtain battery | |
| 229 | +characteristics from a devicetree battery node, defined in | |
| 230 | +Documentation/devicetree/bindings/power/supply/battery.txt. This is | |
| 231 | +implemented in drivers/power/supply/bq27xxx_battery.c. | |
| 232 | + | |
| 233 | +Properties in struct power_supply_battery_info and their counterparts in the | |
| 234 | +battery node have names corresponding to elements in enum power_supply_property, | |
| 235 | +for naming consistency between sysfs attributes and battery node properties. | |
| 236 | + | |
| 237 | + | |
| 238 | +QA | |
| 239 | +~~ | |
| 240 | + | |
| 241 | +Q: | |
| 242 | + Where is POWER_SUPPLY_PROP_XYZ attribute? | |
| 243 | +A: | |
| 244 | + If you cannot find attribute suitable for your driver needs, feel free | |
| 245 | + to add it and send patch along with your driver. | |
| 246 | + | |
| 247 | + The attributes available currently are the ones currently provided by the | |
| 248 | + drivers written. | |
| 249 | + | |
| 250 | + Good candidates to add in future: model/part#, cycle_time, manufacturer, | |
| 251 | + etc. | |
| 252 | + | |
| 253 | + | |
| 254 | +Q: | |
| 255 | + I have some very specific attribute (e.g. battery color), should I add | |
| 256 | + this attribute to standard ones? | |
| 257 | +A: | |
| 258 | + Most likely, no. Such attribute can be placed in the driver itself, if | |
| 259 | + it is useful. Of course, if the attribute in question applicable to | |
| 260 | + large set of batteries, provided by many drivers, and/or comes from | |
| 261 | + some general battery specification/standard, it may be a candidate to | |
| 262 | + be added to the core attribute set. | |
| 263 | + | |
| 264 | + | |
| 265 | +Q: | |
| 266 | + Suppose, my battery monitoring chip/firmware does not provides capacity | |
| 267 | + in percents, but provides charge_{now,full,empty}. Should I calculate | |
| 268 | + percentage capacity manually, inside the driver, and register CAPACITY | |
| 269 | + attribute? The same question about time_to_empty/time_to_full. | |
| 270 | +A: | |
| 271 | + Most likely, no. This class is designed to export properties which are | |
| 272 | + directly measurable by the specific hardware available. | |
| 273 | + | |
| 274 | + Inferring not available properties using some heuristics or mathematical | |
| 275 | + model is not subject of work for a battery driver. Such functionality | |
| 276 | + should be factored out, and in fact, apm_power, the driver to serve | |
| 277 | + legacy APM API on top of power supply class, uses a simple heuristic of | |
| 278 | + approximating remaining battery capacity based on its charge, current, | |
| 279 | + voltage and so on. But full-fledged battery model is likely not subject | |
| 280 | + for kernel at all, as it would require floating point calculation to deal | |
| 281 | + with things like differential equations and Kalman filters. This is | |
| 282 | + better be handled by batteryd/libbattery, yet to be written. | |
| @@ -1,231 +0,0 @@ | ||
| 1 | −Linux power supply class | |
| 2 | −======================== | |
| 3 | − | |
| 4 | −Synopsis | |
| 5 | −~~~~~~~~ | |
| 6 | −Power supply class used to represent battery, UPS, AC or DC power supply | |
| 7 | −properties to user-space. | |
| 8 | − | |
| 9 | −It defines core set of attributes, which should be applicable to (almost) | |
| 10 | −every power supply out there. Attributes are available via sysfs and uevent | |
| 11 | −interfaces. | |
| 12 | − | |
| 13 | −Each attribute has well defined meaning, up to unit of measure used. While | |
| 14 | −the attributes provided are believed to be universally applicable to any | |
| 15 | −power supply, specific monitoring hardware may not be able to provide them | |
| 16 | −all, so any of them may be skipped. | |
| 17 | − | |
| 18 | −Power supply class is extensible, and allows to define drivers own attributes. | |
| 19 | −The core attribute set is subject to the standard Linux evolution (i.e. | |
| 20 | −if it will be found that some attribute is applicable to many power supply | |
| 21 | −types or their drivers, it can be added to the core set). | |
| 22 | − | |
| 23 | −It also integrates with LED framework, for the purpose of providing | |
| 24 | −typically expected feedback of battery charging/fully charged status and | |
| 25 | −AC/USB power supply online status. (Note that specific details of the | |
| 26 | −indication (including whether to use it at all) are fully controllable by | |
| 27 | −user and/or specific machine defaults, per design principles of LED | |
| 28 | −framework). | |
| 29 | − | |
| 30 | − | |
| 31 | −Attributes/properties | |
| 32 | −~~~~~~~~~~~~~~~~~~~~~ | |
| 33 | −Power supply class has predefined set of attributes, this eliminates code | |
| 34 | −duplication across drivers. Power supply class insist on reusing its | |
| 35 | −predefined attributes *and* their units. | |
| 36 | − | |
| 37 | −So, userspace gets predictable set of attributes and their units for any | |
| 38 | −kind of power supply, and can process/present them to a user in consistent | |
| 39 | −manner. Results for different power supplies and machines are also directly | |
| 40 | −comparable. | |
| 41 | − | |
| 42 | −See drivers/power/supply/ds2760_battery.c and drivers/power/supply/pda_power.c | |
| 43 | −for the example how to declare and handle attributes. | |
| 44 | − | |
| 45 | − | |
| 46 | −Units | |
| 47 | −~~~~~ | |
| 48 | −Quoting include/linux/power_supply.h: | |
| 49 | − | |
| 50 | − All voltages, currents, charges, energies, time and temperatures in µV, | |
| 51 | − µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise | |
| 52 | − stated. It's driver's job to convert its raw values to units in which | |
| 53 | − this class operates. | |
| 54 | − | |
| 55 | − | |
| 56 | −Attributes/properties detailed | |
| 57 | −~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 58 | − | |
| 59 | −~ ~ ~ ~ ~ ~ ~ Charge/Energy/Capacity - how to not confuse ~ ~ ~ ~ ~ ~ ~ | |
| 60 | −~ ~ | |
| 61 | −~ Because both "charge" (µAh) and "energy" (µWh) represents "capacity" ~ | |
| 62 | −~ of battery, this class distinguish these terms. Don't mix them! ~ | |
| 63 | −~ ~ | |
| 64 | −~ CHARGE_* attributes represents capacity in µAh only. ~ | |
| 65 | −~ ENERGY_* attributes represents capacity in µWh only. ~ | |
| 66 | −~ CAPACITY attribute represents capacity in *percents*, from 0 to 100. ~ | |
| 67 | −~ ~ | |
| 68 | −~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ | |
| 69 | − | |
| 70 | −Postfixes: | |
| 71 | −_AVG - *hardware* averaged value, use it if your hardware is really able to | |
| 72 | −report averaged values. | |
| 73 | −_NOW - momentary/instantaneous values. | |
| 74 | − | |
| 75 | −STATUS - this attribute represents operating status (charging, full, | |
| 76 | −discharging (i.e. powering a load), etc.). This corresponds to | |
| 77 | −BATTERY_STATUS_* values, as defined in battery.h. | |
| 78 | − | |
| 79 | −CHARGE_TYPE - batteries can typically charge at different rates. | |
| 80 | −This defines trickle and fast charges. For batteries that | |
| 81 | −are already charged or discharging, 'n/a' can be displayed (or | |
| 82 | −'unknown', if the status is not known). | |
| 83 | − | |
| 84 | −AUTHENTIC - indicates the power supply (battery or charger) connected | |
| 85 | −to the platform is authentic(1) or non authentic(0). | |
| 86 | − | |
| 87 | −HEALTH - represents health of the battery, values corresponds to | |
| 88 | −POWER_SUPPLY_HEALTH_*, defined in battery.h. | |
| 89 | − | |
| 90 | −VOLTAGE_OCV - open circuit voltage of the battery. | |
| 91 | − | |
| 92 | −VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN - design values for maximal and | |
| 93 | −minimal power supply voltages. Maximal/minimal means values of voltages | |
| 94 | −when battery considered "full"/"empty" at normal conditions. Yes, there is | |
| 95 | −no direct relation between voltage and battery capacity, but some dumb | |
| 96 | −batteries use voltage for very approximated calculation of capacity. | |
| 97 | −Battery driver also can use this attribute just to inform userspace | |
| 98 | −about maximal and minimal voltage thresholds of a given battery. | |
| 99 | − | |
| 100 | −VOLTAGE_MAX, VOLTAGE_MIN - same as _DESIGN voltage values except that | |
| 101 | −these ones should be used if hardware could only guess (measure and | |
| 102 | −retain) the thresholds of a given power supply. | |
| 103 | − | |
| 104 | −VOLTAGE_BOOT - Reports the voltage measured during boot | |
| 105 | − | |
| 106 | −CURRENT_BOOT - Reports the current measured during boot | |
| 107 | − | |
| 108 | −CHARGE_FULL_DESIGN, CHARGE_EMPTY_DESIGN - design charge values, when | |
| 109 | −battery considered full/empty. | |
| 110 | − | |
| 111 | −ENERGY_FULL_DESIGN, ENERGY_EMPTY_DESIGN - same as above but for energy. | |
| 112 | − | |
| 113 | −CHARGE_FULL, CHARGE_EMPTY - These attributes means "last remembered value | |
| 114 | −of charge when battery became full/empty". It also could mean "value of | |
| 115 | −charge when battery considered full/empty at given conditions (temperature, | |
| 116 | −age)". I.e. these attributes represents real thresholds, not design values. | |
| 117 | − | |
| 118 | −ENERGY_FULL, ENERGY_EMPTY - same as above but for energy. | |
| 119 | − | |
| 120 | −CHARGE_COUNTER - the current charge counter (in µAh). This could easily | |
| 121 | −be negative; there is no empty or full value. It is only useful for | |
| 122 | −relative, time-based measurements. | |
| 123 | − | |
| 124 | −PRECHARGE_CURRENT - the maximum charge current during precharge phase | |
| 125 | −of charge cycle (typically 20% of battery capacity). | |
| 126 | −CHARGE_TERM_CURRENT - Charge termination current. The charge cycle | |
| 127 | −terminates when battery voltage is above recharge threshold, and charge | |
| 128 | −current is below this setting (typically 10% of battery capacity). | |
| 129 | − | |
| 130 | −CONSTANT_CHARGE_CURRENT - constant charge current programmed by charger. | |
| 131 | −CONSTANT_CHARGE_CURRENT_MAX - maximum charge current supported by the | |
| 132 | −power supply object. | |
| 133 | − | |
| 134 | −CONSTANT_CHARGE_VOLTAGE - constant charge voltage programmed by charger. | |
| 135 | −CONSTANT_CHARGE_VOLTAGE_MAX - maximum charge voltage supported by the | |
| 136 | −power supply object. | |
| 137 | − | |
| 138 | −INPUT_CURRENT_LIMIT - input current limit programmed by charger. Indicates | |
| 139 | −the current drawn from a charging source. | |
| 140 | − | |
| 141 | −CHARGE_CONTROL_LIMIT - current charge control limit setting | |
| 142 | −CHARGE_CONTROL_LIMIT_MAX - maximum charge control limit setting | |
| 143 | − | |
| 144 | −CALIBRATE - battery or coulomb counter calibration status | |
| 145 | − | |
| 146 | −CAPACITY - capacity in percents. | |
| 147 | −CAPACITY_ALERT_MIN - minimum capacity alert value in percents. | |
| 148 | −CAPACITY_ALERT_MAX - maximum capacity alert value in percents. | |
| 149 | −CAPACITY_LEVEL - capacity level. This corresponds to | |
| 150 | −POWER_SUPPLY_CAPACITY_LEVEL_*. | |
| 151 | − | |
| 152 | −TEMP - temperature of the power supply. | |
| 153 | −TEMP_ALERT_MIN - minimum battery temperature alert. | |
| 154 | −TEMP_ALERT_MAX - maximum battery temperature alert. | |
| 155 | −TEMP_AMBIENT - ambient temperature. | |
| 156 | −TEMP_AMBIENT_ALERT_MIN - minimum ambient temperature alert. | |
| 157 | −TEMP_AMBIENT_ALERT_MAX - maximum ambient temperature alert. | |
| 158 | −TEMP_MIN - minimum operatable temperature | |
| 159 | −TEMP_MAX - maximum operatable temperature | |
| 160 | − | |
| 161 | −TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e. | |
| 162 | −while battery powers a load) | |
| 163 | −TIME_TO_FULL - seconds left for battery to be considered full (i.e. | |
| 164 | −while battery is charging) | |
| 165 | − | |
| 166 | − | |
| 167 | −Battery <-> external power supply interaction | |
| 168 | −~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 169 | −Often power supplies are acting as supplies and supplicants at the same | |
| 170 | −time. Batteries are good example. So, batteries usually care if they're | |
| 171 | −externally powered or not. | |
| 172 | − | |
| 173 | −For that case, power supply class implements notification mechanism for | |
| 174 | −batteries. | |
| 175 | − | |
| 176 | −External power supply (AC) lists supplicants (batteries) names in | |
| 177 | −"supplied_to" struct member, and each power_supply_changed() call | |
| 178 | −issued by external power supply will notify supplicants via | |
| 179 | −external_power_changed callback. | |
| 180 | − | |
| 181 | − | |
| 182 | −Devicetree battery characteristics | |
| 183 | −~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 184 | −Drivers should call power_supply_get_battery_info() to obtain battery | |
| 185 | −characteristics from a devicetree battery node, defined in | |
| 186 | −Documentation/devicetree/bindings/power/supply/battery.txt. This is | |
| 187 | −implemented in drivers/power/supply/bq27xxx_battery.c. | |
| 188 | − | |
| 189 | −Properties in struct power_supply_battery_info and their counterparts in the | |
| 190 | −battery node have names corresponding to elements in enum power_supply_property, | |
| 191 | −for naming consistency between sysfs attributes and battery node properties. | |
| 192 | − | |
| 193 | − | |
| 194 | −QA | |
| 195 | −~~ | |
| 196 | −Q: Where is POWER_SUPPLY_PROP_XYZ attribute? | |
| 197 | −A: If you cannot find attribute suitable for your driver needs, feel free | |
| 198 | − to add it and send patch along with your driver. | |
| 199 | − | |
| 200 | − The attributes available currently are the ones currently provided by the | |
| 201 | − drivers written. | |
| 202 | − | |
| 203 | − Good candidates to add in future: model/part#, cycle_time, manufacturer, | |
| 204 | − etc. | |
| 205 | − | |
| 206 | − | |
| 207 | −Q: I have some very specific attribute (e.g. battery color), should I add | |
| 208 | − this attribute to standard ones? | |
| 209 | −A: Most likely, no. Such attribute can be placed in the driver itself, if | |
| 210 | − it is useful. Of course, if the attribute in question applicable to | |
| 211 | − large set of batteries, provided by many drivers, and/or comes from | |
| 212 | − some general battery specification/standard, it may be a candidate to | |
| 213 | − be added to the core attribute set. | |
| 214 | − | |
| 215 | − | |
| 216 | −Q: Suppose, my battery monitoring chip/firmware does not provides capacity | |
| 217 | − in percents, but provides charge_{now,full,empty}. Should I calculate | |
| 218 | − percentage capacity manually, inside the driver, and register CAPACITY | |
| 219 | − attribute? The same question about time_to_empty/time_to_full. | |
| 220 | −A: Most likely, no. This class is designed to export properties which are | |
| 221 | − directly measurable by the specific hardware available. | |
| 222 | − | |
| 223 | − Inferring not available properties using some heuristics or mathematical | |
| 224 | − model is not subject of work for a battery driver. Such functionality | |
| 225 | − should be factored out, and in fact, apm_power, the driver to serve | |
| 226 | − legacy APM API on top of power supply class, uses a simple heuristic of | |
| 227 | − approximating remaining battery capacity based on its charge, current, | |
| 228 | − voltage and so on. But full-fledged battery model is likely not subject | |
| 229 | − for kernel at all, as it would require floating point calculation to deal | |
| 230 | − with things like differential equations and Kalman filters. This is | |
| 231 | − better be handled by batteryd/libbattery, yet to be written. | |
| @@ -0,0 +1,257 @@ | ||
| 1 | +======================= | |
| 2 | +Power Capping Framework | |
| 3 | +======================= | |
| 4 | + | |
| 5 | +The power capping framework provides a consistent interface between the kernel | |
| 6 | +and the user space that allows power capping drivers to expose the settings to | |
| 7 | +user space in a uniform way. | |
| 8 | + | |
| 9 | +Terminology | |
| 10 | +=========== | |
| 11 | + | |
| 12 | +The framework exposes power capping devices to user space via sysfs in the | |
| 13 | +form of a tree of objects. The objects at the root level of the tree represent | |
| 14 | +'control types', which correspond to different methods of power capping. For | |
| 15 | +example, the intel-rapl control type represents the Intel "Running Average | |
| 16 | +Power Limit" (RAPL) technology, whereas the 'idle-injection' control type | |
| 17 | +corresponds to the use of idle injection for controlling power. | |
| 18 | + | |
| 19 | +Power zones represent different parts of the system, which can be controlled and | |
| 20 | +monitored using the power capping method determined by the control type the | |
| 21 | +given zone belongs to. They each contain attributes for monitoring power, as | |
| 22 | +well as controls represented in the form of power constraints. If the parts of | |
| 23 | +the system represented by different power zones are hierarchical (that is, one | |
| 24 | +bigger part consists of multiple smaller parts that each have their own power | |
| 25 | +controls), those power zones may also be organized in a hierarchy with one | |
| 26 | +parent power zone containing multiple subzones and so on to reflect the power | |
| 27 | +control topology of the system. In that case, it is possible to apply power | |
| 28 | +capping to a set of devices together using the parent power zone and if more | |
| 29 | +fine grained control is required, it can be applied through the subzones. | |
| 30 | + | |
| 31 | + | |
| 32 | +Example sysfs interface tree:: | |
| 33 | + | |
| 34 | + /sys/devices/virtual/powercap | |
| 35 | + └──intel-rapl | |
| 36 | + ├──intel-rapl:0 | |
| 37 | + │ ├──constraint_0_name | |
| 38 | + │ ├──constraint_0_power_limit_uw | |
| 39 | + │ ├──constraint_0_time_window_us | |
| 40 | + │ ├──constraint_1_name | |
| 41 | + │ ├──constraint_1_power_limit_uw | |
| 42 | + │ ├──constraint_1_time_window_us | |
| 43 | + │ ├──device -> ../../intel-rapl | |
| 44 | + │ ├──energy_uj | |
| 45 | + │ ├──intel-rapl:0:0 | |
| 46 | + │ │ ├──constraint_0_name | |
| 47 | + │ │ ├──constraint_0_power_limit_uw | |
| 48 | + │ │ ├──constraint_0_time_window_us | |
| 49 | + │ │ ├──constraint_1_name | |
| 50 | + │ │ ├──constraint_1_power_limit_uw | |
| 51 | + │ │ ├──constraint_1_time_window_us | |
| 52 | + │ │ ├──device -> ../../intel-rapl:0 | |
| 53 | + │ │ ├──energy_uj | |
| 54 | + │ │ ├──max_energy_range_uj | |
| 55 | + │ │ ├──name | |
| 56 | + │ │ ├──enabled | |
| 57 | + │ │ ├──power | |
| 58 | + │ │ │ ├──async | |
| 59 | + │ │ │ [] | |
| 60 | + │ │ ├──subsystem -> ../../../../../../class/power_cap | |
| 61 | + │ │ └──uevent | |
| 62 | + │ ├──intel-rapl:0:1 | |
| 63 | + │ │ ├──constraint_0_name | |
| 64 | + │ │ ├──constraint_0_power_limit_uw | |
| 65 | + │ │ ├──constraint_0_time_window_us | |
| 66 | + │ │ ├──constraint_1_name | |
| 67 | + │ │ ├──constraint_1_power_limit_uw | |
| 68 | + │ │ ├──constraint_1_time_window_us | |
| 69 | + │ │ ├──device -> ../../intel-rapl:0 | |
| 70 | + │ │ ├──energy_uj | |
| 71 | + │ │ ├──max_energy_range_uj | |
| 72 | + │ │ ├──name | |
| 73 | + │ │ ├──enabled | |
| 74 | + │ │ ├──power | |
| 75 | + │ │ │ ├──async | |
| 76 | + │ │ │ [] | |
| 77 | + │ │ ├──subsystem -> ../../../../../../class/power_cap | |
| 78 | + │ │ └──uevent | |
| 79 | + │ ├──max_energy_range_uj | |
| 80 | + │ ├──max_power_range_uw | |
| 81 | + │ ├──name | |
| 82 | + │ ├──enabled | |
| 83 | + │ ├──power | |
| 84 | + │ │ ├──async | |
| 85 | + │ │ [] | |
| 86 | + │ ├──subsystem -> ../../../../../class/power_cap | |
| 87 | + │ ├──enabled | |
| 88 | + │ ├──uevent | |
| 89 | + ├──intel-rapl:1 | |
| 90 | + │ ├──constraint_0_name | |
| 91 | + │ ├──constraint_0_power_limit_uw | |
| 92 | + │ ├──constraint_0_time_window_us | |
| 93 | + │ ├──constraint_1_name | |
| 94 | + │ ├──constraint_1_power_limit_uw | |
| 95 | + │ ├──constraint_1_time_window_us | |
| 96 | + │ ├──device -> ../../intel-rapl | |
| 97 | + │ ├──energy_uj | |
| 98 | + │ ├──intel-rapl:1:0 | |
| 99 | + │ │ ├──constraint_0_name | |
| 100 | + │ │ ├──constraint_0_power_limit_uw | |
| 101 | + │ │ ├──constraint_0_time_window_us | |
| 102 | + │ │ ├──constraint_1_name | |
| 103 | + │ │ ├──constraint_1_power_limit_uw | |
| 104 | + │ │ ├──constraint_1_time_window_us | |
| 105 | + │ │ ├──device -> ../../intel-rapl:1 | |
| 106 | + │ │ ├──energy_uj | |
| 107 | + │ │ ├──max_energy_range_uj | |
| 108 | + │ │ ├──name | |
| 109 | + │ │ ├──enabled | |
| 110 | + │ │ ├──power | |
| 111 | + │ │ │ ├──async | |
| 112 | + │ │ │ [] | |
| 113 | + │ │ ├──subsystem -> ../../../../../../class/power_cap | |
| 114 | + │ │ └──uevent | |
| 115 | + │ ├──intel-rapl:1:1 | |
| 116 | + │ │ ├──constraint_0_name | |
| 117 | + │ │ ├──constraint_0_power_limit_uw | |
| 118 | + │ │ ├──constraint_0_time_window_us | |
| 119 | + │ │ ├──constraint_1_name | |
| 120 | + │ │ ├──constraint_1_power_limit_uw | |
| 121 | + │ │ ├──constraint_1_time_window_us | |
| 122 | + │ │ ├──device -> ../../intel-rapl:1 | |
| 123 | + │ │ ├──energy_uj | |
| 124 | + │ │ ├──max_energy_range_uj | |
| 125 | + │ │ ├──name | |
| 126 | + │ │ ├──enabled | |
| 127 | + │ │ ├──power | |
| 128 | + │ │ │ ├──async | |
| 129 | + │ │ │ [] | |
| 130 | + │ │ ├──subsystem -> ../../../../../../class/power_cap | |
| 131 | + │ │ └──uevent | |
| 132 | + │ ├──max_energy_range_uj | |
| 133 | + │ ├──max_power_range_uw | |
| 134 | + │ ├──name | |
| 135 | + │ ├──enabled | |
| 136 | + │ ├──power | |
| 137 | + │ │ ├──async | |
| 138 | + │ │ [] | |
| 139 | + │ ├──subsystem -> ../../../../../class/power_cap | |
| 140 | + │ ├──uevent | |
| 141 | + ├──power | |
| 142 | + │ ├──async | |
| 143 | + │ [] | |
| 144 | + ├──subsystem -> ../../../../class/power_cap | |
| 145 | + ├──enabled | |
| 146 | + └──uevent | |
| 147 | + | |
| 148 | +The above example illustrates a case in which the Intel RAPL technology, | |
| 149 | +available in Intel® IA-64 and IA-32 Processor Architectures, is used. There is one | |
| 150 | +control type called intel-rapl which contains two power zones, intel-rapl:0 and | |
| 151 | +intel-rapl:1, representing CPU packages. Each of these power zones contains | |
| 152 | +two subzones, intel-rapl:j:0 and intel-rapl:j:1 (j = 0, 1), representing the | |
| 153 | +"core" and the "uncore" parts of the given CPU package, respectively. All of | |
| 154 | +the zones and subzones contain energy monitoring attributes (energy_uj, | |
| 155 | +max_energy_range_uj) and constraint attributes (constraint_*) allowing controls | |
| 156 | +to be applied (the constraints in the 'package' power zones apply to the whole | |
| 157 | +CPU packages and the subzone constraints only apply to the respective parts of | |
| 158 | +the given package individually). Since Intel RAPL doesn't provide instantaneous | |
| 159 | +power value, there is no power_uw attribute. | |
| 160 | + | |
| 161 | +In addition to that, each power zone contains a name attribute, allowing the | |
| 162 | +part of the system represented by that zone to be identified. | |
| 163 | +For example:: | |
| 164 | + | |
| 165 | + cat /sys/class/power_cap/intel-rapl/intel-rapl:0/name | |
| 166 | + | |
| 167 | +package-0 | |
| 168 | +--------- | |
| 169 | + | |
| 170 | +The Intel RAPL technology allows two constraints, short term and long term, | |
| 171 | +with two different time windows to be applied to each power zone. Thus for | |
| 172 | +each zone there are 2 attributes representing the constraint names, 2 power | |
| 173 | +limits and 2 attributes representing the sizes of the time windows. Such that, | |
| 174 | +constraint_j_* attributes correspond to the jth constraint (j = 0,1). | |
| 175 | + | |
| 176 | +For example:: | |
| 177 | + | |
| 178 | + constraint_0_name | |
| 179 | + constraint_0_power_limit_uw | |
| 180 | + constraint_0_time_window_us | |
| 181 | + constraint_1_name | |
| 182 | + constraint_1_power_limit_uw | |
| 183 | + constraint_1_time_window_us | |
| 184 | + | |
| 185 | +Power Zone Attributes | |
| 186 | +===================== | |
| 187 | + | |
| 188 | +Monitoring attributes | |
| 189 | +--------------------- | |
| 190 | + | |
| 191 | +energy_uj (rw) | |
| 192 | + Current energy counter in micro joules. Write "0" to reset. | |
| 193 | + If the counter can not be reset, then this attribute is read only. | |
| 194 | + | |
| 195 | +max_energy_range_uj (ro) | |
| 196 | + Range of the above energy counter in micro-joules. | |
| 197 | + | |
| 198 | +power_uw (ro) | |
| 199 | + Current power in micro watts. | |
| 200 | + | |
| 201 | +max_power_range_uw (ro) | |
| 202 | + Range of the above power value in micro-watts. | |
| 203 | + | |
| 204 | +name (ro) | |
| 205 | + Name of this power zone. | |
| 206 | + | |
| 207 | +It is possible that some domains have both power ranges and energy counter ranges; | |
| 208 | +however, only one is mandatory. | |
| 209 | + | |
| 210 | +Constraints | |
| 211 | +----------- | |
| 212 | + | |
| 213 | +constraint_X_power_limit_uw (rw) | |
| 214 | + Power limit in micro watts, which should be applicable for the | |
| 215 | + time window specified by "constraint_X_time_window_us". | |
| 216 | + | |
| 217 | +constraint_X_time_window_us (rw) | |
| 218 | + Time window in micro seconds. | |
| 219 | + | |
| 220 | +constraint_X_name (ro) | |
| 221 | + An optional name of the constraint | |
| 222 | + | |
| 223 | +constraint_X_max_power_uw(ro) | |
| 224 | + Maximum allowed power in micro watts. | |
| 225 | + | |
| 226 | +constraint_X_min_power_uw(ro) | |
| 227 | + Minimum allowed power in micro watts. | |
| 228 | + | |
| 229 | +constraint_X_max_time_window_us(ro) | |
| 230 | + Maximum allowed time window in micro seconds. | |
| 231 | + | |
| 232 | +constraint_X_min_time_window_us(ro) | |
| 233 | + Minimum allowed time window in micro seconds. | |
| 234 | + | |
| 235 | +Except power_limit_uw and time_window_us other fields are optional. | |
| 236 | + | |
| 237 | +Common zone and control type attributes | |
| 238 | +--------------------------------------- | |
| 239 | + | |
| 240 | +enabled (rw): Enable/Disable controls at zone level or for all zones using | |
| 241 | +a control type. | |
| 242 | + | |
| 243 | +Power Cap Client Driver Interface | |
| 244 | +================================= | |
| 245 | + | |
| 246 | +The API summary: | |
| 247 | + | |
| 248 | +Call powercap_register_control_type() to register control type object. | |
| 249 | +Call powercap_register_zone() to register a power zone (under a given | |
| 250 | +control type), either as a top-level power zone or as a subzone of another | |
| 251 | +power zone registered earlier. | |
| 252 | +The number of constraints in a power zone and the corresponding callbacks have | |
| 253 | +to be defined prior to calling powercap_register_zone() to register that zone. | |
| 254 | + | |
| 255 | +To Free a power zone call powercap_unregister_zone(). | |
| 256 | +To free a control type object call powercap_unregister_control_type(). | |
| 257 | +Detailed API can be generated using kernel-doc on include/linux/powercap.h. | |
| @@ -1,236 +0,0 @@ | ||
| 1 | −Power Capping Framework | |
| 2 | −================================== | |
| 3 | − | |
| 4 | −The power capping framework provides a consistent interface between the kernel | |
| 5 | −and the user space that allows power capping drivers to expose the settings to | |
| 6 | −user space in a uniform way. | |
| 7 | − | |
| 8 | −Terminology | |
| 9 | −========================= | |
| 10 | −The framework exposes power capping devices to user space via sysfs in the | |
| 11 | −form of a tree of objects. The objects at the root level of the tree represent | |
| 12 | −'control types', which correspond to different methods of power capping. For | |
| 13 | −example, the intel-rapl control type represents the Intel "Running Average | |
| 14 | −Power Limit" (RAPL) technology, whereas the 'idle-injection' control type | |
| 15 | −corresponds to the use of idle injection for controlling power. | |
| 16 | − | |
| 17 | −Power zones represent different parts of the system, which can be controlled and | |
| 18 | −monitored using the power capping method determined by the control type the | |
| 19 | −given zone belongs to. They each contain attributes for monitoring power, as | |
| 20 | −well as controls represented in the form of power constraints. If the parts of | |
| 21 | −the system represented by different power zones are hierarchical (that is, one | |
| 22 | −bigger part consists of multiple smaller parts that each have their own power | |
| 23 | −controls), those power zones may also be organized in a hierarchy with one | |
| 24 | −parent power zone containing multiple subzones and so on to reflect the power | |
| 25 | −control topology of the system. In that case, it is possible to apply power | |
| 26 | −capping to a set of devices together using the parent power zone and if more | |
| 27 | −fine grained control is required, it can be applied through the subzones. | |
| 28 | − | |
| 29 | − | |
| 30 | −Example sysfs interface tree: | |
| 31 | − | |
| 32 | −/sys/devices/virtual/powercap | |
| 33 | −??? intel-rapl | |
| 34 | − ??? intel-rapl:0 | |
| 35 | − ? ??? constraint_0_name | |
| 36 | − ? ??? constraint_0_power_limit_uw | |
| 37 | − ? ??? constraint_0_time_window_us | |
| 38 | − ? ??? constraint_1_name | |
| 39 | − ? ??? constraint_1_power_limit_uw | |
| 40 | − ? ??? constraint_1_time_window_us | |
| 41 | − ? ??? device -> ../../intel-rapl | |
| 42 | − ? ??? energy_uj | |
| 43 | − ? ??? intel-rapl:0:0 | |
| 44 | − ? ? ??? constraint_0_name | |
| 45 | − ? ? ??? constraint_0_power_limit_uw | |
| 46 | − ? ? ??? constraint_0_time_window_us | |
| 47 | − ? ? ??? constraint_1_name | |
| 48 | − ? ? ??? constraint_1_power_limit_uw | |
| 49 | − ? ? ??? constraint_1_time_window_us | |
| 50 | − ? ? ??? device -> ../../intel-rapl:0 | |
| 51 | − ? ? ??? energy_uj | |
| 52 | − ? ? ??? max_energy_range_uj | |
| 53 | − ? ? ??? name | |
| 54 | − ? ? ??? enabled | |
| 55 | − ? ? ??? power | |
| 56 | − ? ? ? ??? async | |
| 57 | − ? ? ? [] | |
| 58 | − ? ? ??? subsystem -> ../../../../../../class/power_cap | |
| 59 | − ? ? ??? uevent | |
| 60 | − ? ??? intel-rapl:0:1 | |
| 61 | − ? ? ??? constraint_0_name | |
| 62 | − ? ? ??? constraint_0_power_limit_uw | |
| 63 | − ? ? ??? constraint_0_time_window_us | |
| 64 | − ? ? ??? constraint_1_name | |
| 65 | − ? ? ??? constraint_1_power_limit_uw | |
| 66 | − ? ? ??? constraint_1_time_window_us | |
| 67 | − ? ? ??? device -> ../../intel-rapl:0 | |
| 68 | − ? ? ??? energy_uj | |
| 69 | − ? ? ??? max_energy_range_uj | |
| 70 | − ? ? ??? name | |
| 71 | − ? ? ??? enabled | |
| 72 | − ? ? ??? power | |
| 73 | − ? ? ? ??? async | |
| 74 | − ? ? ? [] | |
| 75 | − ? ? ??? subsystem -> ../../../../../../class/power_cap | |
| 76 | − ? ? ??? uevent | |
| 77 | − ? ??? max_energy_range_uj | |
| 78 | − ? ??? max_power_range_uw | |
| 79 | − ? ??? name | |
| 80 | − ? ??? enabled | |
| 81 | − ? ??? power | |
| 82 | − ? ? ??? async | |
| 83 | − ? ? [] | |
| 84 | − ? ??? subsystem -> ../../../../../class/power_cap | |
| 85 | − ? ??? enabled | |
| 86 | − ? ??? uevent | |
| 87 | − ??? intel-rapl:1 | |
| 88 | − ? ??? constraint_0_name | |
| 89 | − ? ??? constraint_0_power_limit_uw | |
| 90 | − ? ??? constraint_0_time_window_us | |
| 91 | − ? ??? constraint_1_name | |
| 92 | − ? ??? constraint_1_power_limit_uw | |
| 93 | − ? ??? constraint_1_time_window_us | |
| 94 | − ? ??? device -> ../../intel-rapl | |
| 95 | − ? ??? energy_uj | |
| 96 | − ? ??? intel-rapl:1:0 | |
| 97 | − ? ? ??? constraint_0_name | |
| 98 | − ? ? ??? constraint_0_power_limit_uw | |
| 99 | − ? ? ??? constraint_0_time_window_us | |
| 100 | − ? ? ??? constraint_1_name | |
| 101 | − ? ? ??? constraint_1_power_limit_uw | |
| 102 | − ? ? ??? constraint_1_time_window_us | |
| 103 | − ? ? ??? device -> ../../intel-rapl:1 | |
| 104 | − ? ? ??? energy_uj | |
| 105 | − ? ? ??? max_energy_range_uj | |
| 106 | − ? ? ??? name | |
| 107 | − ? ? ??? enabled | |
| 108 | − ? ? ??? power | |
| 109 | − ? ? ? ??? async | |
| 110 | − ? ? ? [] | |
| 111 | − ? ? ??? subsystem -> ../../../../../../class/power_cap | |
| 112 | − ? ? ??? uevent | |
| 113 | − ? ??? intel-rapl:1:1 | |
| 114 | − ? ? ??? constraint_0_name | |
| 115 | − ? ? ??? constraint_0_power_limit_uw | |
| 116 | − ? ? ??? constraint_0_time_window_us | |
| 117 | − ? ? ??? constraint_1_name | |
| 118 | − ? ? ??? constraint_1_power_limit_uw | |
| 119 | − ? ? ??? constraint_1_time_window_us | |
| 120 | − ? ? ??? device -> ../../intel-rapl:1 | |
| 121 | − ? ? ??? energy_uj | |
| 122 | − ? ? ??? max_energy_range_uj | |
| 123 | − ? ? ??? name | |
| 124 | − ? ? ??? enabled | |
| 125 | − ? ? ??? power | |
| 126 | − ? ? ? ??? async | |
| 127 | − ? ? ? [] | |
| 128 | − ? ? ??? subsystem -> ../../../../../../class/power_cap | |
| 129 | − ? ? ??? uevent | |
| 130 | − ? ??? max_energy_range_uj | |
| 131 | − ? ??? max_power_range_uw | |
| 132 | − ? ??? name | |
| 133 | − ? ??? enabled | |
| 134 | − ? ??? power | |
| 135 | − ? ? ??? async | |
| 136 | − ? ? [] | |
| 137 | − ? ??? subsystem -> ../../../../../class/power_cap | |
| 138 | − ? ??? uevent | |
| 139 | − ??? power | |
| 140 | − ? ??? async | |
| 141 | − ? [] | |
| 142 | − ??? subsystem -> ../../../../class/power_cap | |
| 143 | − ??? enabled | |
| 144 | − ??? uevent | |
| 145 | − | |
| 146 | −The above example illustrates a case in which the Intel RAPL technology, | |
| 147 | −available in Intel® IA-64 and IA-32 Processor Architectures, is used. There is one | |
| 148 | −control type called intel-rapl which contains two power zones, intel-rapl:0 and | |
| 149 | −intel-rapl:1, representing CPU packages. Each of these power zones contains | |
| 150 | −two subzones, intel-rapl:j:0 and intel-rapl:j:1 (j = 0, 1), representing the | |
| 151 | −"core" and the "uncore" parts of the given CPU package, respectively. All of | |
| 152 | −the zones and subzones contain energy monitoring attributes (energy_uj, | |
| 153 | −max_energy_range_uj) and constraint attributes (constraint_*) allowing controls | |
| 154 | −to be applied (the constraints in the 'package' power zones apply to the whole | |
| 155 | −CPU packages and the subzone constraints only apply to the respective parts of | |
| 156 | −the given package individually). Since Intel RAPL doesn't provide instantaneous | |
| 157 | −power value, there is no power_uw attribute. | |
| 158 | − | |
| 159 | −In addition to that, each power zone contains a name attribute, allowing the | |
| 160 | −part of the system represented by that zone to be identified. | |
| 161 | −For example: | |
| 162 | − | |
| 163 | −cat /sys/class/power_cap/intel-rapl/intel-rapl:0/name | |
| 164 | −package-0 | |
| 165 | − | |
| 166 | −The Intel RAPL technology allows two constraints, short term and long term, | |
| 167 | −with two different time windows to be applied to each power zone. Thus for | |
| 168 | −each zone there are 2 attributes representing the constraint names, 2 power | |
| 169 | −limits and 2 attributes representing the sizes of the time windows. Such that, | |
| 170 | −constraint_j_* attributes correspond to the jth constraint (j = 0,1). | |
| 171 | − | |
| 172 | −For example: | |
| 173 | − constraint_0_name | |
| 174 | − constraint_0_power_limit_uw | |
| 175 | − constraint_0_time_window_us | |
| 176 | − constraint_1_name | |
| 177 | − constraint_1_power_limit_uw | |
| 178 | − constraint_1_time_window_us | |
| 179 | − | |
| 180 | −Power Zone Attributes | |
| 181 | −================================= | |
| 182 | −Monitoring attributes | |
| 183 | −---------------------- | |
| 184 | − | |
| 185 | −energy_uj (rw): Current energy counter in micro joules. Write "0" to reset. | |
| 186 | −If the counter can not be reset, then this attribute is read only. | |
| 187 | − | |
| 188 | −max_energy_range_uj (ro): Range of the above energy counter in micro-joules. | |
| 189 | − | |
| 190 | −power_uw (ro): Current power in micro watts. | |
| 191 | − | |
| 192 | −max_power_range_uw (ro): Range of the above power value in micro-watts. | |
| 193 | − | |
| 194 | −name (ro): Name of this power zone. | |
| 195 | − | |
| 196 | −It is possible that some domains have both power ranges and energy counter ranges; | |
| 197 | −however, only one is mandatory. | |
| 198 | − | |
| 199 | −Constraints | |
| 200 | −---------------- | |
| 201 | −constraint_X_power_limit_uw (rw): Power limit in micro watts, which should be | |
| 202 | −applicable for the time window specified by "constraint_X_time_window_us". | |
| 203 | − | |
| 204 | −constraint_X_time_window_us (rw): Time window in micro seconds. | |
| 205 | − | |
| 206 | −constraint_X_name (ro): An optional name of the constraint | |
| 207 | − | |
| 208 | −constraint_X_max_power_uw(ro): Maximum allowed power in micro watts. | |
| 209 | − | |
| 210 | −constraint_X_min_power_uw(ro): Minimum allowed power in micro watts. | |
| 211 | − | |
| 212 | −constraint_X_max_time_window_us(ro): Maximum allowed time window in micro seconds. | |
| 213 | − | |
| 214 | −constraint_X_min_time_window_us(ro): Minimum allowed time window in micro seconds. | |
| 215 | − | |
| 216 | −Except power_limit_uw and time_window_us other fields are optional. | |
| 217 | − | |
| 218 | −Common zone and control type attributes | |
| 219 | −---------------------------------------- | |
| 220 | −enabled (rw): Enable/Disable controls at zone level or for all zones using | |
| 221 | −a control type. | |
| 222 | − | |
| 223 | −Power Cap Client Driver Interface | |
| 224 | −================================== | |
| 225 | −The API summary: | |
| 226 | − | |
| 227 | −Call powercap_register_control_type() to register control type object. | |
| 228 | −Call powercap_register_zone() to register a power zone (under a given | |
| 229 | −control type), either as a top-level power zone or as a subzone of another | |
| 230 | −power zone registered earlier. | |
| 231 | −The number of constraints in a power zone and the corresponding callbacks have | |
| 232 | −to be defined prior to calling powercap_register_zone() to register that zone. | |
| 233 | − | |
| 234 | −To Free a power zone call powercap_unregister_zone(). | |
| 235 | −To free a control type object call powercap_unregister_control_type(). | |
| 236 | −Detailed API can be generated using kernel-doc on include/linux/powercap.h. | |
| @@ -1,3 +1,4 @@ | ||
| 1 | +=================================== | |
| 1 | 2 | Regulator Consumer Driver Interface |
| 2 | 3 | =================================== |
| 3 | 4 | |
| @@ -8,73 +9,77 @@ Please see overview.txt for a description of the terms used in this text. · 4 unmodified lines | ||
| 8 | 9 | 1. Consumer Regulator Access (static & dynamic drivers) |
| 9 | 10 | ======================================================= |
| 10 | 11 | |
| 11 | −A consumer driver can get access to its supply regulator by calling :- | |
| 12 | +A consumer driver can get access to its supply regulator by calling :: | |
| 12 | 13 | |
| 13 | −regulator = regulator_get(dev, "Vcc"); | |
| 14 | + regulator = regulator_get(dev, "Vcc"); | |
| 14 | 15 | |
| 15 | 16 | The consumer passes in its struct device pointer and power supply ID. The core |
| 16 | 17 | then finds the correct regulator by consulting a machine specific lookup table. |
| 17 | 18 | If the lookup is successful then this call will return a pointer to the struct |
| 18 | 19 | regulator that supplies this consumer. |
| 19 | 20 | |
| 20 | −To release the regulator the consumer driver should call :- | |
| 21 | +To release the regulator the consumer driver should call :: | |
| 21 | 22 | |
| 22 | −regulator_put(regulator); | |
| 23 | + regulator_put(regulator); | |
| 23 | 24 | |
| 24 | 25 | Consumers can be supplied by more than one regulator e.g. codec consumer with |
| 25 | −analog and digital supplies :- | |
| 26 | +analog and digital supplies :: | |
| 26 | 27 | |
| 27 | −digital = regulator_get(dev, "Vcc"); /* digital core */ | |
| 28 | −analog = regulator_get(dev, "Avdd"); /* analog */ | |
| 28 | + digital = regulator_get(dev, "Vcc"); /* digital core */ | |
| 29 | + analog = regulator_get(dev, "Avdd"); /* analog */ | |
| 29 | 30 | |
| 30 | 31 | The regulator access functions regulator_get() and regulator_put() will |
| 31 | 32 | usually be called in your device drivers probe() and remove() respectively. |
| 32 | 33 | |
| 33 | 34 | |
| 34 | 35 | 2. Regulator Output Enable & Disable (static & dynamic drivers) |
| 35 | −==================================================================== | |
| 36 | +=============================================================== | |
| 37 | + | |
| 36 | 38 | |
| 37 | −A consumer can enable its power supply by calling:- | |
| 39 | +A consumer can enable its power supply by calling:: | |
| 38 | 40 | |
| 39 | −int regulator_enable(regulator); | |
| 41 | + int regulator_enable(regulator); | |
| 40 | 42 | |
| 41 | −NOTE: The supply may already be enabled before regulator_enabled() is called. | |
| 42 | −This may happen if the consumer shares the regulator or the regulator has been | |
| 43 | −previously enabled by bootloader or kernel board initialization code. | |
| 43 | +NOTE: | |
| 44 | + The supply may already be enabled before regulator_enabled() is called. | |
| 45 | + This may happen if the consumer shares the regulator or the regulator has been | |
| 46 | + previously enabled by bootloader or kernel board initialization code. | |
| 44 | 47 | |
| 45 | −A consumer can determine if a regulator is enabled by calling :- | |
| 48 | +A consumer can determine if a regulator is enabled by calling:: | |
| 46 | 49 | |
| 47 | −int regulator_is_enabled(regulator); | |
| 50 | + int regulator_is_enabled(regulator); | |
| 48 | 51 | |
| 49 | 52 | This will return > zero when the regulator is enabled. |
| 50 | 53 | |
| 51 | 54 | |
| 52 | −A consumer can disable its supply when no longer needed by calling :- | |
| 55 | +A consumer can disable its supply when no longer needed by calling:: | |
| 53 | 56 | |
| 54 | −int regulator_disable(regulator); | |
| 57 | + int regulator_disable(regulator); | |
| 55 | 58 | |
| 56 | −NOTE: This may not disable the supply if it's shared with other consumers. The | |
| 57 | −regulator will only be disabled when the enabled reference count is zero. | |
| 59 | +NOTE: | |
| 60 | + This may not disable the supply if it's shared with other consumers. The | |
| 61 | + regulator will only be disabled when the enabled reference count is zero. | |
| 58 | 62 | |
| 59 | −Finally, a regulator can be forcefully disabled in the case of an emergency :- | |
| 63 | +Finally, a regulator can be forcefully disabled in the case of an emergency:: | |
| 60 | 64 | |
| 61 | −int regulator_force_disable(regulator); | |
| 65 | + int regulator_force_disable(regulator); | |
| 62 | 66 | |
| 63 | −NOTE: this will immediately and forcefully shutdown the regulator output. All | |
| 64 | −consumers will be powered off. | |
| 67 | +NOTE: | |
| 68 | + this will immediately and forcefully shutdown the regulator output. All | |
| 69 | + consumers will be powered off. | |
| 65 | 70 | |
| 66 | 71 | |
| 67 | 72 | 3. Regulator Voltage Control & Status (dynamic drivers) |
| 68 | −====================================================== | |
| 73 | +======================================================= | |
| 69 | 74 | |
| 70 | 75 | Some consumer drivers need to be able to dynamically change their supply |
| 71 | 76 | voltage to match system operating points. e.g. CPUfreq drivers can scale |
| 72 | 77 | voltage along with frequency to save power, SD drivers may need to select the |
| 73 | 78 | correct card voltage, etc. |
| 74 | 79 | |
| 75 | −Consumers can control their supply voltage by calling :- | |
| 80 | +Consumers can control their supply voltage by calling:: | |
| 76 | 81 | |
| 77 | −int regulator_set_voltage(regulator, min_uV, max_uV); | |
| 82 | + int regulator_set_voltage(regulator, min_uV, max_uV); | |
| 78 | 83 | |
| 79 | 84 | Where min_uV and max_uV are the minimum and maximum acceptable voltages in |
| 80 | 85 | microvolts. |
| @@ -84,47 +89,50 @@ when enabled, then the voltage changes instantly, otherwise the voltage · 3 unmodified lines | ||
| 84 | 89 | configuration changes and the voltage is physically set when the regulator is |
| 85 | 90 | next enabled. |
| 86 | 91 | |
| 87 | −The regulators configured voltage output can be found by calling :- | |
| 92 | +The regulators configured voltage output can be found by calling:: | |
| 88 | 93 | |
| 89 | −int regulator_get_voltage(regulator); | |
| 94 | + int regulator_get_voltage(regulator); | |
| 90 | 95 | |
| 91 | −NOTE: get_voltage() will return the configured output voltage whether the | |
| 92 | −regulator is enabled or disabled and should NOT be used to determine regulator | |
| 93 | −output state. However this can be used in conjunction with is_enabled() to | |
| 94 | −determine the regulator physical output voltage. | |
| 96 | +NOTE: | |
| 97 | + get_voltage() will return the configured output voltage whether the | |
| 98 | + regulator is enabled or disabled and should NOT be used to determine regulator | |
| 99 | + output state. However this can be used in conjunction with is_enabled() to | |
| 100 | + determine the regulator physical output voltage. | |
| 95 | 101 | |
| 96 | 102 | |
| 97 | 103 | 4. Regulator Current Limit Control & Status (dynamic drivers) |
| 98 | −=========================================================== | |
| 104 | +============================================================= | |
| 99 | 105 | |
| 100 | 106 | Some consumer drivers need to be able to dynamically change their supply |
| 101 | 107 | current limit to match system operating points. e.g. LCD backlight driver can |
| 102 | 108 | change the current limit to vary the backlight brightness, USB drivers may want |
| 103 | 109 | to set the limit to 500mA when supplying power. |
| 104 | 110 | |
| 105 | −Consumers can control their supply current limit by calling :- | |
| 111 | +Consumers can control their supply current limit by calling:: | |
| 106 | 112 | |
| 107 | −int regulator_set_current_limit(regulator, min_uA, max_uA); | |
| 113 | + int regulator_set_current_limit(regulator, min_uA, max_uA); | |
| 108 | 114 | |
| 109 | 115 | Where min_uA and max_uA are the minimum and maximum acceptable current limit in |
| 110 | 116 | microamps. |
| 111 | 117 | |
| 112 | −NOTE: this can be called when the regulator is enabled or disabled. If called | |
| 113 | −when enabled, then the current limit changes instantly, otherwise the current | |
| 114 | −limit configuration changes and the current limit is physically set when the | |
| 115 | −regulator is next enabled. | |
| 118 | +NOTE: | |
| 119 | + this can be called when the regulator is enabled or disabled. If called | |
| 120 | + when enabled, then the current limit changes instantly, otherwise the current | |
| 121 | + limit configuration changes and the current limit is physically set when the | |
| 122 | + regulator is next enabled. | |
| 116 | 123 | |
| 117 | −A regulators current limit can be found by calling :- | |
| 124 | +A regulators current limit can be found by calling:: | |
| 118 | 125 | |
| 119 | −int regulator_get_current_limit(regulator); | |
| 126 | + int regulator_get_current_limit(regulator); | |
| 120 | 127 | |
| 121 | −NOTE: get_current_limit() will return the current limit whether the regulator | |
| 122 | −is enabled or disabled and should not be used to determine regulator current | |
| 123 | −load. | |
| 128 | +NOTE: | |
| 129 | + get_current_limit() will return the current limit whether the regulator | |
| 130 | + is enabled or disabled and should not be used to determine regulator current | |
| 131 | + load. | |
| 124 | 132 | |
| 125 | 133 | |
| 126 | 134 | 5. Regulator Operating Mode Control & Status (dynamic drivers) |
| 127 | −============================================================= | |
| 135 | +============================================================== | |
| 128 | 136 | |
| 129 | 137 | Some consumers can further save system power by changing the operating mode of |
| 130 | 138 | their supply regulator to be more efficient when the consumers operating state |
| @@ -135,9 +143,9 @@ Regulator operating mode can be changed indirectly or directly. · 4 unmodified lines | ||
| 135 | 143 | Indirect operating mode control. |
| 136 | 144 | -------------------------------- |
| 137 | 145 | Consumer drivers can request a change in their supply regulator operating mode |
| 138 | −by calling :- | |
| 146 | +by calling:: | |
| 139 | 147 | |
| 140 | −int regulator_set_load(struct regulator *regulator, int load_uA); | |
| 148 | + int regulator_set_load(struct regulator *regulator, int load_uA); | |
| 141 | 149 | |
| 142 | 150 | This will cause the core to recalculate the total load on the regulator (based |
| 143 | 151 | on all its consumers) and change operating mode (if necessary and permitted) |
| @@ -153,12 +161,13 @@ consumers. · 9 unmodified lines | ||
| 153 | 161 | |
| 154 | 162 | Direct operating mode control. |
| 155 | 163 | ------------------------------ |
| 164 | + | |
| 156 | 165 | Bespoke or tightly coupled drivers may want to directly control regulator |
| 157 | 166 | operating mode depending on their operating point. This can be achieved by |
| 158 | −calling :- | |
| 167 | +calling:: | |
| 159 | 168 | |
| 160 | −int regulator_set_mode(struct regulator *regulator, unsigned int mode); | |
| 161 | −unsigned int regulator_get_mode(struct regulator *regulator); | |
| 169 | + int regulator_set_mode(struct regulator *regulator, unsigned int mode); | |
| 170 | + unsigned int regulator_get_mode(struct regulator *regulator); | |
| 162 | 171 | |
| 163 | 172 | Direct mode will only be used by consumers that *know* about the regulator and |
| 164 | 173 | are not sharing the regulator with other consumers. |
| @@ -166,24 +175,26 @@ are not sharing the regulator with other consumers. · 1 unmodified line | ||
| 166 | 175 | |
| 167 | 176 | 6. Regulator Events |
| 168 | 177 | =================== |
| 178 | + | |
| 169 | 179 | Regulators can notify consumers of external events. Events could be received by |
| 170 | 180 | consumers under regulator stress or failure conditions. |
| 171 | 181 | |
| 172 | −Consumers can register interest in regulator events by calling :- | |
| 182 | +Consumers can register interest in regulator events by calling:: | |
| 173 | 183 | |
| 174 | −int regulator_register_notifier(struct regulator *regulator, | |
| 175 | − struct notifier_block *nb); | |
| 184 | + int regulator_register_notifier(struct regulator *regulator, | |
| 185 | + struct notifier_block *nb); | |
| 176 | 186 | |
| 177 | −Consumers can unregister interest by calling :- | |
| 187 | +Consumers can unregister interest by calling:: | |
| 178 | 188 | |
| 179 | −int regulator_unregister_notifier(struct regulator *regulator, | |
| 180 | − struct notifier_block *nb); | |
| 189 | + int regulator_unregister_notifier(struct regulator *regulator, | |
| 190 | + struct notifier_block *nb); | |
| 181 | 191 | |
| 182 | 192 | Regulators use the kernel notifier framework to send event to their interested |
| 183 | 193 | consumers. |
| 184 | 194 | |
| 185 | 195 | 7. Regulator Direct Register Access |
| 186 | 196 | =================================== |
| 197 | + | |
| 187 | 198 | Some kinds of power management hardware or firmware are designed such that |
| 188 | 199 | they need to do low-level hardware access to regulators, with no involvement |
| 189 | 200 | from the kernel. Examples of such devices are: |
| @@ -199,20 +210,20 @@ to it. The regulator framework provides the following helpers for querying · 9 unmodified lines | ||
| 199 | 210 | these details. |
| 200 | 211 | |
| 201 | 212 | Bus-specific details, like I2C addresses or transfer rates are handled by the |
| 202 | −regmap framework. To get the regulator's regmap (if supported), use :- | |
| 213 | +regmap framework. To get the regulator's regmap (if supported), use:: | |
| 203 | 214 | |
| 204 | −struct regmap *regulator_get_regmap(struct regulator *regulator); | |
| 215 | + struct regmap *regulator_get_regmap(struct regulator *regulator); | |
| 205 | 216 | |
| 206 | 217 | To obtain the hardware register offset and bitmask for the regulator's voltage |
| 207 | −selector register, use :- | |
| 218 | +selector register, use:: | |
| 208 | 219 | |
| 209 | −int regulator_get_hardware_vsel_register(struct regulator *regulator, | |
| 210 | − unsigned *vsel_reg, | |
| 211 | − unsigned *vsel_mask); | |
| 220 | + int regulator_get_hardware_vsel_register(struct regulator *regulator, | |
| 221 | + unsigned *vsel_reg, | |
| 222 | + unsigned *vsel_mask); | |
| 212 | 223 | |
| 213 | 224 | To convert a regulator framework voltage selector code (used by |
| 214 | 225 | regulator_list_voltage) to a hardware-specific voltage selector that can be |
| 215 | −directly written to the voltage selector register, use :- | |
| 226 | +directly written to the voltage selector register, use:: | |
| 216 | 227 | |
| 217 | −int regulator_list_hardware_vsel(struct regulator *regulator, | |
| 218 | − unsigned selector); | |
| 228 | + int regulator_list_hardware_vsel(struct regulator *regulator, | |
| 229 | + unsigned selector); | |
| @@ -1,3 +1,4 @@ | ||
| 1 | +========================== | |
| 1 | 2 | Regulator API design notes |
| 2 | 3 | ========================== |
| 3 | 4 | |
| @@ -14,7 +15,9 @@ Safety · 10 unmodified lines | ||
| 14 | 15 | have different power requirements, and not all components with power |
| 15 | 16 | requirements are visible to software. |
| 16 | 17 | |
| 17 | − => The API should make no changes to the hardware state unless it has | |
| 18 | +.. note:: | |
| 19 | + | |
| 20 | + The API should make no changes to the hardware state unless it has | |
| 18 | 21 | specific knowledge that these changes are safe to perform on this |
| 19 | 22 | particular system. |
| 20 | 23 | |
| @@ -28,6 +31,8 @@ Consumer use cases · 7 unmodified lines | ||
| 28 | 31 | - Many of the power supplies in the system will be shared between many |
| 29 | 32 | different consumers. |
| 30 | 33 | |
| 31 | − => The consumer API should be structured so that these use cases are | |
| 34 | +.. note:: | |
| 35 | + | |
| 36 | + The consumer API should be structured so that these use cases are | |
| 32 | 37 | very easy to handle and so that consumers will work with shared |
| 33 | 38 | supplies without any additional effort. |
| @@ -1,10 +1,11 @@ | ||
| 1 | +================================== | |
| 1 | 2 | Regulator Machine Driver Interface |
| 2 | −=================================== | |
| 3 | +================================== | |
| 3 | 4 | |
| 4 | 5 | The regulator machine driver interface is intended for board/machine specific |
| 5 | 6 | initialisation code to configure the regulator subsystem. |
| 6 | 7 | |
| 7 | −Consider the following machine :- | |
| 8 | +Consider the following machine:: | |
| 8 | 9 | |
| 9 | 10 | Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V] |
| 10 | 11 | | |
| @@ -13,31 +14,31 @@ Consider the following machine :- · 2 unmodified lines | ||
| 13 | 14 | The drivers for consumers A & B must be mapped to the correct regulator in |
| 14 | 15 | order to control their power supplies. This mapping can be achieved in machine |
| 15 | 16 | initialisation code by creating a struct regulator_consumer_supply for |
| 16 | −each regulator. | |
| 17 | +each regulator:: | |
| 17 | 18 | |
| 18 | −struct regulator_consumer_supply { | |
| 19 | + struct regulator_consumer_supply { | |
| 19 | 20 | const char *dev_name; /* consumer dev_name() */ |
| 20 | 21 | const char *supply; /* consumer supply - e.g. "vcc" */ |
| 21 | −}; | |
| 22 | + }; | |
| 22 | 23 | |
| 23 | −e.g. for the machine above | |
| 24 | +e.g. for the machine above:: | |
| 24 | 25 | |
| 25 | −static struct regulator_consumer_supply regulator1_consumers[] = { | |
| 26 | + static struct regulator_consumer_supply regulator1_consumers[] = { | |
| 26 | 27 | REGULATOR_SUPPLY("Vcc", "consumer B"), |
| 27 | −}; | |
| 28 | + }; | |
| 28 | 29 | |
| 29 | −static struct regulator_consumer_supply regulator2_consumers[] = { | |
| 30 | + static struct regulator_consumer_supply regulator2_consumers[] = { | |
| 30 | 31 | REGULATOR_SUPPLY("Vcc", "consumer A"), |
| 31 | −}; | |
| 32 | + }; | |
| 32 | 33 | |
| 33 | 34 | This maps Regulator-1 to the 'Vcc' supply for Consumer B and maps Regulator-2 |
| 34 | 35 | to the 'Vcc' supply for Consumer A. |
| 35 | 36 | |
| 36 | 37 | Constraints can now be registered by defining a struct regulator_init_data |
| 37 | 38 | for each regulator power domain. This structure also maps the consumers |
| 38 | −to their supply regulators :- | |
| 39 | +to their supply regulators:: | |
| 39 | 40 | |
| 40 | −static struct regulator_init_data regulator1_data = { | |
| 41 | + static struct regulator_init_data regulator1_data = { | |
| 41 | 42 | .constraints = { |
| 42 | 43 | .name = "Regulator-1", |
| 43 | 44 | .min_uV = 3300000, |
| @@ -46,7 +47,7 @@ static struct regulator_init_data regulator1_data = { · 2 unmodified lines | ||
| 46 | 47 | }, |
| 47 | 48 | .num_consumer_supplies = ARRAY_SIZE(regulator1_consumers), |
| 48 | 49 | .consumer_supplies = regulator1_consumers, |
| 49 | −}; | |
| 50 | + }; | |
| 50 | 51 | |
| 51 | 52 | The name field should be set to something that is usefully descriptive |
| 52 | 53 | for the board for configuration of supplies for other regulators and |
| @@ -57,9 +58,9 @@ name is provided then the subsystem will choose one. · 4 unmodified lines | ||
| 57 | 58 | Regulator-1 supplies power to Regulator-2. This relationship must be registered |
| 58 | 59 | with the core so that Regulator-1 is also enabled when Consumer A enables its |
| 59 | 60 | supply (Regulator-2). The supply regulator is set by the supply_regulator |
| 60 | −field below and co:- | |
| 61 | +field below and co:: | |
| 61 | 62 | |
| 62 | −static struct regulator_init_data regulator2_data = { | |
| 63 | + static struct regulator_init_data regulator2_data = { | |
| 63 | 64 | .supply_regulator = "Regulator-1", |
| 64 | 65 | .constraints = { |
| 65 | 66 | .min_uV = 1800000, |
| @@ -69,11 +70,11 @@ static struct regulator_init_data regulator2_data = { · 3 unmodified lines | ||
| 69 | 70 | }, |
| 70 | 71 | .num_consumer_supplies = ARRAY_SIZE(regulator2_consumers), |
| 71 | 72 | .consumer_supplies = regulator2_consumers, |
| 72 | −}; | |
| 73 | + }; | |
| 73 | 74 | |
| 74 | −Finally the regulator devices must be registered in the usual manner. | |
| 75 | +Finally the regulator devices must be registered in the usual manner:: | |
| 75 | 76 | |
| 76 | −static struct platform_device regulator_devices[] = { | |
| 77 | + static struct platform_device regulator_devices[] = { | |
| 77 | 78 | { |
| 78 | 79 | .name = "regulator", |
| 79 | 80 | .id = DCDC_1, |
| @@ -88,9 +89,9 @@ static struct platform_device regulator_devices[] = { · 8 unmodified lines | ||
| 88 | 89 | .platform_data = ®ulator2_data, |
| 89 | 90 | }, |
| 90 | 91 | }, |
| 91 | −}; | |
| 92 | −/* register regulator 1 device */ | |
| 93 | −platform_device_register(®ulator_devices[0]); | |
| 92 | + }; | |
| 93 | + /* register regulator 1 device */ | |
| 94 | + platform_device_register(®ulator_devices[0]); | |
| 94 | 95 | |
| 95 | −/* register regulator 2 device */ | |
| 96 | −platform_device_register(®ulator_devices[1]); | |
| 96 | + /* register regulator 2 device */ | |
| 97 | + platform_device_register(®ulator_devices[1]); | |
| @@ -1,3 +1,4 @@ | ||
| 1 | +============================================= | |
| 1 | 2 | Linux voltage and current regulator framework |
| 2 | 3 | ============================================= |
| 3 | 4 | |
| @@ -13,26 +14,30 @@ regulators (where voltage output is controllable) and current sinks (where · 9 unmodified lines | ||
| 13 | 14 | current limit is controllable). |
| 14 | 15 | |
| 15 | 16 | (C) 2008 Wolfson Microelectronics PLC. |
| 17 | + | |
| 16 | 18 | Author: Liam Girdwood <lrg@slimlogic.co.uk> |
| 17 | 19 | |
| 18 | 20 | |
| 19 | 21 | Nomenclature |
| 20 | 22 | ============ |
| 21 | 23 | |
| 22 | −Some terms used in this document:- | |
| 24 | +Some terms used in this document: | |
| 23 | 25 | |
| 24 | − o Regulator - Electronic device that supplies power to other devices. | |
| 26 | + - Regulator | |
| 27 | + - Electronic device that supplies power to other devices. | |
| 25 | 28 | Most regulators can enable and disable their output while |
| 26 | 29 | some can control their output voltage and or current. |
| 27 | 30 | |
| 28 | 31 | Input Voltage -> Regulator -> Output Voltage |
| 29 | 32 | |
| 30 | 33 | |
| 31 | − o PMIC - Power Management IC. An IC that contains numerous regulators | |
| 32 | − and often contains other subsystems. | |
| 34 | + - PMIC | |
| 35 | + - Power Management IC. An IC that contains numerous | |
| 36 | + regulators and often contains other subsystems. | |
| 33 | 37 | |
| 34 | 38 | |
| 35 | − o Consumer - Electronic device that is supplied power by a regulator. | |
| 39 | + - Consumer | |
| 40 | + - Electronic device that is supplied power by a regulator. | |
| 36 | 41 | Consumers can be classified into two types:- |
| 37 | 42 | |
| 38 | 43 | Static: consumer does not change its supply voltage or |
| @@ -44,46 +49,48 @@ Some terms used in this document:- · 5 unmodified lines | ||
| 44 | 49 | current limit to meet operation demands. |
| 45 | 50 | |
| 46 | 51 | |
| 47 | − o Power Domain - Electronic circuit that is supplied its input power by the | |
| 52 | + - Power Domain | |
| 53 | + - Electronic circuit that is supplied its input power by the | |
| 48 | 54 | output power of a regulator, switch or by another power |
| 49 | 55 | domain. |
| 50 | 56 | |
| 51 | − The supply regulator may be behind a switch(s). i.e. | |
| 57 | + The supply regulator may be behind a switch(s). i.e.:: | |
| 52 | 58 | |
| 53 | − Regulator -+-> Switch-1 -+-> Switch-2 --> [Consumer A] | |
| 54 | − | | | |
| 55 | − | +-> [Consumer B], [Consumer C] | |
| 56 | − | | |
| 57 | − +-> [Consumer D], [Consumer E] | |
| 59 | + Regulator -+-> Switch-1 -+-> Switch-2 --> [Consumer A] | |
| 60 | + | | | |
| 61 | + | +-> [Consumer B], [Consumer C] | |
| 62 | + | | |
| 63 | + +-> [Consumer D], [Consumer E] | |
| 58 | 64 | |
| 59 | 65 | That is one regulator and three power domains: |
| 60 | 66 | |
| 61 | − Domain 1: Switch-1, Consumers D & E. | |
| 62 | − Domain 2: Switch-2, Consumers B & C. | |
| 63 | − Domain 3: Consumer A. | |
| 67 | + - Domain 1: Switch-1, Consumers D & E. | |
| 68 | + - Domain 2: Switch-2, Consumers B & C. | |
| 69 | + - Domain 3: Consumer A. | |
| 64 | 70 | |
| 65 | 71 | and this represents a "supplies" relationship: |
| 66 | 72 | |
| 67 | 73 | Domain-1 --> Domain-2 --> Domain-3. |
| 68 | 74 | |
| 69 | 75 | A power domain may have regulators that are supplied power |
| 70 | − by other regulators. i.e. | |
| 76 | + by other regulators. i.e.:: | |
| 71 | 77 | |
| 72 | − Regulator-1 -+-> Regulator-2 -+-> [Consumer A] | |
| 73 | − | | |
| 74 | − +-> [Consumer B] | |
| 78 | + Regulator-1 -+-> Regulator-2 -+-> [Consumer A] | |
| 79 | + | | |
| 80 | + +-> [Consumer B] | |
| 75 | 81 | |
| 76 | 82 | This gives us two regulators and two power domains: |
| 77 | 83 | |
| 78 | − Domain 1: Regulator-2, Consumer B. | |
| 79 | − Domain 2: Consumer A. | |
| 84 | + - Domain 1: Regulator-2, Consumer B. | |
| 85 | + - Domain 2: Consumer A. | |
| 80 | 86 | |
| 81 | 87 | and a "supplies" relationship: |
| 82 | 88 | |
| 83 | 89 | Domain-1 --> Domain-2 |
| 84 | 90 | |
| 85 | 91 | |
| 86 | − o Constraints - Constraints are used to define power levels for performance | |
| 92 | + - Constraints | |
| 93 | + - Constraints are used to define power levels for performance | |
| 87 | 94 | and hardware protection. Constraints exist at three levels: |
| 88 | 95 | |
| 89 | 96 | 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:- · 51 unmodified lines | ||
| 141 | 148 | limit. This also compiles out if not in use so drivers can be reused in |
| 142 | 149 | systems with no regulator based power control. |
| 143 | 150 | |
| 144 | − See Documentation/power/regulator/consumer.txt | |
| 151 | + See Documentation/power/regulator/consumer.rst | |
| 145 | 152 | |
| 146 | 153 | 2. Regulator driver interface. |
| 147 | 154 | |
| @@ -149,7 +156,7 @@ relevant to non SoC devices and is split into the following four interfaces:- · 1 unmodified line | ||
| 149 | 156 | operations to the core. It also has a notifier call chain for propagating |
| 150 | 157 | regulator events to clients. |
| 151 | 158 | |
| 152 | − See Documentation/power/regulator/regulator.txt | |
| 159 | + See Documentation/power/regulator/regulator.rst | |
| 153 | 160 | |
| 154 | 161 | 3. Machine interface. |
| 155 | 162 | |
| @@ -160,7 +167,7 @@ relevant to non SoC devices and is split into the following four interfaces:- · 4 unmodified lines | ||
| 160 | 167 | allows the creation of a regulator tree whereby some regulators are |
| 161 | 168 | supplied by others (similar to a clock tree). |
| 162 | 169 | |
| 163 | − See Documentation/power/regulator/machine.txt | |
| 170 | + See Documentation/power/regulator/machine.rst | |
| 164 | 171 | |
| 165 | 172 | 4. Userspace ABI. |
| 166 | 173 | |
| @@ -0,0 +1,32 @@ | ||
| 1 | +========================== | |
| 2 | +Regulator Driver Interface | |
| 3 | +========================== | |
| 4 | + | |
| 5 | +The regulator driver interface is relatively simple and designed to allow | |
| 6 | +regulator drivers to register their services with the core framework. | |
| 7 | + | |
| 8 | + | |
| 9 | +Registration | |
| 10 | +============ | |
| 11 | + | |
| 12 | +Drivers can register a regulator by calling:: | |
| 13 | + | |
| 14 | + struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |
| 15 | + const struct regulator_config *config); | |
| 16 | + | |
| 17 | +This will register the regulator's capabilities and operations to the regulator | |
| 18 | +core. | |
| 19 | + | |
| 20 | +Regulators can be unregistered by calling:: | |
| 21 | + | |
| 22 | + void regulator_unregister(struct regulator_dev *rdev); | |
| 23 | + | |
| 24 | + | |
| 25 | +Regulator Events | |
| 26 | +================ | |
| 27 | + | |
| 28 | +Regulators can send events (e.g. overtemperature, undervoltage, etc) to | |
| 29 | +consumer drivers by calling:: | |
| 30 | + | |
| 31 | + int regulator_notifier_call_chain(struct regulator_dev *rdev, | |
| 32 | + unsigned long event, void *data); | |
| @@ -1,30 +0,0 @@ | ||
| 1 | −Regulator Driver Interface | |
| 2 | −========================== | |
| 3 | − | |
| 4 | −The regulator driver interface is relatively simple and designed to allow | |
| 5 | −regulator drivers to register their services with the core framework. | |
| 6 | − | |
| 7 | − | |
| 8 | −Registration | |
| 9 | −============ | |
| 10 | − | |
| 11 | −Drivers can register a regulator by calling :- | |
| 12 | − | |
| 13 | −struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |
| 14 | − const struct regulator_config *config); | |
| 15 | − | |
| 16 | −This will register the regulator's capabilities and operations to the regulator | |
| 17 | −core. | |
| 18 | − | |
| 19 | −Regulators can be unregistered by calling :- | |
| 20 | − | |
| 21 | −void regulator_unregister(struct regulator_dev *rdev); | |
| 22 | − | |
| 23 | − | |
| 24 | −Regulator Events | |
| 25 | −================ | |
| 26 | −Regulators can send events (e.g. overtemperature, undervoltage, etc) to | |
| 27 | −consumer drivers by calling :- | |
| 28 | − | |
| 29 | −int regulator_notifier_call_chain(struct regulator_dev *rdev, | |
| 30 | − unsigned long event, void *data); | |
| @@ -1,10 +1,15 @@ | ||
| 1 | +================================================== | |
| 1 | 2 | Runtime Power Management Framework for I/O Devices |
| 3 | +================================================== | |
| 2 | 4 | |
| 3 | 5 | (C) 2009-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. |
| 6 | + | |
| 4 | 7 | (C) 2010 Alan Stern <stern@rowland.harvard.edu> |
| 8 | + | |
| 5 | 9 | (C) 2014 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| 6 | 10 | |
| 7 | 11 | 1. Introduction |
| 12 | +=============== | |
| 8 | 13 | |
| 9 | 14 | Support for runtime power management (runtime PM) of I/O devices is provided |
| 10 | 15 | at the power management core (PM core) level by means of: |
| @@ -33,16 +38,17 @@ fields of 'struct dev_pm_info' and the core helper functions provided for · 22 unmodified lines | ||
| 33 | 38 | runtime PM are described below. |
| 34 | 39 | |
| 35 | 40 | 2. Device Runtime PM Callbacks |
| 41 | +============================== | |
| 36 | 42 | |
| 37 | −There are three device runtime PM callbacks defined in 'struct dev_pm_ops': | |
| 43 | +There are three device runtime PM callbacks defined in 'struct dev_pm_ops':: | |
| 38 | 44 | |
| 39 | −struct dev_pm_ops { | |
| 45 | + struct dev_pm_ops { | |
| 40 | 46 | ... |
| 41 | 47 | int (*runtime_suspend)(struct device *dev); |
| 42 | 48 | int (*runtime_resume)(struct device *dev); |
| 43 | 49 | int (*runtime_idle)(struct device *dev); |
| 44 | 50 | ... |
| 45 | −}; | |
| 51 | + }; | |
| 46 | 52 | |
| 47 | 53 | The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks |
| 48 | 54 | are executed by the PM core for the device's subsystem that may be either of |
| @@ -112,7 +118,7 @@ low-power state during the execution of the suspend callback, it is expected · 63 unmodified lines | ||
| 112 | 118 | that remote wakeup will be enabled for the device. Generally, remote wakeup |
| 113 | 119 | should be enabled for all input devices put into low-power states at run time. |
| 114 | 120 | |
| 115 | −The subsystem-level resume callback, if present, is _entirely_ _responsible_ for | |
| 121 | +The subsystem-level resume callback, if present, is **entirely responsible** for | |
| 116 | 122 | handling the resume of the device as appropriate, which may, but need not |
| 117 | 123 | include executing the device driver's own ->runtime_resume() callback (from the |
| 118 | 124 | PM core's point of view it is not necessary to implement a ->runtime_resume() |
| @@ -197,95 +203,96 @@ rules: · 78 unmodified lines | ||
| 197 | 203 | except for scheduled autosuspends. |
| 198 | 204 | |
| 199 | 205 | 3. Runtime PM Device Fields |
| 206 | +=========================== | |
| 200 | 207 | |
| 201 | 208 | The following device runtime PM fields are present in 'struct dev_pm_info', as |
| 202 | 209 | defined in include/linux/pm.h: |
| 203 | 210 | |
| 204 | − struct timer_list suspend_timer; | |
| 211 | + `struct timer_list suspend_timer;` | |
| 205 | 212 | - timer used for scheduling (delayed) suspend and autosuspend requests |
| 206 | 213 | |
| 207 | − unsigned long timer_expires; | |
| 214 | + `unsigned long timer_expires;` | |
| 208 | 215 | - timer expiration time, in jiffies (if this is different from zero, the |
| 209 | 216 | timer is running and will expire at that time, otherwise the timer is not |
| 210 | 217 | running) |
| 211 | 218 | |
| 212 | − struct work_struct work; | |
| 219 | + `struct work_struct work;` | |
| 213 | 220 | - work structure used for queuing up requests (i.e. work items in pm_wq) |
| 214 | 221 | |
| 215 | − wait_queue_head_t wait_queue; | |
| 222 | + `wait_queue_head_t wait_queue;` | |
| 216 | 223 | - wait queue used if any of the helper functions needs to wait for another |
| 217 | 224 | one to complete |
| 218 | 225 | |
| 219 | − spinlock_t lock; | |
| 226 | + `spinlock_t lock;` | |
| 220 | 227 | - lock used for synchronization |
| 221 | 228 | |
| 222 | − atomic_t usage_count; | |
| 229 | + `atomic_t usage_count;` | |
| 223 | 230 | - the usage counter of the device |
| 224 | 231 | |
| 225 | − atomic_t child_count; | |
| 232 | + `atomic_t child_count;` | |
| 226 | 233 | - the count of 'active' children of the device |
| 227 | 234 | |
| 228 | − unsigned int ignore_children; | |
| 235 | + `unsigned int ignore_children;` | |
| 229 | 236 | - if set, the value of child_count is ignored (but still updated) |
| 230 | 237 | |
| 231 | − unsigned int disable_depth; | |
| 238 | + `unsigned int disable_depth;` | |
| 232 | 239 | - used for disabling the helper functions (they work normally if this is |
| 233 | 240 | equal to zero); the initial value of it is 1 (i.e. runtime PM is |
| 234 | 241 | initially disabled for all devices) |
| 235 | 242 | |
| 236 | − int runtime_error; | |
| 243 | + `int runtime_error;` | |
| 237 | 244 | - if set, there was a fatal error (one of the callbacks returned error code |
| 238 | 245 | as described in Section 2), so the helper functions will not work until |
| 239 | 246 | this flag is cleared; this is the error code returned by the failing |
| 240 | 247 | callback |
| 241 | 248 | |
| 242 | − unsigned int idle_notification; | |
| 249 | + `unsigned int idle_notification;` | |
| 243 | 250 | - if set, ->runtime_idle() is being executed |
| 244 | 251 | |
| 245 | − unsigned int request_pending; | |
| 252 | + `unsigned int request_pending;` | |
| 246 | 253 | - if set, there's a pending request (i.e. a work item queued up into pm_wq) |
| 247 | 254 | |
| 248 | − enum rpm_request request; | |
| 255 | + `enum rpm_request request;` | |
| 249 | 256 | - type of request that's pending (valid if request_pending is set) |
| 250 | 257 | |
| 251 | − unsigned int deferred_resume; | |
| 258 | + `unsigned int deferred_resume;` | |
| 252 | 259 | - set if ->runtime_resume() is about to be run while ->runtime_suspend() is |
| 253 | 260 | being executed for that device and it is not practical to wait for the |
| 254 | 261 | suspend to complete; means "start a resume as soon as you've suspended" |
| 255 | 262 | |
| 256 | − enum rpm_status runtime_status; | |
| 263 | + `enum rpm_status runtime_status;` | |
| 257 | 264 | - the runtime PM status of the device; this field's initial value is |
| 258 | 265 | RPM_SUSPENDED, which means that each device is initially regarded by the |
| 259 | 266 | PM core as 'suspended', regardless of its real hardware status |
| 260 | 267 | |
| 261 | − unsigned int runtime_auto; | |
| 268 | + `unsigned int runtime_auto;` | |
| 262 | 269 | - if set, indicates that the user space has allowed the device driver to |
| 263 | 270 | power manage the device at run time via the /sys/devices/.../power/control |
| 264 | − interface; it may only be modified with the help of the pm_runtime_allow() | |
| 271 | + `interface;` it may only be modified with the help of the pm_runtime_allow() | |
| 265 | 272 | and pm_runtime_forbid() helper functions |
| 266 | 273 | |
| 267 | − unsigned int no_callbacks; | |
| 274 | + `unsigned int no_callbacks;` | |
| 268 | 275 | - indicates that the device does not use the runtime PM callbacks (see |
| 269 | 276 | Section 8); it may be modified only by the pm_runtime_no_callbacks() |
| 270 | 277 | helper function |
| 271 | 278 | |
| 272 | − unsigned int irq_safe; | |
| 279 | + `unsigned int irq_safe;` | |
| 273 | 280 | - indicates that the ->runtime_suspend() and ->runtime_resume() callbacks |
| 274 | 281 | will be invoked with the spinlock held and interrupts disabled |
| 275 | 282 | |
| 276 | − unsigned int use_autosuspend; | |
| 283 | + `unsigned int use_autosuspend;` | |
| 277 | 284 | - indicates that the device's driver supports delayed autosuspend (see |
| 278 | 285 | Section 9); it may be modified only by the |
| 279 | 286 | pm_runtime{_dont}_use_autosuspend() helper functions |
| 280 | 287 | |
| 281 | − unsigned int timer_autosuspends; | |
| 288 | + `unsigned int timer_autosuspends;` | |
| 282 | 289 | - indicates that the PM core should attempt to carry out an autosuspend |
| 283 | 290 | when the timer expires rather than a normal suspend |
| 284 | 291 | |
| 285 | − int autosuspend_delay; | |
| 292 | + `int autosuspend_delay;` | |
| 286 | 293 | - the delay time (in milliseconds) to be used for autosuspend |
| 287 | 294 | |
| 288 | − unsigned long last_busy; | |
| 295 | + `unsigned long last_busy;` | |
| 289 | 296 | - the time (in jiffies) when the pm_runtime_mark_last_busy() helper |
| 290 | 297 | function was last called for this device; used in calculating inactivity |
| 291 | 298 | periods for autosuspend |
| @@ -293,37 +300,38 @@ defined in include/linux/pm.h: · 1 unmodified line | ||
| 293 | 300 | All of the above fields are members of the 'power' member of 'struct device'. |
| 294 | 301 | |
| 295 | 302 | 4. Runtime PM Device Helper Functions |
| 303 | +===================================== | |
| 296 | 304 | |
| 297 | 305 | The following runtime PM helper functions are defined in |
| 298 | 306 | drivers/base/power/runtime.c and include/linux/pm_runtime.h: |
| 299 | 307 | |
| 300 | − void pm_runtime_init(struct device *dev); | |
| 308 | + `void pm_runtime_init(struct device *dev);` | |
| 301 | 309 | - initialize the device runtime PM fields in 'struct dev_pm_info' |
| 302 | 310 | |
| 303 | − void pm_runtime_remove(struct device *dev); | |
| 311 | + `void pm_runtime_remove(struct device *dev);` | |
| 304 | 312 | - make sure that the runtime PM of the device will be disabled after |
| 305 | 313 | removing the device from device hierarchy |
| 306 | 314 | |
| 307 | − int pm_runtime_idle(struct device *dev); | |
| 315 | + `int pm_runtime_idle(struct device *dev);` | |
| 308 | 316 | - execute the subsystem-level idle callback for the device; returns an |
| 309 | 317 | error code on failure, where -EINPROGRESS means that ->runtime_idle() is |
| 310 | 318 | already being executed; if there is no callback or the callback returns 0 |
| 311 | 319 | then run pm_runtime_autosuspend(dev) and return its result |
| 312 | 320 | |
| 313 | − int pm_runtime_suspend(struct device *dev); | |
| 321 | + `int pm_runtime_suspend(struct device *dev);` | |
| 314 | 322 | - execute the subsystem-level suspend callback for the device; returns 0 on |
| 315 | 323 | success, 1 if the device's runtime PM status was already 'suspended', or |
| 316 | 324 | error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt |
| 317 | 325 | to suspend the device again in future and -EACCES means that |
| 318 | 326 | 'power.disable_depth' is different from 0 |
| 319 | 327 | |
| 320 | − int pm_runtime_autosuspend(struct device *dev); | |
| 328 | + `int pm_runtime_autosuspend(struct device *dev);` | |
| 321 | 329 | - same as pm_runtime_suspend() except that the autosuspend delay is taken |
| 322 | − into account; if pm_runtime_autosuspend_expiration() says the delay has | |
| 330 | + `into account;` if pm_runtime_autosuspend_expiration() says the delay has | |
| 323 | 331 | not yet expired then an autosuspend is scheduled for the appropriate time |
| 324 | 332 | and 0 is returned |
| 325 | 333 | |
| 326 | − int pm_runtime_resume(struct device *dev); | |
| 334 | + `int pm_runtime_resume(struct device *dev);` | |
| 327 | 335 | - execute the subsystem-level resume callback for the device; returns 0 on |
| 328 | 336 | success, 1 if the device's runtime PM status was already 'active' or |
| 329 | 337 | error code on failure, where -EAGAIN means it may be safe to attempt to |
| @@ -331,17 +339,17 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: · 1 unmodified line | ||
| 331 | 339 | checked additionally, and -EACCES means that 'power.disable_depth' is |
| 332 | 340 | different from 0 |
| 333 | 341 | |
| 334 | − int pm_request_idle(struct device *dev); | |
| 342 | + `int pm_request_idle(struct device *dev);` | |
| 335 | 343 | - submit a request to execute the subsystem-level idle callback for the |
| 336 | 344 | device (the request is represented by a work item in pm_wq); returns 0 on |
| 337 | 345 | success or error code if the request has not been queued up |
| 338 | 346 | |
| 339 | − int pm_request_autosuspend(struct device *dev); | |
| 347 | + `int pm_request_autosuspend(struct device *dev);` | |
| 340 | 348 | - schedule the execution of the subsystem-level suspend callback for the |
| 341 | 349 | device when the autosuspend delay has expired; if the delay has already |
| 342 | 350 | expired then the work item is queued up immediately |
| 343 | 351 | |
| 344 | − int pm_schedule_suspend(struct device *dev, unsigned int delay); | |
| 352 | + `int pm_schedule_suspend(struct device *dev, unsigned int delay);` | |
| 345 | 353 | - schedule the execution of the subsystem-level suspend callback for the |
| 346 | 354 | device in future, where 'delay' is the time to wait before queuing up a |
| 347 | 355 | suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work |
| @@ -351,58 +359,58 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: · 3 unmodified lines | ||
| 351 | 359 | ->runtime_suspend() is already scheduled and not yet expired, the new |
| 352 | 360 | value of 'delay' will be used as the time to wait |
| 353 | 361 | |
| 354 | − int pm_request_resume(struct device *dev); | |
| 362 | + `int pm_request_resume(struct device *dev);` | |
| 355 | 363 | - submit a request to execute the subsystem-level resume callback for the |
| 356 | 364 | device (the request is represented by a work item in pm_wq); returns 0 on |
| 357 | 365 | success, 1 if the device's runtime PM status was already 'active', or |
| 358 | 366 | error code if the request hasn't been queued up |
| 359 | 367 | |
| 360 | − void pm_runtime_get_noresume(struct device *dev); | |
| 368 | + `void pm_runtime_get_noresume(struct device *dev);` | |
| 361 | 369 | - increment the device's usage counter |
| 362 | 370 | |
| 363 | − int pm_runtime_get(struct device *dev); | |
| 371 | + `int pm_runtime_get(struct device *dev);` | |
| 364 | 372 | - increment the device's usage counter, run pm_request_resume(dev) and |
| 365 | 373 | return its result |
| 366 | 374 | |
| 367 | − int pm_runtime_get_sync(struct device *dev); | |
| 375 | + `int pm_runtime_get_sync(struct device *dev);` | |
| 368 | 376 | - increment the device's usage counter, run pm_runtime_resume(dev) and |
| 369 | 377 | return its result |
| 370 | 378 | |
| 371 | − int pm_runtime_get_if_in_use(struct device *dev); | |
| 379 | + `int pm_runtime_get_if_in_use(struct device *dev);` | |
| 372 | 380 | - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the |
| 373 | 381 | runtime PM status is RPM_ACTIVE and the runtime PM usage counter is |
| 374 | 382 | nonzero, increment the counter and return 1; otherwise return 0 without |
| 375 | 383 | changing the counter |
| 376 | 384 | |
| 377 | − void pm_runtime_put_noidle(struct device *dev); | |
| 385 | + `void pm_runtime_put_noidle(struct device *dev);` | |
| 378 | 386 | - decrement the device's usage counter |
| 379 | 387 | |
| 380 | − int pm_runtime_put(struct device *dev); | |
| 388 | + `int pm_runtime_put(struct device *dev);` | |
| 381 | 389 | - decrement the device's usage counter; if the result is 0 then run |
| 382 | 390 | pm_request_idle(dev) and return its result |
| 383 | 391 | |
| 384 | − int pm_runtime_put_autosuspend(struct device *dev); | |
| 392 | + `int pm_runtime_put_autosuspend(struct device *dev);` | |
| 385 | 393 | - decrement the device's usage counter; if the result is 0 then run |
| 386 | 394 | pm_request_autosuspend(dev) and return its result |
| 387 | 395 | |
| 388 | − int pm_runtime_put_sync(struct device *dev); | |
| 396 | + `int pm_runtime_put_sync(struct device *dev);` | |
| 389 | 397 | - decrement the device's usage counter; if the result is 0 then run |
| 390 | 398 | pm_runtime_idle(dev) and return its result |
| 391 | 399 | |
| 392 | − int pm_runtime_put_sync_suspend(struct device *dev); | |
| 400 | + `int pm_runtime_put_sync_suspend(struct device *dev);` | |
| 393 | 401 | - decrement the device's usage counter; if the result is 0 then run |
| 394 | 402 | pm_runtime_suspend(dev) and return its result |
| 395 | 403 | |
| 396 | − int pm_runtime_put_sync_autosuspend(struct device *dev); | |
| 404 | + `int pm_runtime_put_sync_autosuspend(struct device *dev);` | |
| 397 | 405 | - decrement the device's usage counter; if the result is 0 then run |
| 398 | 406 | pm_runtime_autosuspend(dev) and return its result |
| 399 | 407 | |
| 400 | − void pm_runtime_enable(struct device *dev); | |
| 408 | + `void pm_runtime_enable(struct device *dev);` | |
| 401 | 409 | - decrement the device's 'power.disable_depth' field; if that field is equal |
| 402 | 410 | to zero, the runtime PM helper functions can execute subsystem-level |
| 403 | 411 | callbacks described in Section 2 for the device |
| 404 | 412 | |
| 405 | − int pm_runtime_disable(struct device *dev); | |
| 413 | + `int pm_runtime_disable(struct device *dev);` | |
| 406 | 414 | - increment the device's 'power.disable_depth' field (if the value of that |
| 407 | 415 | field was previously zero, this prevents subsystem-level runtime PM |
| 408 | 416 | callbacks from being run for the device), make sure that all of the |
| @@ -411,7 +419,7 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: · 2 unmodified lines | ||
| 411 | 419 | necessary to execute the subsystem-level resume callback for the device |
| 412 | 420 | to satisfy that request, otherwise 0 is returned |
| 413 | 421 | |
| 414 | − int pm_runtime_barrier(struct device *dev); | |
| 422 | + `int pm_runtime_barrier(struct device *dev);` | |
| 415 | 423 | - check if there's a resume request pending for the device and resume it |
| 416 | 424 | (synchronously) in that case, cancel any other pending runtime PM requests |
| 417 | 425 | regarding it and wait for all runtime PM operations on it in progress to |
| @@ -419,10 +427,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: · 1 unmodified line | ||
| 419 | 427 | necessary to execute the subsystem-level resume callback for the device to |
| 420 | 428 | satisfy that request, otherwise 0 is returned |
| 421 | 429 | |
| 422 | − void pm_suspend_ignore_children(struct device *dev, bool enable); | |
| 430 | + `void pm_suspend_ignore_children(struct device *dev, bool enable);` | |
| 423 | 431 | - set/unset the power.ignore_children flag of the device |
| 424 | 432 | |
| 425 | − int pm_runtime_set_active(struct device *dev); | |
| 433 | + `int pm_runtime_set_active(struct device *dev);` | |
| 426 | 434 | - clear the device's 'power.runtime_error' flag, set the device's runtime |
| 427 | 435 | PM status to 'active' and update its parent's counter of 'active' |
| 428 | 436 | children as appropriate (it is only valid to use this function if |
| @@ -430,61 +438,61 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: · 1 unmodified line | ||
| 430 | 438 | zero); it will fail and return error code if the device has a parent |
| 431 | 439 | which is not active and the 'power.ignore_children' flag of which is unset |
| 432 | 440 | |
| 433 | − void pm_runtime_set_suspended(struct device *dev); | |
| 441 | + `void pm_runtime_set_suspended(struct device *dev);` | |
| 434 | 442 | - clear the device's 'power.runtime_error' flag, set the device's runtime |
| 435 | 443 | PM status to 'suspended' and update its parent's counter of 'active' |
| 436 | 444 | children as appropriate (it is only valid to use this function if |
| 437 | 445 | 'power.runtime_error' is set or 'power.disable_depth' is greater than |
| 438 | 446 | zero) |
| 439 | 447 | |
| 440 | − bool pm_runtime_active(struct device *dev); | |
| 448 | + `bool pm_runtime_active(struct device *dev);` | |
| 441 | 449 | - return true if the device's runtime PM status is 'active' or its |
| 442 | 450 | 'power.disable_depth' field is not equal to zero, or false otherwise |
| 443 | 451 | |
| 444 | − bool pm_runtime_suspended(struct device *dev); | |
| 452 | + `bool pm_runtime_suspended(struct device *dev);` | |
| 445 | 453 | - return true if the device's runtime PM status is 'suspended' and its |
| 446 | 454 | 'power.disable_depth' field is equal to zero, or false otherwise |
| 447 | 455 | |
| 448 | − bool pm_runtime_status_suspended(struct device *dev); | |
| 456 | + `bool pm_runtime_status_suspended(struct device *dev);` | |
| 449 | 457 | - return true if the device's runtime PM status is 'suspended' |
| 450 | 458 | |
| 451 | − void pm_runtime_allow(struct device *dev); | |
| 459 | + `void pm_runtime_allow(struct device *dev);` | |
| 452 | 460 | - set the power.runtime_auto flag for the device and decrease its usage |
| 453 | 461 | counter (used by the /sys/devices/.../power/control interface to |
| 454 | 462 | effectively allow the device to be power managed at run time) |
| 455 | 463 | |
| 456 | − void pm_runtime_forbid(struct device *dev); | |
| 464 | + `void pm_runtime_forbid(struct device *dev);` | |
| 457 | 465 | - unset the power.runtime_auto flag for the device and increase its usage |
| 458 | 466 | counter (used by the /sys/devices/.../power/control interface to |
| 459 | 467 | effectively prevent the device from being power managed at run time) |
| 460 | 468 | |
| 461 | − void pm_runtime_no_callbacks(struct device *dev); | |
| 469 | + `void pm_runtime_no_callbacks(struct device *dev);` | |
| 462 | 470 | - set the power.no_callbacks flag for the device and remove the runtime |
| 463 | 471 | PM attributes from /sys/devices/.../power (or prevent them from being |
| 464 | 472 | added when the device is registered) |
| 465 | 473 | |
| 466 | − void pm_runtime_irq_safe(struct device *dev); | |
| 474 | + `void pm_runtime_irq_safe(struct device *dev);` | |
| 467 | 475 | - set the power.irq_safe flag for the device, causing the runtime-PM |
| 468 | 476 | callbacks to be invoked with interrupts off |
| 469 | 477 | |
| 470 | − bool pm_runtime_is_irq_safe(struct device *dev); | |
| 478 | + `bool pm_runtime_is_irq_safe(struct device *dev);` | |
| 471 | 479 | - return true if power.irq_safe flag was set for the device, causing |
| 472 | 480 | the runtime-PM callbacks to be invoked with interrupts off |
| 473 | 481 | |
| 474 | − void pm_runtime_mark_last_busy(struct device *dev); | |
| 482 | + `void pm_runtime_mark_last_busy(struct device *dev);` | |
| 475 | 483 | - set the power.last_busy field to the current time |
| 476 | 484 | |
| 477 | − void pm_runtime_use_autosuspend(struct device *dev); | |
| 485 | + `void pm_runtime_use_autosuspend(struct device *dev);` | |
| 478 | 486 | - set the power.use_autosuspend flag, enabling autosuspend delays; call |
| 479 | 487 | pm_runtime_get_sync if the flag was previously cleared and |
| 480 | 488 | power.autosuspend_delay is negative |
| 481 | 489 | |
| 482 | − void pm_runtime_dont_use_autosuspend(struct device *dev); | |
| 490 | + `void pm_runtime_dont_use_autosuspend(struct device *dev);` | |
| 483 | 491 | - clear the power.use_autosuspend flag, disabling autosuspend delays; |
| 484 | 492 | decrement the device's usage counter if the flag was previously set and |
| 485 | 493 | power.autosuspend_delay is negative; call pm_runtime_idle |
| 486 | 494 | |
| 487 | − void pm_runtime_set_autosuspend_delay(struct device *dev, int delay); | |
| 495 | + `void pm_runtime_set_autosuspend_delay(struct device *dev, int delay);` | |
| 488 | 496 | - set the power.autosuspend_delay value to 'delay' (expressed in |
| 489 | 497 | milliseconds); if 'delay' is negative then runtime suspends are |
| 490 | 498 | prevented; if power.use_autosuspend is set, pm_runtime_get_sync may be |
| @@ -493,7 +501,7 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: · 2 unmodified lines | ||
| 493 | 501 | changed to or from a negative value; if power.use_autosuspend is clear, |
| 494 | 502 | pm_runtime_idle is called |
| 495 | 503 | |
| 496 | − unsigned long pm_runtime_autosuspend_expiration(struct device *dev); | |
| 504 | + `unsigned long pm_runtime_autosuspend_expiration(struct device *dev);` | |
| 497 | 505 | - calculate the time when the current autosuspend delay period will expire, |
| 498 | 506 | based on power.last_busy and power.autosuspend_delay; if the delay time |
| 499 | 507 | is 1000 ms or larger then the expiration time is rounded up to the |
| @@ -503,36 +511,37 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: · 3 unmodified lines | ||
| 503 | 511 | |
| 504 | 512 | It is safe to execute the following helper functions from interrupt context: |
| 505 | 513 | |
| 506 | −pm_request_idle() | |
| 507 | −pm_request_autosuspend() | |
| 508 | −pm_schedule_suspend() | |
| 509 | −pm_request_resume() | |
| 510 | −pm_runtime_get_noresume() | |
| 511 | −pm_runtime_get() | |
| 512 | −pm_runtime_put_noidle() | |
| 513 | −pm_runtime_put() | |
| 514 | −pm_runtime_put_autosuspend() | |
| 515 | −pm_runtime_enable() | |
| 516 | −pm_suspend_ignore_children() | |
| 517 | −pm_runtime_set_active() | |
| 518 | −pm_runtime_set_suspended() | |
| 519 | −pm_runtime_suspended() | |
| 520 | −pm_runtime_mark_last_busy() | |
| 521 | −pm_runtime_autosuspend_expiration() | |
| 514 | +- pm_request_idle() | |
| 515 | +- pm_request_autosuspend() | |
| 516 | +- pm_schedule_suspend() | |
| 517 | +- pm_request_resume() | |
| 518 | +- pm_runtime_get_noresume() | |
| 519 | +- pm_runtime_get() | |
| 520 | +- pm_runtime_put_noidle() | |
| 521 | +- pm_runtime_put() | |
| 522 | +- pm_runtime_put_autosuspend() | |
| 523 | +- pm_runtime_enable() | |
| 524 | +- pm_suspend_ignore_children() | |
| 525 | +- pm_runtime_set_active() | |
| 526 | +- pm_runtime_set_suspended() | |
| 527 | +- pm_runtime_suspended() | |
| 528 | +- pm_runtime_mark_last_busy() | |
| 529 | +- pm_runtime_autosuspend_expiration() | |
| 522 | 530 | |
| 523 | 531 | If pm_runtime_irq_safe() has been called for a device then the following helper |
| 524 | 532 | functions may also be used in interrupt context: |
| 525 | 533 | |
| 526 | −pm_runtime_idle() | |
| 527 | −pm_runtime_suspend() | |
| 528 | −pm_runtime_autosuspend() | |
| 529 | −pm_runtime_resume() | |
| 530 | −pm_runtime_get_sync() | |
| 531 | −pm_runtime_put_sync() | |
| 532 | −pm_runtime_put_sync_suspend() | |
| 533 | −pm_runtime_put_sync_autosuspend() | |
| 534 | +- pm_runtime_idle() | |
| 535 | +- pm_runtime_suspend() | |
| 536 | +- pm_runtime_autosuspend() | |
| 537 | +- pm_runtime_resume() | |
| 538 | +- pm_runtime_get_sync() | |
| 539 | +- pm_runtime_put_sync() | |
| 540 | +- pm_runtime_put_sync_suspend() | |
| 541 | +- pm_runtime_put_sync_autosuspend() | |
| 534 | 542 | |
| 535 | 543 | 5. Runtime PM Initialization, Device Probing and Removal |
| 544 | +======================================================== | |
| 536 | 545 | |
| 537 | 546 | Initially, the runtime PM is disabled for all devices, which means that the |
| 538 | 547 | majority of the runtime PM helper functions described in Section 4 will return |
| @@ -608,6 +617,7 @@ manage the device at run time, the driver may confuse it by using · 69 unmodified lines | ||
| 608 | 617 | pm_runtime_forbid() this way. |
| 609 | 618 | |
| 610 | 619 | 6. Runtime PM and System Sleep |
| 620 | +============================== | |
| 611 | 621 | |
| 612 | 622 | Runtime PM and system sleep (i.e., system suspend and hibernation, also known |
| 613 | 623 | as suspend-to-RAM and suspend-to-disk) interact with each other in a couple of |
| @@ -647,9 +657,9 @@ brought back to full power during resume, then its runtime PM status will have · 33 unmodified lines | ||
| 647 | 657 | to be updated to reflect the actual post-system sleep status. The way to do |
| 648 | 658 | this is: |
| 649 | 659 | |
| 650 | − pm_runtime_disable(dev); | |
| 651 | − pm_runtime_set_active(dev); | |
| 652 | − pm_runtime_enable(dev); | |
| 660 | + - pm_runtime_disable(dev); | |
| 661 | + - pm_runtime_set_active(dev); | |
| 662 | + - pm_runtime_enable(dev); | |
| 653 | 663 | |
| 654 | 664 | The PM core always increments the runtime usage counter before calling the |
| 655 | 665 | ->suspend() callback and decrements it after calling the ->resume() callback. |
| @@ -705,66 +715,66 @@ Subsystems may wish to conserve code space by using the set of generic power · 49 unmodified lines | ||
| 705 | 715 | management callbacks provided by the PM core, defined in |
| 706 | 716 | driver/base/power/generic_ops.c: |
| 707 | 717 | |
| 708 | − int pm_generic_runtime_suspend(struct device *dev); | |
| 718 | + `int pm_generic_runtime_suspend(struct device *dev);` | |
| 709 | 719 | - invoke the ->runtime_suspend() callback provided by the driver of this |
| 710 | 720 | device and return its result, or return 0 if not defined |
| 711 | 721 | |
| 712 | − int pm_generic_runtime_resume(struct device *dev); | |
| 722 | + `int pm_generic_runtime_resume(struct device *dev);` | |
| 713 | 723 | - invoke the ->runtime_resume() callback provided by the driver of this |
| 714 | 724 | device and return its result, or return 0 if not defined |
| 715 | 725 | |
| 716 | − int pm_generic_suspend(struct device *dev); | |
| 726 | + `int pm_generic_suspend(struct device *dev);` | |
| 717 | 727 | - if the device has not been suspended at run time, invoke the ->suspend() |
| 718 | 728 | callback provided by its driver and return its result, or return 0 if not |
| 719 | 729 | defined |
| 720 | 730 | |
| 721 | − int pm_generic_suspend_noirq(struct device *dev); | |
| 731 | + `int pm_generic_suspend_noirq(struct device *dev);` | |
| 722 | 732 | - if pm_runtime_suspended(dev) returns "false", invoke the ->suspend_noirq() |
| 723 | 733 | callback provided by the device's driver and return its result, or return |
| 724 | 734 | 0 if not defined |
| 725 | 735 | |
| 726 | − int pm_generic_resume(struct device *dev); | |
| 736 | + `int pm_generic_resume(struct device *dev);` | |
| 727 | 737 | - invoke the ->resume() callback provided by the driver of this device and, |
| 728 | 738 | if successful, change the device's runtime PM status to 'active' |
| 729 | 739 | |
| 730 | − int pm_generic_resume_noirq(struct device *dev); | |
| 740 | + `int pm_generic_resume_noirq(struct device *dev);` | |
| 731 | 741 | - invoke the ->resume_noirq() callback provided by the driver of this device |
| 732 | 742 | |
| 733 | − int pm_generic_freeze(struct device *dev); | |
| 743 | + `int pm_generic_freeze(struct device *dev);` | |
| 734 | 744 | - if the device has not been suspended at run time, invoke the ->freeze() |
| 735 | 745 | callback provided by its driver and return its result, or return 0 if not |
| 736 | 746 | defined |
| 737 | 747 | |
| 738 | − int pm_generic_freeze_noirq(struct device *dev); | |
| 748 | + `int pm_generic_freeze_noirq(struct device *dev);` | |
| 739 | 749 | - if pm_runtime_suspended(dev) returns "false", invoke the ->freeze_noirq() |
| 740 | 750 | callback provided by the device's driver and return its result, or return |
| 741 | 751 | 0 if not defined |
| 742 | 752 | |
| 743 | − int pm_generic_thaw(struct device *dev); | |
| 753 | + `int pm_generic_thaw(struct device *dev);` | |
| 744 | 754 | - if the device has not been suspended at run time, invoke the ->thaw() |
| 745 | 755 | callback provided by its driver and return its result, or return 0 if not |
| 746 | 756 | defined |
| 747 | 757 | |
| 748 | − int pm_generic_thaw_noirq(struct device *dev); | |
| 758 | + `int pm_generic_thaw_noirq(struct device *dev);` | |
| 749 | 759 | - if pm_runtime_suspended(dev) returns "false", invoke the ->thaw_noirq() |
| 750 | 760 | callback provided by the device's driver and return its result, or return |
| 751 | 761 | 0 if not defined |
| 752 | 762 | |
| 753 | − int pm_generic_poweroff(struct device *dev); | |
| 763 | + `int pm_generic_poweroff(struct device *dev);` | |
| 754 | 764 | - if the device has not been suspended at run time, invoke the ->poweroff() |
| 755 | 765 | callback provided by its driver and return its result, or return 0 if not |
| 756 | 766 | defined |
| 757 | 767 | |
| 758 | − int pm_generic_poweroff_noirq(struct device *dev); | |
| 768 | + `int pm_generic_poweroff_noirq(struct device *dev);` | |
| 759 | 769 | - if pm_runtime_suspended(dev) returns "false", run the ->poweroff_noirq() |
| 760 | 770 | callback provided by the device's driver and return its result, or return |
| 761 | 771 | 0 if not defined |
| 762 | 772 | |
| 763 | − int pm_generic_restore(struct device *dev); | |
| 773 | + `int pm_generic_restore(struct device *dev);` | |
| 764 | 774 | - invoke the ->restore() callback provided by the driver of this device and, |
| 765 | 775 | if successful, change the device's runtime PM status to 'active' |
| 766 | 776 | |
| 767 | − int pm_generic_restore_noirq(struct device *dev); | |
| 777 | + `int pm_generic_restore_noirq(struct device *dev);` | |
| 768 | 778 | - invoke the ->restore_noirq() callback provided by the device's driver |
| 769 | 779 | |
| 770 | 780 | These functions are the defaults used by the PM core, if a subsystem doesn't |
| @@ -781,6 +791,7 @@ UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its · 10 unmodified lines | ||
| 781 | 791 | last argument to NULL). |
| 782 | 792 | |
| 783 | 793 | 8. "No-Callback" Devices |
| 794 | +======================== | |
| 784 | 795 | |
| 785 | 796 | Some "devices" are only logical sub-devices of their parent and cannot be |
| 786 | 797 | power-managed on their own. (The prototype example is a USB interface. Entire |
| @@ -807,6 +818,7 @@ parent must take responsibility for telling the device's driver when the · 20 unmodified lines | ||
| 807 | 818 | parent's power state changes. |
| 808 | 819 | |
| 809 | 820 | 9. Autosuspend, or automatically-delayed suspends |
| 821 | +================================================= | |
| 810 | 822 | |
| 811 | 823 | Changing a device's power state isn't free; it requires both time and energy. |
| 812 | 824 | A device should be put in a low-power state only when there's some reason to |
| @@ -832,8 +844,8 @@ registration the length should be controlled by user space, using the · 19 unmodified lines | ||
| 832 | 844 | |
| 833 | 845 | In order to use autosuspend, subsystems or drivers must call |
| 834 | 846 | pm_runtime_use_autosuspend() (preferably before registering the device), and |
| 835 | −thereafter they should use the various *_autosuspend() helper functions instead | |
| 836 | −of the non-autosuspend counterparts: | |
| 847 | +thereafter they should use the various `*_autosuspend()` helper functions | |
| 848 | +instead of the non-autosuspend counterparts:: | |
| 837 | 849 | |
| 838 | 850 | Instead of: pm_runtime_suspend use: pm_runtime_autosuspend; |
| 839 | 851 | Instead of: pm_schedule_suspend use: pm_request_autosuspend; |
| @@ -858,7 +870,7 @@ The implementation is well suited for asynchronous use in interrupt contexts. · 18 unmodified lines | ||
| 858 | 870 | However such use inevitably involves races, because the PM core can't |
| 859 | 871 | synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. |
| 860 | 872 | This synchronization must be handled by the driver, using its private lock. |
| 861 | −Here is a schematic pseudo-code example: | |
| 873 | +Here is a schematic pseudo-code example:: | |
| 862 | 874 | |
| 863 | 875 | foo_read_or_write(struct foo_priv *foo, void *data) |
| 864 | 876 | { |
| @@ -1,7 +1,9 @@ | ||
| 1 | − How to get s2ram working | |
| 2 | − ~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 3 | − 2006 Linus Torvalds | |
| 4 | − 2006 Pavel Machek | |
| 1 | +======================== | |
| 2 | +How to get s2ram working | |
| 3 | +======================== | |
| 4 | + | |
| 5 | +2006 Linus Torvalds | |
| 6 | +2006 Pavel Machek | |
| 5 | 7 | |
| 6 | 8 | 1) Check suspend.sf.net, program s2ram there has long whitelist of |
| 7 | 9 | "known ok" machines, along with tricks to use on each one. |
| @@ -12,8 +14,8 @@ · 4 unmodified lines | ||
| 12 | 14 | |
| 13 | 15 | 3) You can use Linus' TRACE_RESUME infrastructure, described below. |
| 14 | 16 | |
| 15 | − Using TRACE_RESUME | |
| 16 | − ~~~~~~~~~~~~~~~~~~ | |
| 17 | +Using TRACE_RESUME | |
| 18 | +~~~~~~~~~~~~~~~~~~ | |
| 17 | 19 | |
| 18 | 20 | I've been working at making the machines I have able to STR, and almost |
| 19 | 21 | always it's a driver that is buggy. Thank God for the suspend/resume |
| @@ -27,7 +29,7 @@ machine that doesn't boot) is: · 7 unmodified lines | ||
| 27 | 29 | |
| 28 | 30 | - enable PM_DEBUG, and PM_TRACE |
| 29 | 31 | |
| 30 | − - use a script like this: | |
| 32 | + - use a script like this:: | |
| 31 | 33 | |
| 32 | 34 | #!/bin/sh |
| 33 | 35 | sync |
| @@ -38,7 +40,7 @@ machine that doesn't boot) is: · 4 unmodified lines | ||
| 38 | 40 | |
| 39 | 41 | - if it doesn't come back up (which is usually the problem), reboot by |
| 40 | 42 | holding the power button down, and look at the dmesg output for things |
| 41 | − like | |
| 43 | + like:: | |
| 42 | 44 | |
| 43 | 45 | Magic number: 4:156:725 |
| 44 | 46 | hash matches drivers/base/power/resume.c:28 |
| @@ -52,7 +54,7 @@ machine that doesn't boot) is: · 7 unmodified lines | ||
| 52 | 54 | If no device matches the hash (or any matches appear to be false positives), |
| 53 | 55 | the culprit may be a device from a loadable kernel module that is not loaded |
| 54 | 56 | until after the hash is checked. You can check the hash against the current |
| 55 | − devices again after more modules are loaded using sysfs: | |
| 57 | + devices again after more modules are loaded using sysfs:: | |
| 56 | 58 | |
| 57 | 59 | cat /sys/power/pm_trace_dev_match |
| 58 | 60 | |
| @@ -1,10 +1,15 @@ | ||
| 1 | +==================================================================== | |
| 1 | 2 | Interaction of Suspend code (S3) with the CPU hotplug infrastructure |
| 3 | +==================================================================== | |
| 2 | 4 | |
| 3 | − (C) 2011 - 2014 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> | |
| 5 | +(C) 2011 - 2014 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> | |
| 4 | 6 | |
| 5 | 7 | |
| 6 | −I. How does the regular CPU hotplug code differ from how the Suspend-to-RAM | |
| 7 | − infrastructure uses it internally? And where do they share common code? | |
| 8 | +I. Differences between CPU hotplug and Suspend-to-RAM | |
| 9 | +====================================================== | |
| 10 | + | |
| 11 | +How does the regular CPU hotplug code differ from how the Suspend-to-RAM | |
| 12 | +infrastructure uses it internally? And where do they share common code? | |
| 8 | 13 | |
| 9 | 14 | Well, a picture is worth a thousand words... So ASCII art follows :-) |
| 10 | 15 | |
| @@ -16,13 +21,13 @@ of describing where they take different paths and where they share code. · 5 unmodified lines | ||
| 16 | 21 | What happens when regular CPU hotplug and Suspend-to-RAM race with each other |
| 17 | 22 | is not depicted here.] |
| 18 | 23 | |
| 19 | −On a high level, the suspend-resume cycle goes like this: | |
| 24 | +On a high level, the suspend-resume cycle goes like this:: | |
| 20 | 25 | |
| 21 | −|Freeze| -> |Disable nonboot| -> |Do suspend| -> |Enable nonboot| -> |Thaw | | |
| 22 | −|tasks | | cpus | | | | cpus | |tasks| | |
| 26 | + |Freeze| -> |Disable nonboot| -> |Do suspend| -> |Enable nonboot| -> |Thaw | | |
| 27 | + |tasks | | cpus | | | | cpus | |tasks| | |
| 23 | 28 | |
| 24 | 29 | |
| 25 | −More details follow: | |
| 30 | +More details follow:: | |
| 26 | 31 | |
| 27 | 32 | Suspend call path |
| 28 | 33 | ----------------- |
| @@ -87,7 +92,9 @@ More details follow: · 58 unmodified lines | ||
| 87 | 92 | |
| 88 | 93 | Resuming back is likewise, with the counterparts being (in the order of |
| 89 | 94 | execution during resume): |
| 90 | −* enable_nonboot_cpus() which involves: | |
| 95 | + | |
| 96 | +* enable_nonboot_cpus() which involves:: | |
| 97 | + | |
| 91 | 98 | | Acquire cpu_add_remove_lock |
| 92 | 99 | | Decrease cpu_hotplug_disabled, thereby enabling regular cpu hotplug |
| 93 | 100 | | 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 · 9 unmodified lines | ||
| 103 | 110 | beginning, when we are just starting out to suspend, and then released only |
| 104 | 111 | after the entire cycle is complete (i.e., suspend + resume). |
| 105 | 112 | |
| 113 | +:: | |
| 114 | + | |
| 106 | 115 | |
| 107 | 116 | |
| 108 | 117 | Regular CPU hotplug call path |
| @@ -152,16 +161,16 @@ with the 'tasks_frozen' argument set to 1. · 43 unmodified lines | ||
| 152 | 161 | |
| 153 | 162 | |
| 154 | 163 | Important files and functions/entry points: |
| 155 | −------------------------------------------ | |
| 164 | +------------------------------------------- | |
| 156 | 165 | |
| 157 | −kernel/power/process.c : freeze_processes(), thaw_processes() | |
| 158 | −kernel/power/suspend.c : suspend_prepare(), suspend_enter(), suspend_finish() | |
| 159 | −kernel/cpu.c: cpu_[up|down](), _cpu_[up|down](), [disable|enable]_nonboot_cpus() | |
| 166 | +- kernel/power/process.c : freeze_processes(), thaw_processes() | |
| 167 | +- kernel/power/suspend.c : suspend_prepare(), suspend_enter(), suspend_finish() | |
| 168 | +- kernel/cpu.c: cpu_[up|down](), _cpu_[up|down](), [disable|enable]_nonboot_cpus() | |
| 160 | 169 | |
| 161 | 170 | |
| 162 | 171 | |
| 163 | 172 | II. What are the issues involved in CPU hotplug? |
| 164 | − ------------------------------------------- | |
| 173 | +------------------------------------------------ | |
| 165 | 174 | |
| 166 | 175 | There are some interesting situations involving CPU hotplug and microcode |
| 167 | 176 | update on the CPUs, as discussed below: |
| @@ -243,8 +252,11 @@ d. Handling microcode update during suspend/hibernate: · 75 unmodified lines | ||
| 243 | 252 | cycles). |
| 244 | 253 | |
| 245 | 254 | |
| 246 | −III. Are there any known problems when regular CPU hotplug and suspend race | |
| 247 | − with each other? | |
| 255 | +III. Known problems | |
| 256 | +=================== | |
| 257 | + | |
| 258 | +Are there any known problems when regular CPU hotplug and suspend race | |
| 259 | +with each other? | |
| 248 | 260 | |
| 249 | 261 | Yes, they are listed below: |
| 250 | 262 | |
| @@ -1,4 +1,6 @@ | ||
| 1 | +==================================== | |
| 1 | 2 | System Suspend and Device Interrupts |
| 3 | +==================================== | |
| 2 | 4 | |
| 3 | 5 | Copyright (C) 2014 Intel Corp. |
| 4 | 6 | Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| @@ -1,4 +1,7 @@ | ||
| 1 | +=============================================== | |
| 1 | 2 | Using swap files with software suspend (swsusp) |
| 3 | +=============================================== | |
| 4 | + | |
| 2 | 5 | (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> |
| 3 | 6 | |
| 4 | 7 | The Linux kernel handles swap files almost in the same way as it handles swap |
| @@ -21,20 +24,20 @@ units. · 16 unmodified lines | ||
| 21 | 24 | |
| 22 | 25 | In order to use a swap file with swsusp, you need to: |
| 23 | 26 | |
| 24 | −1) Create the swap file and make it active, eg. | |
| 27 | +1) Create the swap file and make it active, eg.:: | |
| 25 | 28 | |
| 26 | −# dd if=/dev/zero of=<swap_file_path> bs=1024 count=<swap_file_size_in_k> | |
| 27 | −# mkswap <swap_file_path> | |
| 28 | −# swapon <swap_file_path> | |
| 29 | + # dd if=/dev/zero of=<swap_file_path> bs=1024 count=<swap_file_size_in_k> | |
| 30 | + # mkswap <swap_file_path> | |
| 31 | + # swapon <swap_file_path> | |
| 29 | 32 | |
| 30 | 33 | 2) Use an application that will bmap the swap file with the help of the |
| 31 | 34 | FIBMAP ioctl and determine the location of the file's swap header, as the |
| 32 | 35 | offset, in <PAGE_SIZE> units, from the beginning of the partition which |
| 33 | 36 | holds the swap file. |
| 34 | 37 | |
| 35 | −3) Add the following parameters to the kernel command line: | |
| 38 | +3) Add the following parameters to the kernel command line:: | |
| 36 | 39 | |
| 37 | −resume=<swap_file_partition> resume_offset=<swap_file_offset> | |
| 40 | + resume=<swap_file_partition> resume_offset=<swap_file_offset> | |
| 38 | 41 | |
| 39 | 42 | where <swap_file_partition> is the partition on which the swap file is located |
| 40 | 43 | and <swap_file_offset> is the offset of the swap header determined by the |
| @@ -46,7 +49,7 @@ OR · 5 unmodified lines | ||
| 46 | 49 | |
| 47 | 50 | Use a userland suspend application that will set the partition and offset |
| 48 | 51 | with the help of the SNAPSHOT_SET_SWAP_AREA ioctl described in |
| 49 | −Documentation/power/userland-swsusp.txt (this is the only method to suspend | |
| 52 | +Documentation/power/userland-swsusp.rst (this is the only method to suspend | |
| 50 | 53 | to a swap file allowing the resume to be initiated from an initrd or initramfs |
| 51 | 54 | image). |
| 52 | 55 | |
| @@ -1,13 +1,15 @@ | ||
| 1 | +======================================= | |
| 2 | +How to use dm-crypt and swsusp together | |
| 3 | +======================================= | |
| 4 | + | |
| 1 | 5 | Author: Andreas Steinmetz <ast@domdv.de> |
| 2 | 6 | |
| 3 | 7 | |
| 4 | −How to use dm-crypt and swsusp together: | |
| 5 | −======================================== | |
| 6 | 8 | |
| 7 | 9 | Some prerequisites: |
| 8 | 10 | You know how dm-crypt works. If not, visit the following web page: |
| 9 | 11 | http://www.saout.de/misc/dm-crypt/ |
| 10 | −You have read Documentation/power/swsusp.txt and understand it. | |
| 12 | +You have read Documentation/power/swsusp.rst and understand it. | |
| 11 | 13 | You did read Documentation/admin-guide/initrd.rst and know how an initrd works. |
| 12 | 14 | You know how to create or how to modify an initrd. |
| 13 | 15 | |
| @@ -29,23 +31,23 @@ a way that the swap device you suspend to/resume from has · 15 unmodified lines | ||
| 29 | 31 | always the same major/minor within the initrd as well as |
| 30 | 32 | within your running system. The easiest way to achieve this is |
| 31 | 33 | to always set up this swap device first with dmsetup, so that |
| 32 | −it will always look like the following: | |
| 34 | +it will always look like the following:: | |
| 33 | 35 | |
| 34 | −brw------- 1 root root 254, 0 Jul 28 13:37 /dev/mapper/swap0 | |
| 36 | + brw------- 1 root root 254, 0 Jul 28 13:37 /dev/mapper/swap0 | |
| 35 | 37 | |
| 36 | 38 | Now set up your kernel to use /dev/mapper/swap0 as the default |
| 37 | −resume partition, so your kernel .config contains: | |
| 39 | +resume partition, so your kernel .config contains:: | |
| 38 | 40 | |
| 39 | −CONFIG_PM_STD_PARTITION="/dev/mapper/swap0" | |
| 41 | + CONFIG_PM_STD_PARTITION="/dev/mapper/swap0" | |
| 40 | 42 | |
| 41 | 43 | Prepare your boot loader to use the initrd you will create or |
| 42 | 44 | modify. For lilo the simplest setup looks like the following |
| 43 | −lines: | |
| 45 | +lines:: | |
| 44 | 46 | |
| 45 | −image=/boot/vmlinuz | |
| 46 | −initrd=/boot/initrd.gz | |
| 47 | −label=linux | |
| 48 | −append="root=/dev/ram0 init=/linuxrc rw" | |
| 47 | + image=/boot/vmlinuz | |
| 48 | + initrd=/boot/initrd.gz | |
| 49 | + label=linux | |
| 50 | + append="root=/dev/ram0 init=/linuxrc rw" | |
| 49 | 51 | |
| 50 | 52 | Finally you need to create or modify your initrd. Lets assume |
| 51 | 53 | you create an initrd that reads the required dm-crypt setup |
| @@ -53,66 +55,66 @@ from a pcmcia flash disk card. The card is formatted with an ext2 · 1 unmodified line | ||
| 53 | 55 | fs which resides on /dev/hde1 when the card is inserted. The |
| 54 | 56 | card contains at least the encrypted swap setup in a file |
| 55 | 57 | named "swapkey". /etc/fstab of your initrd contains something |
| 56 | −like the following: | |
| 58 | +like the following:: | |
| 57 | 59 | |
| 58 | −/dev/hda1 /mnt ext3 ro 0 0 | |
| 59 | −none /proc proc defaults,noatime,nodiratime 0 0 | |
| 60 | −none /sys sysfs defaults,noatime,nodiratime 0 0 | |
| 60 | + /dev/hda1 /mnt ext3 ro 0 0 | |
| 61 | + none /proc proc defaults,noatime,nodiratime 0 0 | |
| 62 | + none /sys sysfs defaults,noatime,nodiratime 0 0 | |
| 61 | 63 | |
| 62 | 64 | /dev/hda1 contains an unencrypted mini system that sets up all |
| 63 | 65 | of your crypto devices, again by reading the setup from the |
| 64 | 66 | pcmcia flash disk. What follows now is a /linuxrc for your |
| 65 | 67 | initrd that allows you to resume from encrypted swap and that |
| 66 | 68 | continues boot with your mini system on /dev/hda1 if resume |
| 67 | −does not happen: | |
| 68 | − | |
| 69 | −#!/bin/sh | |
| 70 | −PATH=/sbin:/bin:/usr/sbin:/usr/bin | |
| 71 | −mount /proc | |
| 72 | −mount /sys | |
| 73 | −mapped=0 | |
| 74 | −noresume=`grep -c noresume /proc/cmdline` | |
| 75 | −if [ "$*" != "" ] | |
| 76 | −then | |
| 77 | − noresume=1 | |
| 78 | −fi | |
| 79 | −dmesg -n 1 | |
| 80 | −/sbin/cardmgr -q | |
| 81 | −for i in 1 2 3 4 5 6 7 8 9 0 | |
| 82 | −do | |
| 83 | − if [ -f /proc/ide/hde/media ] | |
| 69 | +does not happen:: | |
| 70 | + | |
| 71 | + #!/bin/sh | |
| 72 | + PATH=/sbin:/bin:/usr/sbin:/usr/bin | |
| 73 | + mount /proc | |
| 74 | + mount /sys | |
| 75 | + mapped=0 | |
| 76 | + noresume=`grep -c noresume /proc/cmdline` | |
| 77 | + if [ "$*" != "" ] | |
| 84 | 78 | then |
| 85 | − usleep 500000 | |
| 86 | − mount -t ext2 -o ro /dev/hde1 /mnt | |
| 87 | − if [ -f /mnt/swapkey ] | |
| 79 | + noresume=1 | |
| 80 | + fi | |
| 81 | + dmesg -n 1 | |
| 82 | + /sbin/cardmgr -q | |
| 83 | + for i in 1 2 3 4 5 6 7 8 9 0 | |
| 84 | + do | |
| 85 | + if [ -f /proc/ide/hde/media ] | |
| 88 | 86 | then |
| 89 | − dmsetup create swap0 /mnt/swapkey > /dev/null 2>&1 && mapped=1 | |
| 87 | + usleep 500000 | |
| 88 | + mount -t ext2 -o ro /dev/hde1 /mnt | |
| 89 | + if [ -f /mnt/swapkey ] | |
| 90 | + then | |
| 91 | + dmsetup create swap0 /mnt/swapkey > /dev/null 2>&1 && mapped=1 | |
| 92 | + fi | |
| 93 | + umount /mnt | |
| 94 | + break | |
| 90 | 95 | fi |
| 91 | − umount /mnt | |
| 92 | − break | |
| 93 | − fi | |
| 94 | − usleep 500000 | |
| 95 | −done | |
| 96 | −killproc /sbin/cardmgr | |
| 97 | −dmesg -n 6 | |
| 98 | −if [ $mapped = 1 ] | |
| 99 | −then | |
| 100 | − if [ $noresume != 0 ] | |
| 96 | + usleep 500000 | |
| 97 | + done | |
| 98 | + killproc /sbin/cardmgr | |
| 99 | + dmesg -n 6 | |
| 100 | + if [ $mapped = 1 ] | |
| 101 | 101 | then |
| 102 | − mkswap /dev/mapper/swap0 > /dev/null 2>&1 | |
| 102 | + if [ $noresume != 0 ] | |
| 103 | + then | |
| 104 | + mkswap /dev/mapper/swap0 > /dev/null 2>&1 | |
| 105 | + fi | |
| 106 | + echo 254:0 > /sys/power/resume | |
| 107 | + dmsetup remove swap0 | |
| 103 | 108 | fi |
| 104 | − echo 254:0 > /sys/power/resume | |
| 105 | − dmsetup remove swap0 | |
| 106 | −fi | |
| 107 | −umount /sys | |
| 108 | −mount /mnt | |
| 109 | −umount /proc | |
| 110 | −cd /mnt | |
| 111 | −pivot_root . mnt | |
| 112 | −mount /proc | |
| 113 | −umount -l /mnt | |
| 114 | −umount /proc | |
| 115 | −exec chroot . /sbin/init $* < dev/console > dev/console 2>&1 | |
| 109 | + umount /sys | |
| 110 | + mount /mnt | |
| 111 | + umount /proc | |
| 112 | + cd /mnt | |
| 113 | + pivot_root . mnt | |
| 114 | + mount /proc | |
| 115 | + umount -l /mnt | |
| 116 | + umount /proc | |
| 117 | + exec chroot . /sbin/init $* < dev/console > dev/console 2>&1 | |
| 116 | 118 | |
| 117 | 119 | Please don't mind the weird loop above, busybox's msh doesn't know |
| 118 | 120 | the let statement. Now, what is happening in the script? |
| @@ -0,0 +1,501 @@ | ||
| 1 | +============ | |
| 2 | +Swap suspend | |
| 3 | +============ | |
| 4 | + | |
| 5 | +Some warnings, first. | |
| 6 | + | |
| 7 | +.. warning:: | |
| 8 | + | |
| 9 | + **BIG FAT WARNING** | |
| 10 | + | |
| 11 | + If you touch anything on disk between suspend and resume... | |
| 12 | + ...kiss your data goodbye. | |
| 13 | + | |
| 14 | + If you do resume from initrd after your filesystems are mounted... | |
| 15 | + ...bye bye root partition. | |
| 16 | + | |
| 17 | + [this is actually same case as above] | |
| 18 | + | |
| 19 | + If you have unsupported ( ) devices using DMA, you may have some | |
| 20 | + problems. If your disk driver does not support suspend... (IDE does), | |
| 21 | + it may cause some problems, too. If you change kernel command line | |
| 22 | + between suspend and resume, it may do something wrong. If you change | |
| 23 | + your hardware while system is suspended... well, it was not good idea; | |
| 24 | + but it will probably only crash. | |
| 25 | + | |
| 26 | + ( ) suspend/resume support is needed to make it safe. | |
| 27 | + | |
| 28 | + If you have any filesystems on USB devices mounted before software suspend, | |
| 29 | + they won't be accessible after resume and you may lose data, as though | |
| 30 | + you have unplugged the USB devices with mounted filesystems on them; | |
| 31 | + see the FAQ below for details. (This is not true for more traditional | |
| 32 | + power states like "standby", which normally don't turn USB off.) | |
| 33 | + | |
| 34 | +Swap partition: | |
| 35 | + You need to append resume=/dev/your_swap_partition to kernel command | |
| 36 | + line or specify it using /sys/power/resume. | |
| 37 | + | |
| 38 | +Swap file: | |
| 39 | + If using a swapfile you can also specify a resume offset using | |
| 40 | + resume_offset=<number> on the kernel command line or specify it | |
| 41 | + in /sys/power/resume_offset. | |
| 42 | + | |
| 43 | +After preparing then you suspend by:: | |
| 44 | + | |
| 45 | + echo shutdown > /sys/power/disk; echo disk > /sys/power/state | |
| 46 | + | |
| 47 | +- If you feel ACPI works pretty well on your system, you might try:: | |
| 48 | + | |
| 49 | + echo platform > /sys/power/disk; echo disk > /sys/power/state | |
| 50 | + | |
| 51 | +- If you would like to write hibernation image to swap and then suspend | |
| 52 | + to RAM (provided your platform supports it), you can try:: | |
| 53 | + | |
| 54 | + echo suspend > /sys/power/disk; echo disk > /sys/power/state | |
| 55 | + | |
| 56 | +- If you have SATA disks, you'll need recent kernels with SATA suspend | |
| 57 | + support. For suspend and resume to work, make sure your disk drivers | |
| 58 | + are built into kernel -- not modules. [There's way to make | |
| 59 | + suspend/resume with modular disk drivers, see FAQ, but you probably | |
| 60 | + should not do that.] | |
| 61 | + | |
| 62 | +If you want to limit the suspend image size to N bytes, do:: | |
| 63 | + | |
| 64 | + echo N > /sys/power/image_size | |
| 65 | + | |
| 66 | +before suspend (it is limited to around 2/5 of available RAM by default). | |
| 67 | + | |
| 68 | +- The resume process checks for the presence of the resume device, | |
| 69 | + if found, it then checks the contents for the hibernation image signature. | |
| 70 | + If both are found, it resumes the hibernation image. | |
| 71 | + | |
| 72 | +- The resume process may be triggered in two ways: | |
| 73 | + | |
| 74 | + 1) During lateinit: If resume=/dev/your_swap_partition is specified on | |
| 75 | + the kernel command line, lateinit runs the resume process. If the | |
| 76 | + resume device has not been probed yet, the resume process fails and | |
| 77 | + bootup continues. | |
| 78 | + 2) Manually from an initrd or initramfs: May be run from | |
| 79 | + the init script by using the /sys/power/resume file. It is vital | |
| 80 | + that this be done prior to remounting any filesystems (even as | |
| 81 | + read-only) otherwise data may be corrupted. | |
| 82 | + | |
| 83 | +Article about goals and implementation of Software Suspend for Linux | |
| 84 | +==================================================================== | |
| 85 | + | |
| 86 | +Author: Gábor Kuti | |
| 87 | +Last revised: 2003-10-20 by Pavel Machek | |
| 88 | + | |
| 89 | +Idea and goals to achieve | |
| 90 | +------------------------- | |
| 91 | + | |
| 92 | +Nowadays it is common in several laptops that they have a suspend button. It | |
| 93 | +saves the state of the machine to a filesystem or to a partition and switches | |
| 94 | +to standby mode. Later resuming the machine the saved state is loaded back to | |
| 95 | +ram and the machine can continue its work. It has two real benefits. First we | |
| 96 | +save ourselves the time machine goes down and later boots up, energy costs | |
| 97 | +are real high when running from batteries. The other gain is that we don't have | |
| 98 | +to interrupt our programs so processes that are calculating something for a long | |
| 99 | +time shouldn't need to be written interruptible. | |
| 100 | + | |
| 101 | +swsusp saves the state of the machine into active swaps and then reboots or | |
| 102 | +powerdowns. You must explicitly specify the swap partition to resume from with | |
| 103 | +`resume=` kernel option. If signature is found it loads and restores saved | |
| 104 | +state. If the option `noresume` is specified as a boot parameter, it skips | |
| 105 | +the resuming. If the option `hibernate=nocompress` is specified as a boot | |
| 106 | +parameter, it saves hibernation image without compression. | |
| 107 | + | |
| 108 | +In the meantime while the system is suspended you should not add/remove any | |
| 109 | +of the hardware, write to the filesystems, etc. | |
| 110 | + | |
| 111 | +Sleep states summary | |
| 112 | +==================== | |
| 113 | + | |
| 114 | +There are three different interfaces you can use, /proc/acpi should | |
| 115 | +work like this: | |
| 116 | + | |
| 117 | +In a really perfect world:: | |
| 118 | + | |
| 119 | + echo 1 > /proc/acpi/sleep # for standby | |
| 120 | + echo 2 > /proc/acpi/sleep # for suspend to ram | |
| 121 | + echo 3 > /proc/acpi/sleep # for suspend to ram, but with more power conservative | |
| 122 | + echo 4 > /proc/acpi/sleep # for suspend to disk | |
| 123 | + echo 5 > /proc/acpi/sleep # for shutdown unfriendly the system | |
| 124 | + | |
| 125 | +and perhaps:: | |
| 126 | + | |
| 127 | + echo 4b > /proc/acpi/sleep # for suspend to disk via s4bios | |
| 128 | + | |
| 129 | +Frequently Asked Questions | |
| 130 | +========================== | |
| 131 | + | |
| 132 | +Q: | |
| 133 | + well, suspending a server is IMHO a really stupid thing, | |
| 134 | + but... (Diego Zuccato): | |
| 135 | + | |
| 136 | +A: | |
| 137 | + You bought new UPS for your server. How do you install it without | |
| 138 | + bringing machine down? Suspend to disk, rearrange power cables, | |
| 139 | + resume. | |
| 140 | + | |
| 141 | + You have your server on UPS. Power died, and UPS is indicating 30 | |
| 142 | + seconds to failure. What do you do? Suspend to disk. | |
| 143 | + | |
| 144 | + | |
| 145 | +Q: | |
| 146 | + Maybe I'm missing something, but why don't the regular I/O paths work? | |
| 147 | + | |
| 148 | +A: | |
| 149 | + We do use the regular I/O paths. However we cannot restore the data | |
| 150 | + to its original location as we load it. That would create an | |
| 151 | + inconsistent kernel state which would certainly result in an oops. | |
| 152 | + Instead, we load the image into unused memory and then atomically copy | |
| 153 | + it back to it original location. This implies, of course, a maximum | |
| 154 | + image size of half the amount of memory. | |
| 155 | + | |
| 156 | + There are two solutions to this: | |
| 157 | + | |
| 158 | + * require half of memory to be free during suspend. That way you can | |
| 159 | + read "new" data onto free spots, then cli and copy | |
| 160 | + | |
| 161 | + * assume we had special "polling" ide driver that only uses memory | |
| 162 | + between 0-640KB. That way, I'd have to make sure that 0-640KB is free | |
| 163 | + during suspending, but otherwise it would work... | |
| 164 | + | |
| 165 | + suspend2 shares this fundamental limitation, but does not include user | |
| 166 | + data and disk caches into "used memory" by saving them in | |
| 167 | + advance. That means that the limitation goes away in practice. | |
| 168 | + | |
| 169 | +Q: | |
| 170 | + Does linux support ACPI S4? | |
| 171 | + | |
| 172 | +A: | |
| 173 | + Yes. That's what echo platform > /sys/power/disk does. | |
| 174 | + | |
| 175 | +Q: | |
| 176 | + What is 'suspend2'? | |
| 177 | + | |
| 178 | +A: | |
| 179 | + suspend2 is 'Software Suspend 2', a forked implementation of | |
| 180 | + suspend-to-disk which is available as separate patches for 2.4 and 2.6 | |
| 181 | + kernels from swsusp.sourceforge.net. It includes support for SMP, 4GB | |
| 182 | + highmem and preemption. It also has a extensible architecture that | |
| 183 | + allows for arbitrary transformations on the image (compression, | |
| 184 | + encryption) and arbitrary backends for writing the image (eg to swap | |
| 185 | + or an NFS share[Work In Progress]). Questions regarding suspend2 | |
| 186 | + should be sent to the mailing list available through the suspend2 | |
| 187 | + website, and not to the Linux Kernel Mailing List. We are working | |
| 188 | + toward merging suspend2 into the mainline kernel. | |
| 189 | + | |
| 190 | +Q: | |
| 191 | + What is the freezing of tasks and why are we using it? | |
| 192 | + | |
| 193 | +A: | |
| 194 | + The freezing of tasks is a mechanism by which user space processes and some | |
| 195 | + kernel threads are controlled during hibernation or system-wide suspend (on some | |
| 196 | + architectures). See freezing-of-tasks.txt for details. | |
| 197 | + | |
| 198 | +Q: | |
| 199 | + What is the difference between "platform" and "shutdown"? | |
| 200 | + | |
| 201 | +A: | |
| 202 | + shutdown: | |
| 203 | + save state in linux, then tell bios to powerdown | |
| 204 | + | |
| 205 | + platform: | |
| 206 | + save state in linux, then tell bios to powerdown and blink | |
| 207 | + "suspended led" | |
| 208 | + | |
| 209 | + "platform" is actually right thing to do where supported, but | |
| 210 | + "shutdown" is most reliable (except on ACPI systems). | |
| 211 | + | |
| 212 | +Q: | |
| 213 | + I do not understand why you have such strong objections to idea of | |
| 214 | + selective suspend. | |
| 215 | + | |
| 216 | +A: | |
| 217 | + Do selective suspend during runtime power management, that's okay. But | |
| 218 | + it's useless for suspend-to-disk. (And I do not see how you could use | |
| 219 | + it for suspend-to-ram, I hope you do not want that). | |
| 220 | + | |
| 221 | + Lets see, so you suggest to | |
| 222 | + | |
| 223 | + * SUSPEND all but swap device and parents | |
| 224 | + * Snapshot | |
| 225 | + * Write image to disk | |
| 226 | + * SUSPEND swap device and parents | |
| 227 | + * Powerdown | |
| 228 | + | |
| 229 | + Oh no, that does not work, if swap device or its parents uses DMA, | |
| 230 | + you've corrupted data. You'd have to do | |
| 231 | + | |
| 232 | + * SUSPEND all but swap device and parents | |
| 233 | + * FREEZE swap device and parents | |
| 234 | + * Snapshot | |
| 235 | + * UNFREEZE swap device and parents | |
| 236 | + * Write | |
| 237 | + * SUSPEND swap device and parents | |
| 238 | + | |
| 239 | + Which means that you still need that FREEZE state, and you get more | |
| 240 | + complicated code. (And I have not yet introduce details like system | |
| 241 | + devices). | |
| 242 | + | |
| 243 | +Q: | |
| 244 | + There don't seem to be any generally useful behavioral | |
| 245 | + distinctions between SUSPEND and FREEZE. | |
| 246 | + | |
| 247 | +A: | |
| 248 | + Doing SUSPEND when you are asked to do FREEZE is always correct, | |
| 249 | + but it may be unnecessarily slow. If you want your driver to stay simple, | |
| 250 | + slowness may not matter to you. It can always be fixed later. | |
| 251 | + | |
| 252 | + For devices like disk it does matter, you do not want to spindown for | |
| 253 | + FREEZE. | |
| 254 | + | |
| 255 | +Q: | |
| 256 | + After resuming, system is paging heavily, leading to very bad interactivity. | |
| 257 | + | |
| 258 | +A: | |
| 259 | + Try running:: | |
| 260 | + | |
| 261 | + cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u | while read file | |
| 262 | + do | |
| 263 | + test -f "$file" && cat "$file" > /dev/null | |
| 264 | + done | |
| 265 | + | |
| 266 | + after resume. swapoff -a; swapon -a may also be useful. | |
| 267 | + | |
| 268 | +Q: | |
| 269 | + What happens to devices during swsusp? They seem to be resumed | |
| 270 | + during system suspend? | |
| 271 | + | |
| 272 | +A: | |
| 273 | + That's correct. We need to resume them if we want to write image to | |
| 274 | + disk. Whole sequence goes like | |
| 275 | + | |
| 276 | + **Suspend part** | |
| 277 | + | |
| 278 | + running system, user asks for suspend-to-disk | |
| 279 | + | |
| 280 | + user processes are stopped | |
| 281 | + | |
| 282 | + suspend(PMSG_FREEZE): devices are frozen so that they don't interfere | |
| 283 | + with state snapshot | |
| 284 | + | |
| 285 | + state snapshot: copy of whole used memory is taken with interrupts disabled | |
| 286 | + | |
| 287 | + resume(): devices are woken up so that we can write image to swap | |
| 288 | + | |
| 289 | + write image to swap | |
| 290 | + | |
| 291 | + suspend(PMSG_SUSPEND): suspend devices so that we can power off | |
| 292 | + | |
| 293 | + turn the power off | |
| 294 | + | |
| 295 | + **Resume part** | |
| 296 | + | |
| 297 | + (is actually pretty similar) | |
| 298 | + | |
| 299 | + running system, user asks for suspend-to-disk | |
| 300 | + | |
| 301 | + user processes are stopped (in common case there are none, | |
| 302 | + but with resume-from-initrd, no one knows) | |
| 303 | + | |
| 304 | + read image from disk | |
| 305 | + | |
| 306 | + suspend(PMSG_FREEZE): devices are frozen so that they don't interfere | |
| 307 | + with image restoration | |
| 308 | + | |
| 309 | + image restoration: rewrite memory with image | |
| 310 | + | |
| 311 | + resume(): devices are woken up so that system can continue | |
| 312 | + | |
| 313 | + thaw all user processes | |
| 314 | + | |
| 315 | +Q: | |
| 316 | + What is this 'Encrypt suspend image' for? | |
| 317 | + | |
| 318 | +A: | |
| 319 | + First of all: it is not a replacement for dm-crypt encrypted swap. | |
| 320 | + It cannot protect your computer while it is suspended. Instead it does | |
| 321 | + protect from leaking sensitive data after resume from suspend. | |
| 322 | + | |
| 323 | + Think of the following: you suspend while an application is running | |
| 324 | + that keeps sensitive data in memory. The application itself prevents | |
| 325 | + the data from being swapped out. Suspend, however, must write these | |
| 326 | + data to swap to be able to resume later on. Without suspend encryption | |
| 327 | + your sensitive data are then stored in plaintext on disk. This means | |
| 328 | + that after resume your sensitive data are accessible to all | |
| 329 | + applications having direct access to the swap device which was used | |
| 330 | + for suspend. If you don't need swap after resume these data can remain | |
| 331 | + on disk virtually forever. Thus it can happen that your system gets | |
| 332 | + broken in weeks later and sensitive data which you thought were | |
| 333 | + encrypted and protected are retrieved and stolen from the swap device. | |
| 334 | + To prevent this situation you should use 'Encrypt suspend image'. | |
| 335 | + | |
| 336 | + During suspend a temporary key is created and this key is used to | |
| 337 | + encrypt the data written to disk. When, during resume, the data was | |
| 338 | + read back into memory the temporary key is destroyed which simply | |
| 339 | + means that all data written to disk during suspend are then | |
| 340 | + inaccessible so they can't be stolen later on. The only thing that | |
| 341 | + you must then take care of is that you call 'mkswap' for the swap | |
| 342 | + partition used for suspend as early as possible during regular | |
| 343 | + boot. This asserts that any temporary key from an oopsed suspend or | |
| 344 | + from a failed or aborted resume is erased from the swap device. | |
| 345 | + | |
| 346 | + As a rule of thumb use encrypted swap to protect your data while your | |
| 347 | + system is shut down or suspended. Additionally use the encrypted | |
| 348 | + suspend image to prevent sensitive data from being stolen after | |
| 349 | + resume. | |
| 350 | + | |
| 351 | +Q: | |
| 352 | + Can I suspend to a swap file? | |
| 353 | + | |
| 354 | +A: | |
| 355 | + Generally, yes, you can. However, it requires you to use the "resume=" and | |
| 356 | + "resume_offset=" kernel command line parameters, so the resume from a swap file | |
| 357 | + cannot be initiated from an initrd or initramfs image. See | |
| 358 | + swsusp-and-swap-files.txt for details. | |
| 359 | + | |
| 360 | +Q: | |
| 361 | + Is there a maximum system RAM size that is supported by swsusp? | |
| 362 | + | |
| 363 | +A: | |
| 364 | + It should work okay with highmem. | |
| 365 | + | |
| 366 | +Q: | |
| 367 | + Does swsusp (to disk) use only one swap partition or can it use | |
| 368 | + multiple swap partitions (aggregate them into one logical space)? | |
| 369 | + | |
| 370 | +A: | |
| 371 | + Only one swap partition, sorry. | |
| 372 | + | |
| 373 | +Q: | |
| 374 | + If my application(s) causes lots of memory & swap space to be used | |
| 375 | + (over half of the total system RAM), is it correct that it is likely | |
| 376 | + to be useless to try to suspend to disk while that app is running? | |
| 377 | + | |
| 378 | +A: | |
| 379 | + No, it should work okay, as long as your app does not mlock() | |
| 380 | + it. Just prepare big enough swap partition. | |
| 381 | + | |
| 382 | +Q: | |
| 383 | + What information is useful for debugging suspend-to-disk problems? | |
| 384 | + | |
| 385 | +A: | |
| 386 | + Well, last messages on the screen are always useful. If something | |
| 387 | + is broken, it is usually some kernel driver, therefore trying with as | |
| 388 | + little as possible modules loaded helps a lot. I also prefer people to | |
| 389 | + suspend from console, preferably without X running. Booting with | |
| 390 | + init=/bin/bash, then swapon and starting suspend sequence manually | |
| 391 | + usually does the trick. Then it is good idea to try with latest | |
| 392 | + vanilla kernel. | |
| 393 | + | |
| 394 | +Q: | |
| 395 | + How can distributions ship a swsusp-supporting kernel with modular | |
| 396 | + disk drivers (especially SATA)? | |
| 397 | + | |
| 398 | +A: | |
| 399 | + Well, it can be done, load the drivers, then do echo into | |
| 400 | + /sys/power/resume file from initrd. Be sure not to mount | |
| 401 | + anything, not even read-only mount, or you are going to lose your | |
| 402 | + data. | |
| 403 | + | |
| 404 | +Q: | |
| 405 | + How do I make suspend more verbose? | |
| 406 | + | |
| 407 | +A: | |
| 408 | + If you want to see any non-error kernel messages on the virtual | |
| 409 | + terminal the kernel switches to during suspend, you have to set the | |
| 410 | + kernel console loglevel to at least 4 (KERN_WARNING), for example by | |
| 411 | + doing:: | |
| 412 | + | |
| 413 | + # save the old loglevel | |
| 414 | + read LOGLEVEL DUMMY < /proc/sys/kernel/printk | |
| 415 | + # set the loglevel so we see the progress bar. | |
| 416 | + # if the level is higher than needed, we leave it alone. | |
| 417 | + if [ $LOGLEVEL -lt 5 ]; then | |
| 418 | + echo 5 > /proc/sys/kernel/printk | |
| 419 | + fi | |
| 420 | + | |
| 421 | + IMG_SZ=0 | |
| 422 | + read IMG_SZ < /sys/power/image_size | |
| 423 | + echo -n disk > /sys/power/state | |
| 424 | + RET=$? | |
| 425 | + # | |
| 426 | + # the logic here is: | |
| 427 | + # if image_size > 0 (without kernel support, IMG_SZ will be zero), | |
| 428 | + # then try again with image_size set to zero. | |
| 429 | + if [ $RET -ne 0 -a $IMG_SZ -ne 0 ]; then # try again with minimal image size | |
| 430 | + echo 0 > /sys/power/image_size | |
| 431 | + echo -n disk > /sys/power/state | |
| 432 | + RET=$? | |
| 433 | + fi | |
| 434 | + | |
| 435 | + # restore previous loglevel | |
| 436 | + echo $LOGLEVEL > /proc/sys/kernel/printk | |
| 437 | + exit $RET | |
| 438 | + | |
| 439 | +Q: | |
| 440 | + Is this true that if I have a mounted filesystem on a USB device and | |
| 441 | + I suspend to disk, I can lose data unless the filesystem has been mounted | |
| 442 | + with "sync"? | |
| 443 | + | |
| 444 | +A: | |
| 445 | + That's right ... if you disconnect that device, you may lose data. | |
| 446 | + In fact, even with "-o sync" you can lose data if your programs have | |
| 447 | + information in buffers they haven't written out to a disk you disconnect, | |
| 448 | + or if you disconnect before the device finished saving data you wrote. | |
| 449 | + | |
| 450 | + Software suspend normally powers down USB controllers, which is equivalent | |
| 451 | + to disconnecting all USB devices attached to your system. | |
| 452 | + | |
| 453 | + Your system might well support low-power modes for its USB controllers | |
| 454 | + while the system is asleep, maintaining the connection, using true sleep | |
| 455 | + modes like "suspend-to-RAM" or "standby". (Don't write "disk" to the | |
| 456 | + /sys/power/state file; write "standby" or "mem".) We've not seen any | |
| 457 | + hardware that can use these modes through software suspend, although in | |
| 458 | + theory some systems might support "platform" modes that won't break the | |
| 459 | + USB connections. | |
| 460 | + | |
| 461 | + Remember that it's always a bad idea to unplug a disk drive containing a | |
| 462 | + mounted filesystem. That's true even when your system is asleep! The | |
| 463 | + safest thing is to unmount all filesystems on removable media (such USB, | |
| 464 | + Firewire, CompactFlash, MMC, external SATA, or even IDE hotplug bays) | |
| 465 | + before suspending; then remount them after resuming. | |
| 466 | + | |
| 467 | + There is a work-around for this problem. For more information, see | |
| 468 | + Documentation/driver-api/usb/persist.rst. | |
| 469 | + | |
| 470 | +Q: | |
| 471 | + Can I suspend-to-disk using a swap partition under LVM? | |
| 472 | + | |
| 473 | +A: | |
| 474 | + Yes and No. You can suspend successfully, but the kernel will not be able | |
| 475 | + to resume on its own. You need an initramfs that can recognize the resume | |
| 476 | + situation, activate the logical volume containing the swap volume (but not | |
| 477 | + touch any filesystems!), and eventually call:: | |
| 478 | + | |
| 479 | + echo -n "$major:$minor" > /sys/power/resume | |
| 480 | + | |
| 481 | + where $major and $minor are the respective major and minor device numbers of | |
| 482 | + the swap volume. | |
| 483 | + | |
| 484 | + uswsusp works with LVM, too. See http://suspend.sourceforge.net/ | |
| 485 | + | |
| 486 | +Q: | |
| 487 | + I upgraded the kernel from 2.6.15 to 2.6.16. Both kernels were | |
| 488 | + compiled with the similar configuration files. Anyway I found that | |
| 489 | + suspend to disk (and resume) is much slower on 2.6.16 compared to | |
| 490 | + 2.6.15. Any idea for why that might happen or how can I speed it up? | |
| 491 | + | |
| 492 | +A: | |
| 493 | + This is because the size of the suspend image is now greater than | |
| 494 | + for 2.6.15 (by saving more data we can get more responsive system | |
| 495 | + after resume). | |
| 496 | + | |
| 497 | + There's the /sys/power/image_size knob that controls the size of the | |
| 498 | + image. If you set it to 0 (eg. by echo 0 > /sys/power/image_size as | |
| 499 | + root), the 2.6.15 behavior should be restored. If it is still too | |
| 500 | + slow, take a look at suspend.sf.net -- userland suspend is faster and | |
| 501 | + supports LZF compression to speed it up further. | |
| @@ -1,446 +0,0 @@ | ||
| 1 | −Some warnings, first. | |
| 2 | − | |
| 3 | − * BIG FAT WARNING ********************************************************* | |
| 4 | − * | |
| 5 | − * If you touch anything on disk between suspend and resume... | |
| 6 | − * ...kiss your data goodbye. | |
| 7 | − * | |
| 8 | − * If you do resume from initrd after your filesystems are mounted... | |
| 9 | − * ...bye bye root partition. | |
| 10 | − * [this is actually same case as above] | |
| 11 | − * | |
| 12 | − * If you have unsupported (*) devices using DMA, you may have some | |
| 13 | − * problems. If your disk driver does not support suspend... (IDE does), | |
| 14 | − * it may cause some problems, too. If you change kernel command line | |
| 15 | − * between suspend and resume, it may do something wrong. If you change | |
| 16 | − * your hardware while system is suspended... well, it was not good idea; | |
| 17 | − * but it will probably only crash. | |
| 18 | − * | |
| 19 | − * (*) suspend/resume support is needed to make it safe. | |
| 20 | − * | |
| 21 | − * If you have any filesystems on USB devices mounted before software suspend, | |
| 22 | − * they won't be accessible after resume and you may lose data, as though | |
| 23 | − * you have unplugged the USB devices with mounted filesystems on them; | |
| 24 | − * see the FAQ below for details. (This is not true for more traditional | |
| 25 | − * power states like "standby", which normally don't turn USB off.) | |
| 26 | − | |
| 27 | −Swap partition: | |
| 28 | −You need to append resume=/dev/your_swap_partition to kernel command | |
| 29 | −line or specify it using /sys/power/resume. | |
| 30 | − | |
| 31 | −Swap file: | |
| 32 | −If using a swapfile you can also specify a resume offset using | |
| 33 | −resume_offset=<number> on the kernel command line or specify it | |
| 34 | −in /sys/power/resume_offset. | |
| 35 | − | |
| 36 | −After preparing then you suspend by | |
| 37 | − | |
| 38 | −echo shutdown > /sys/power/disk; echo disk > /sys/power/state | |
| 39 | − | |
| 40 | −. If you feel ACPI works pretty well on your system, you might try | |
| 41 | − | |
| 42 | −echo platform > /sys/power/disk; echo disk > /sys/power/state | |
| 43 | − | |
| 44 | −. If you would like to write hibernation image to swap and then suspend | |
| 45 | −to RAM (provided your platform supports it), you can try | |
| 46 | − | |
| 47 | −echo suspend > /sys/power/disk; echo disk > /sys/power/state | |
| 48 | − | |
| 49 | −. If you have SATA disks, you'll need recent kernels with SATA suspend | |
| 50 | −support. For suspend and resume to work, make sure your disk drivers | |
| 51 | −are built into kernel -- not modules. [There's way to make | |
| 52 | −suspend/resume with modular disk drivers, see FAQ, but you probably | |
| 53 | −should not do that.] | |
| 54 | − | |
| 55 | −If you want to limit the suspend image size to N bytes, do | |
| 56 | − | |
| 57 | −echo N > /sys/power/image_size | |
| 58 | − | |
| 59 | −before suspend (it is limited to around 2/5 of available RAM by default). | |
| 60 | − | |
| 61 | −. The resume process checks for the presence of the resume device, | |
| 62 | −if found, it then checks the contents for the hibernation image signature. | |
| 63 | −If both are found, it resumes the hibernation image. | |
| 64 | − | |
| 65 | −. The resume process may be triggered in two ways: | |
| 66 | − 1) During lateinit: If resume=/dev/your_swap_partition is specified on | |
| 67 | − the kernel command line, lateinit runs the resume process. If the | |
| 68 | − resume device has not been probed yet, the resume process fails and | |
| 69 | − bootup continues. | |
| 70 | − 2) Manually from an initrd or initramfs: May be run from | |
| 71 | − the init script by using the /sys/power/resume file. It is vital | |
| 72 | − that this be done prior to remounting any filesystems (even as | |
| 73 | − read-only) otherwise data may be corrupted. | |
| 74 | − | |
| 75 | −Article about goals and implementation of Software Suspend for Linux | |
| 76 | −~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 77 | −Author: Gábor Kuti | |
| 78 | −Last revised: 2003-10-20 by Pavel Machek | |
| 79 | − | |
| 80 | −Idea and goals to achieve | |
| 81 | − | |
| 82 | −Nowadays it is common in several laptops that they have a suspend button. It | |
| 83 | −saves the state of the machine to a filesystem or to a partition and switches | |
| 84 | −to standby mode. Later resuming the machine the saved state is loaded back to | |
| 85 | −ram and the machine can continue its work. It has two real benefits. First we | |
| 86 | −save ourselves the time machine goes down and later boots up, energy costs | |
| 87 | −are real high when running from batteries. The other gain is that we don't have to | |
| 88 | −interrupt our programs so processes that are calculating something for a long | |
| 89 | −time shouldn't need to be written interruptible. | |
| 90 | − | |
| 91 | −swsusp saves the state of the machine into active swaps and then reboots or | |
| 92 | −powerdowns. You must explicitly specify the swap partition to resume from with | |
| 93 | −``resume='' kernel option. If signature is found it loads and restores saved | |
| 94 | −state. If the option ``noresume'' is specified as a boot parameter, it skips | |
| 95 | −the resuming. If the option ``hibernate=nocompress'' is specified as a boot | |
| 96 | −parameter, it saves hibernation image without compression. | |
| 97 | − | |
| 98 | −In the meantime while the system is suspended you should not add/remove any | |
| 99 | −of the hardware, write to the filesystems, etc. | |
| 100 | − | |
| 101 | −Sleep states summary | |
| 102 | −==================== | |
| 103 | − | |
| 104 | −There are three different interfaces you can use, /proc/acpi should | |
| 105 | −work like this: | |
| 106 | − | |
| 107 | −In a really perfect world: | |
| 108 | −echo 1 > /proc/acpi/sleep # for standby | |
| 109 | −echo 2 > /proc/acpi/sleep # for suspend to ram | |
| 110 | −echo 3 > /proc/acpi/sleep # for suspend to ram, but with more power conservative | |
| 111 | −echo 4 > /proc/acpi/sleep # for suspend to disk | |
| 112 | −echo 5 > /proc/acpi/sleep # for shutdown unfriendly the system | |
| 113 | − | |
| 114 | −and perhaps | |
| 115 | −echo 4b > /proc/acpi/sleep # for suspend to disk via s4bios | |
| 116 | − | |
| 117 | −Frequently Asked Questions | |
| 118 | −========================== | |
| 119 | − | |
| 120 | −Q: well, suspending a server is IMHO a really stupid thing, | |
| 121 | −but... (Diego Zuccato): | |
| 122 | − | |
| 123 | −A: You bought new UPS for your server. How do you install it without | |
| 124 | −bringing machine down? Suspend to disk, rearrange power cables, | |
| 125 | −resume. | |
| 126 | − | |
| 127 | −You have your server on UPS. Power died, and UPS is indicating 30 | |
| 128 | −seconds to failure. What do you do? Suspend to disk. | |
| 129 | − | |
| 130 | − | |
| 131 | −Q: Maybe I'm missing something, but why don't the regular I/O paths work? | |
| 132 | − | |
| 133 | −A: We do use the regular I/O paths. However we cannot restore the data | |
| 134 | −to its original location as we load it. That would create an | |
| 135 | −inconsistent kernel state which would certainly result in an oops. | |
| 136 | −Instead, we load the image into unused memory and then atomically copy | |
| 137 | −it back to it original location. This implies, of course, a maximum | |
| 138 | −image size of half the amount of memory. | |
| 139 | − | |
| 140 | −There are two solutions to this: | |
| 141 | − | |
| 142 | −* require half of memory to be free during suspend. That way you can | |
| 143 | −read "new" data onto free spots, then cli and copy | |
| 144 | − | |
| 145 | −* assume we had special "polling" ide driver that only uses memory | |
| 146 | −between 0-640KB. That way, I'd have to make sure that 0-640KB is free | |
| 147 | −during suspending, but otherwise it would work... | |
| 148 | − | |
| 149 | −suspend2 shares this fundamental limitation, but does not include user | |
| 150 | −data and disk caches into "used memory" by saving them in | |
| 151 | −advance. That means that the limitation goes away in practice. | |
| 152 | − | |
| 153 | −Q: Does linux support ACPI S4? | |
| 154 | − | |
| 155 | −A: Yes. That's what echo platform > /sys/power/disk does. | |
| 156 | − | |
| 157 | −Q: What is 'suspend2'? | |
| 158 | − | |
| 159 | −A: suspend2 is 'Software Suspend 2', a forked implementation of | |
| 160 | −suspend-to-disk which is available as separate patches for 2.4 and 2.6 | |
| 161 | −kernels from swsusp.sourceforge.net. It includes support for SMP, 4GB | |
| 162 | −highmem and preemption. It also has a extensible architecture that | |
| 163 | −allows for arbitrary transformations on the image (compression, | |
| 164 | −encryption) and arbitrary backends for writing the image (eg to swap | |
| 165 | −or an NFS share[Work In Progress]). Questions regarding suspend2 | |
| 166 | −should be sent to the mailing list available through the suspend2 | |
| 167 | −website, and not to the Linux Kernel Mailing List. We are working | |
| 168 | −toward merging suspend2 into the mainline kernel. | |
| 169 | − | |
| 170 | −Q: What is the freezing of tasks and why are we using it? | |
| 171 | − | |
| 172 | −A: The freezing of tasks is a mechanism by which user space processes and some | |
| 173 | −kernel threads are controlled during hibernation or system-wide suspend (on some | |
| 174 | −architectures). See freezing-of-tasks.txt for details. | |
| 175 | − | |
| 176 | −Q: What is the difference between "platform" and "shutdown"? | |
| 177 | − | |
| 178 | −A: | |
| 179 | − | |
| 180 | −shutdown: save state in linux, then tell bios to powerdown | |
| 181 | − | |
| 182 | −platform: save state in linux, then tell bios to powerdown and blink | |
| 183 | − "suspended led" | |
| 184 | − | |
| 185 | −"platform" is actually right thing to do where supported, but | |
| 186 | −"shutdown" is most reliable (except on ACPI systems). | |
| 187 | − | |
| 188 | −Q: I do not understand why you have such strong objections to idea of | |
| 189 | −selective suspend. | |
| 190 | − | |
| 191 | −A: Do selective suspend during runtime power management, that's okay. But | |
| 192 | −it's useless for suspend-to-disk. (And I do not see how you could use | |
| 193 | −it for suspend-to-ram, I hope you do not want that). | |
| 194 | − | |
| 195 | −Lets see, so you suggest to | |
| 196 | − | |
| 197 | −* SUSPEND all but swap device and parents | |
| 198 | −* Snapshot | |
| 199 | −* Write image to disk | |
| 200 | −* SUSPEND swap device and parents | |
| 201 | −* Powerdown | |
| 202 | − | |
| 203 | −Oh no, that does not work, if swap device or its parents uses DMA, | |
| 204 | −you've corrupted data. You'd have to do | |
| 205 | − | |
| 206 | −* SUSPEND all but swap device and parents | |
| 207 | −* FREEZE swap device and parents | |
| 208 | −* Snapshot | |
| 209 | −* UNFREEZE swap device and parents | |
| 210 | −* Write | |
| 211 | −* SUSPEND swap device and parents | |
| 212 | − | |
| 213 | −Which means that you still need that FREEZE state, and you get more | |
| 214 | −complicated code. (And I have not yet introduce details like system | |
| 215 | −devices). | |
| 216 | − | |
| 217 | −Q: There don't seem to be any generally useful behavioral | |
| 218 | −distinctions between SUSPEND and FREEZE. | |
| 219 | − | |
| 220 | −A: Doing SUSPEND when you are asked to do FREEZE is always correct, | |
| 221 | −but it may be unnecessarily slow. If you want your driver to stay simple, | |
| 222 | −slowness may not matter to you. It can always be fixed later. | |
| 223 | − | |
| 224 | −For devices like disk it does matter, you do not want to spindown for | |
| 225 | −FREEZE. | |
| 226 | − | |
| 227 | −Q: After resuming, system is paging heavily, leading to very bad interactivity. | |
| 228 | − | |
| 229 | −A: Try running | |
| 230 | − | |
| 231 | −cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u | while read file | |
| 232 | −do | |
| 233 | − test -f "$file" && cat "$file" > /dev/null | |
| 234 | −done | |
| 235 | − | |
| 236 | −after resume. swapoff -a; swapon -a may also be useful. | |
| 237 | − | |
| 238 | −Q: What happens to devices during swsusp? They seem to be resumed | |
| 239 | −during system suspend? | |
| 240 | − | |
| 241 | −A: That's correct. We need to resume them if we want to write image to | |
| 242 | −disk. Whole sequence goes like | |
| 243 | − | |
| 244 | − Suspend part | |
| 245 | − ~~~~~~~~~~~~ | |
| 246 | − running system, user asks for suspend-to-disk | |
| 247 | − | |
| 248 | − user processes are stopped | |
| 249 | − | |
| 250 | − suspend(PMSG_FREEZE): devices are frozen so that they don't interfere | |
| 251 | − with state snapshot | |
| 252 | − | |
| 253 | − state snapshot: copy of whole used memory is taken with interrupts disabled | |
| 254 | − | |
| 255 | − resume(): devices are woken up so that we can write image to swap | |
| 256 | − | |
| 257 | − write image to swap | |
| 258 | − | |
| 259 | − suspend(PMSG_SUSPEND): suspend devices so that we can power off | |
| 260 | − | |
| 261 | − turn the power off | |
| 262 | − | |
| 263 | − Resume part | |
| 264 | − ~~~~~~~~~~~ | |
| 265 | − (is actually pretty similar) | |
| 266 | − | |
| 267 | − running system, user asks for suspend-to-disk | |
| 268 | − | |
| 269 | − user processes are stopped (in common case there are none, but with resume-from-initrd, no one knows) | |
| 270 | − | |
| 271 | − read image from disk | |
| 272 | − | |
| 273 | − suspend(PMSG_FREEZE): devices are frozen so that they don't interfere | |
| 274 | − with image restoration | |
| 275 | − | |
| 276 | − image restoration: rewrite memory with image | |
| 277 | − | |
| 278 | − resume(): devices are woken up so that system can continue | |
| 279 | − | |
| 280 | − thaw all user processes | |
| 281 | − | |
| 282 | −Q: What is this 'Encrypt suspend image' for? | |
| 283 | − | |
| 284 | −A: First of all: it is not a replacement for dm-crypt encrypted swap. | |
| 285 | −It cannot protect your computer while it is suspended. Instead it does | |
| 286 | −protect from leaking sensitive data after resume from suspend. | |
| 287 | − | |
| 288 | −Think of the following: you suspend while an application is running | |
| 289 | −that keeps sensitive data in memory. The application itself prevents | |
| 290 | −the data from being swapped out. Suspend, however, must write these | |
| 291 | −data to swap to be able to resume later on. Without suspend encryption | |
| 292 | −your sensitive data are then stored in plaintext on disk. This means | |
| 293 | −that after resume your sensitive data are accessible to all | |
| 294 | −applications having direct access to the swap device which was used | |
| 295 | −for suspend. If you don't need swap after resume these data can remain | |
| 296 | −on disk virtually forever. Thus it can happen that your system gets | |
| 297 | −broken in weeks later and sensitive data which you thought were | |
| 298 | −encrypted and protected are retrieved and stolen from the swap device. | |
| 299 | −To prevent this situation you should use 'Encrypt suspend image'. | |
| 300 | − | |
| 301 | −During suspend a temporary key is created and this key is used to | |
| 302 | −encrypt the data written to disk. When, during resume, the data was | |
| 303 | −read back into memory the temporary key is destroyed which simply | |
| 304 | −means that all data written to disk during suspend are then | |
| 305 | −inaccessible so they can't be stolen later on. The only thing that | |
| 306 | −you must then take care of is that you call 'mkswap' for the swap | |
| 307 | −partition used for suspend as early as possible during regular | |
| 308 | −boot. This asserts that any temporary key from an oopsed suspend or | |
| 309 | −from a failed or aborted resume is erased from the swap device. | |
| 310 | − | |
| 311 | −As a rule of thumb use encrypted swap to protect your data while your | |
| 312 | −system is shut down or suspended. Additionally use the encrypted | |
| 313 | −suspend image to prevent sensitive data from being stolen after | |
| 314 | −resume. | |
| 315 | − | |
| 316 | −Q: Can I suspend to a swap file? | |
| 317 | − | |
| 318 | −A: Generally, yes, you can. However, it requires you to use the "resume=" and | |
| 319 | −"resume_offset=" kernel command line parameters, so the resume from a swap file | |
| 320 | −cannot be initiated from an initrd or initramfs image. See | |
| 321 | −swsusp-and-swap-files.txt for details. | |
| 322 | − | |
| 323 | −Q: Is there a maximum system RAM size that is supported by swsusp? | |
| 324 | − | |
| 325 | −A: It should work okay with highmem. | |
| 326 | − | |
| 327 | −Q: Does swsusp (to disk) use only one swap partition or can it use | |
| 328 | −multiple swap partitions (aggregate them into one logical space)? | |
| 329 | − | |
| 330 | −A: Only one swap partition, sorry. | |
| 331 | − | |
| 332 | −Q: If my application(s) causes lots of memory & swap space to be used | |
| 333 | −(over half of the total system RAM), is it correct that it is likely | |
| 334 | −to be useless to try to suspend to disk while that app is running? | |
| 335 | − | |
| 336 | −A: No, it should work okay, as long as your app does not mlock() | |
| 337 | −it. Just prepare big enough swap partition. | |
| 338 | − | |
| 339 | −Q: What information is useful for debugging suspend-to-disk problems? | |
| 340 | − | |
| 341 | −A: Well, last messages on the screen are always useful. If something | |
| 342 | −is broken, it is usually some kernel driver, therefore trying with as | |
| 343 | −little as possible modules loaded helps a lot. I also prefer people to | |
| 344 | −suspend from console, preferably without X running. Booting with | |
| 345 | −init=/bin/bash, then swapon and starting suspend sequence manually | |
| 346 | −usually does the trick. Then it is good idea to try with latest | |
| 347 | −vanilla kernel. | |
| 348 | − | |
| 349 | −Q: How can distributions ship a swsusp-supporting kernel with modular | |
| 350 | −disk drivers (especially SATA)? | |
| 351 | − | |
| 352 | −A: Well, it can be done, load the drivers, then do echo into | |
| 353 | −/sys/power/resume file from initrd. Be sure not to mount | |
| 354 | −anything, not even read-only mount, or you are going to lose your | |
| 355 | −data. | |
| 356 | − | |
| 357 | −Q: How do I make suspend more verbose? | |
| 358 | − | |
| 359 | −A: If you want to see any non-error kernel messages on the virtual | |
| 360 | −terminal the kernel switches to during suspend, you have to set the | |
| 361 | −kernel console loglevel to at least 4 (KERN_WARNING), for example by | |
| 362 | −doing | |
| 363 | − | |
| 364 | − # save the old loglevel | |
| 365 | − read LOGLEVEL DUMMY < /proc/sys/kernel/printk | |
| 366 | − # set the loglevel so we see the progress bar. | |
| 367 | − # if the level is higher than needed, we leave it alone. | |
| 368 | − if [ $LOGLEVEL -lt 5 ]; then | |
| 369 | − echo 5 > /proc/sys/kernel/printk | |
| 370 | − fi | |
| 371 | − | |
| 372 | − IMG_SZ=0 | |
| 373 | − read IMG_SZ < /sys/power/image_size | |
| 374 | − echo -n disk > /sys/power/state | |
| 375 | − RET=$? | |
| 376 | − # | |
| 377 | − # the logic here is: | |
| 378 | − # if image_size > 0 (without kernel support, IMG_SZ will be zero), | |
| 379 | − # then try again with image_size set to zero. | |
| 380 | − if [ $RET -ne 0 -a $IMG_SZ -ne 0 ]; then # try again with minimal image size | |
| 381 | − echo 0 > /sys/power/image_size | |
| 382 | − echo -n disk > /sys/power/state | |
| 383 | − RET=$? | |
| 384 | − fi | |
| 385 | − | |
| 386 | − # restore previous loglevel | |
| 387 | − echo $LOGLEVEL > /proc/sys/kernel/printk | |
| 388 | − exit $RET | |
| 389 | − | |
| 390 | −Q: Is this true that if I have a mounted filesystem on a USB device and | |
| 391 | −I suspend to disk, I can lose data unless the filesystem has been mounted | |
| 392 | −with "sync"? | |
| 393 | − | |
| 394 | −A: That's right ... if you disconnect that device, you may lose data. | |
| 395 | −In fact, even with "-o sync" you can lose data if your programs have | |
| 396 | −information in buffers they haven't written out to a disk you disconnect, | |
| 397 | −or if you disconnect before the device finished saving data you wrote. | |
| 398 | − | |
| 399 | −Software suspend normally powers down USB controllers, which is equivalent | |
| 400 | −to disconnecting all USB devices attached to your system. | |
| 401 | − | |
| 402 | −Your system might well support low-power modes for its USB controllers | |
| 403 | −while the system is asleep, maintaining the connection, using true sleep | |
| 404 | −modes like "suspend-to-RAM" or "standby". (Don't write "disk" to the | |
| 405 | −/sys/power/state file; write "standby" or "mem".) We've not seen any | |
| 406 | −hardware that can use these modes through software suspend, although in | |
| 407 | −theory some systems might support "platform" modes that won't break the | |
| 408 | −USB connections. | |
| 409 | − | |
| 410 | −Remember that it's always a bad idea to unplug a disk drive containing a | |
| 411 | −mounted filesystem. That's true even when your system is asleep! The | |
| 412 | −safest thing is to unmount all filesystems on removable media (such USB, | |
| 413 | −Firewire, CompactFlash, MMC, external SATA, or even IDE hotplug bays) | |
| 414 | −before suspending; then remount them after resuming. | |
| 415 | − | |
| 416 | −There is a work-around for this problem. For more information, see | |
| 417 | −Documentation/driver-api/usb/persist.rst. | |
| 418 | − | |
| 419 | −Q: Can I suspend-to-disk using a swap partition under LVM? | |
| 420 | − | |
| 421 | −A: Yes and No. You can suspend successfully, but the kernel will not be able | |
| 422 | −to resume on its own. You need an initramfs that can recognize the resume | |
| 423 | −situation, activate the logical volume containing the swap volume (but not | |
| 424 | −touch any filesystems!), and eventually call | |
| 425 | − | |
| 426 | −echo -n "$major:$minor" > /sys/power/resume | |
| 427 | − | |
| 428 | −where $major and $minor are the respective major and minor device numbers of | |
| 429 | −the swap volume. | |
| 430 | − | |
| 431 | −uswsusp works with LVM, too. See http://suspend.sourceforge.net/ | |
| 432 | − | |
| 433 | −Q: I upgraded the kernel from 2.6.15 to 2.6.16. Both kernels were | |
| 434 | −compiled with the similar configuration files. Anyway I found that | |
| 435 | −suspend to disk (and resume) is much slower on 2.6.16 compared to | |
| 436 | −2.6.15. Any idea for why that might happen or how can I speed it up? | |
| 437 | − | |
| 438 | −A: This is because the size of the suspend image is now greater than | |
| 439 | −for 2.6.15 (by saving more data we can get more responsive system | |
| 440 | −after resume). | |
| 441 | − | |
| 442 | −There's the /sys/power/image_size knob that controls the size of the | |
| 443 | −image. If you set it to 0 (eg. by echo 0 > /sys/power/image_size as | |
| 444 | −root), the 2.6.15 behavior should be restored. If it is still too | |
| 445 | −slow, take a look at suspend.sf.net -- userland suspend is faster and | |
| 446 | −supports LZF compression to speed it up further. | |
| @@ -1,5 +1,7 @@ | ||
| 1 | − swsusp/S3 tricks | |
| 2 | − ~~~~~~~~~~~~~~~~ | |
| 1 | +================ | |
| 2 | +swsusp/S3 tricks | |
| 3 | +================ | |
| 4 | + | |
| 3 | 5 | Pavel Machek <pavel@ucw.cz> |
| 4 | 6 | |
| 5 | 7 | If you want to trick swsusp/S3 into working, you might want to try: |
| @@ -1,4 +1,7 @@ | ||
| 1 | +===================================================== | |
| 1 | 2 | Documentation for userland software suspend interface |
| 3 | +===================================================== | |
| 4 | + | |
| 2 | 5 | (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> |
| 3 | 6 | |
| 4 | 7 | First, the warnings at the beginning of swsusp.txt still apply. |
| @@ -30,13 +33,16 @@ called. · 25 unmodified lines | ||
| 30 | 33 | |
| 31 | 34 | The ioctl() commands recognized by the device are: |
| 32 | 35 | |
| 33 | −SNAPSHOT_FREEZE - freeze user space processes (the current process is | |
| 36 | +SNAPSHOT_FREEZE | |
| 37 | + freeze user space processes (the current process is | |
| 34 | 38 | not frozen); this is required for SNAPSHOT_CREATE_IMAGE |
| 35 | 39 | and SNAPSHOT_ATOMIC_RESTORE to succeed |
| 36 | 40 | |
| 37 | −SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE | |
| 41 | +SNAPSHOT_UNFREEZE | |
| 42 | + thaw user space processes frozen by SNAPSHOT_FREEZE | |
| 38 | 43 | |
| 39 | −SNAPSHOT_CREATE_IMAGE - create a snapshot of the system memory; the | |
| 44 | +SNAPSHOT_CREATE_IMAGE | |
| 45 | + create a snapshot of the system memory; the | |
| 40 | 46 | last argument of ioctl() should be a pointer to an int variable, |
| 41 | 47 | the value of which will indicate whether the call returned after |
| 42 | 48 | 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 · 2 unmodified lines | ||
| 45 | 51 | has been created the read() operation can be used to transfer |
| 46 | 52 | it out of the kernel |
| 47 | 53 | |
| 48 | −SNAPSHOT_ATOMIC_RESTORE - restore the system memory state from the | |
| 54 | +SNAPSHOT_ATOMIC_RESTORE | |
| 55 | + restore the system memory state from the | |
| 49 | 56 | uploaded snapshot image; before calling it you should transfer |
| 50 | 57 | the system memory snapshot back to the kernel using the write() |
| 51 | 58 | operation; this call will not succeed if the snapshot |
| 52 | 59 | image is not available to the kernel |
| 53 | 60 | |
| 54 | −SNAPSHOT_FREE - free memory allocated for the snapshot image | |
| 61 | +SNAPSHOT_FREE | |
| 62 | + free memory allocated for the snapshot image | |
| 55 | 63 | |
| 56 | −SNAPSHOT_PREF_IMAGE_SIZE - set the preferred maximum size of the image | |
| 64 | +SNAPSHOT_PREF_IMAGE_SIZE | |
| 65 | + set the preferred maximum size of the image | |
| 57 | 66 | (the kernel will do its best to ensure the image size will not exceed |
| 58 | 67 | this number, but if it turns out to be impossible, the kernel will |
| 59 | 68 | create the smallest image possible) |
| 60 | 69 | |
| 61 | −SNAPSHOT_GET_IMAGE_SIZE - return the actual size of the hibernation image | |
| 70 | +SNAPSHOT_GET_IMAGE_SIZE | |
| 71 | + return the actual size of the hibernation image | |
| 62 | 72 | |
| 63 | −SNAPSHOT_AVAIL_SWAP_SIZE - return the amount of available swap in bytes (the | |
| 73 | +SNAPSHOT_AVAIL_SWAP_SIZE | |
| 74 | + return the amount of available swap in bytes (the | |
| 64 | 75 | last argument should be a pointer to an unsigned int variable that will |
| 65 | 76 | contain the result if the call is successful). |
| 66 | 77 | |
| 67 | −SNAPSHOT_ALLOC_SWAP_PAGE - allocate a swap page from the resume partition | |
| 78 | +SNAPSHOT_ALLOC_SWAP_PAGE | |
| 79 | + allocate a swap page from the resume partition | |
| 68 | 80 | (the last argument should be a pointer to a loff_t variable that |
| 69 | 81 | will contain the swap page offset if the call is successful) |
| 70 | 82 | |
| 71 | −SNAPSHOT_FREE_SWAP_PAGES - free all swap pages allocated by | |
| 83 | +SNAPSHOT_FREE_SWAP_PAGES | |
| 84 | + free all swap pages allocated by | |
| 72 | 85 | SNAPSHOT_ALLOC_SWAP_PAGE |
| 73 | 86 | |
| 74 | −SNAPSHOT_SET_SWAP_AREA - set the resume partition and the offset (in <PAGE_SIZE> | |
| 87 | +SNAPSHOT_SET_SWAP_AREA | |
| 88 | + set the resume partition and the offset (in <PAGE_SIZE> | |
| 75 | 89 | units) from the beginning of the partition at which the swap header is |
| 76 | 90 | located (the last ioctl() argument should point to a struct |
| 77 | 91 | resume_swap_area, as defined in kernel/power/suspend_ioctls.h, |
| 78 | 92 | containing the resume device specification and the offset); for swap |
| 79 | 93 | partitions the offset is always 0, but it is different from zero for |
| 80 | − swap files (see Documentation/power/swsusp-and-swap-files.txt for | |
| 94 | + swap files (see Documentation/power/swsusp-and-swap-files.rst for | |
| 81 | 95 | details). |
| 82 | 96 | |
| 83 | −SNAPSHOT_PLATFORM_SUPPORT - enable/disable the hibernation platform support, | |
| 97 | +SNAPSHOT_PLATFORM_SUPPORT | |
| 98 | + enable/disable the hibernation platform support, | |
| 84 | 99 | depending on the argument value (enable, if the argument is nonzero) |
| 85 | 100 | |
| 86 | −SNAPSHOT_POWER_OFF - make the kernel transition the system to the hibernation | |
| 101 | +SNAPSHOT_POWER_OFF | |
| 102 | + make the kernel transition the system to the hibernation | |
| 87 | 103 | state (eg. ACPI S4) using the platform (eg. ACPI) driver |
| 88 | 104 | |
| 89 | −SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to | |
| 105 | +SNAPSHOT_S2RAM | |
| 106 | + suspend to RAM; using this call causes the kernel to | |
| 90 | 107 | immediately enter the suspend-to-RAM state, so this call must always |
| 91 | 108 | be preceded by the SNAPSHOT_FREEZE call and it is also necessary |
| 92 | 109 | 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 · 5 unmodified lines | ||
| 98 | 115 | |
| 99 | 116 | The device's read() operation can be used to transfer the snapshot image from |
| 100 | 117 | the kernel. It has the following limitations: |
| 118 | + | |
| 101 | 119 | - you cannot read() more than one virtual memory page at a time |
| 102 | 120 | - read()s across page boundaries are impossible (ie. if you read() 1/2 of |
| 103 | − a page in the previous call, you will only be able to read() | |
| 104 | − _at_ _most_ 1/2 of the page in the next call) | |
| 121 | + a page in the previous call, you will only be able to read() | |
| 122 | + **at most** 1/2 of the page in the next call) | |
| 105 | 123 | |
| 106 | 124 | The device's write() operation is used for uploading the system memory snapshot |
| 107 | 125 | into the kernel. It has the same limitations as the read() operation. |
| @@ -143,8 +161,10 @@ preferably using mlockall(), before calling SNAPSHOT_FREEZE. · 35 unmodified lines | ||
| 143 | 161 | The suspending utility MUST check the value stored by SNAPSHOT_CREATE_IMAGE |
| 144 | 162 | in the memory location pointed to by the last argument of ioctl() and proceed |
| 145 | 163 | in accordance with it: |
| 164 | + | |
| 146 | 165 | 1. If the value is 1 (ie. the system memory snapshot has just been |
| 147 | 166 | created and the system is ready for saving it): |
| 167 | + | |
| 148 | 168 | (a) The suspending utility MUST NOT close the snapshot device |
| 149 | 169 | _unless_ the whole suspend procedure is to be cancelled, in |
| 150 | 170 | which case, if the snapshot image has already been saved, the |
| @@ -158,6 +178,7 @@ in accordance with it: · 7 unmodified lines | ||
| 158 | 178 | called. However, it MAY mount a file system that was not |
| 159 | 179 | mounted at that time and perform some operations on it (eg. |
| 160 | 180 | use it for saving the image). |
| 181 | + | |
| 161 | 182 | 2. If the value is 0 (ie. the system state has just been restored from |
| 162 | 183 | the snapshot image), the suspending utility MUST close the snapshot |
| 163 | 184 | device. Afterwards it will be treated as a regular userland process, |
| @@ -1,7 +1,8 @@ | ||
| 1 | +=========================== | |
| 2 | +Video issues with S3 resume | |
| 3 | +=========================== | |
| 1 | 4 | |
| 2 | − Video issues with S3 resume | |
| 3 | − ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 4 | − 2003-2006, Pavel Machek | |
| 5 | +2003-2006, Pavel Machek | |
| 5 | 6 | |
| 6 | 7 | During S3 resume, hardware needs to be reinitialized. For most |
| 7 | 8 | devices, this is easy, and kernel driver knows how to do |
| @@ -41,37 +42,37 @@ There are a few types of systems where video works after S3 resume: · 33 unmodified lines | ||
| 41 | 42 | (1) systems where video state is preserved over S3. |
| 42 | 43 | |
| 43 | 44 | (2) systems where it is possible to call the video BIOS during S3 |
| 44 | − resume. Unfortunately, it is not correct to call the video BIOS at | |
| 45 | − that point, but it happens to work on some machines. Use | |
| 46 | − acpi_sleep=s3_bios. | |
| 45 | + resume. Unfortunately, it is not correct to call the video BIOS at | |
| 46 | + that point, but it happens to work on some machines. Use | |
| 47 | + acpi_sleep=s3_bios. | |
| 47 | 48 | |
| 48 | 49 | (3) systems that initialize video card into vga text mode and where |
| 49 | − the BIOS works well enough to be able to set video mode. Use | |
| 50 | − acpi_sleep=s3_mode on these. | |
| 50 | + the BIOS works well enough to be able to set video mode. Use | |
| 51 | + acpi_sleep=s3_mode on these. | |
| 51 | 52 | |
| 52 | 53 | (4) on some systems s3_bios kicks video into text mode, and |
| 53 | − acpi_sleep=s3_bios,s3_mode is needed. | |
| 54 | + acpi_sleep=s3_bios,s3_mode is needed. | |
| 54 | 55 | |
| 55 | 56 | (5) radeon systems, where X can soft-boot your video card. You'll need |
| 56 | − a new enough X, and a plain text console (no vesafb or radeonfb). See | |
| 57 | − http://www.doesi.gmxhome.de/linux/tm800s3/s3.html for more information. | |
| 58 | − Alternatively, you should use vbetool (6) instead. | |
| 57 | + a new enough X, and a plain text console (no vesafb or radeonfb). See | |
| 58 | + http://www.doesi.gmxhome.de/linux/tm800s3/s3.html for more information. | |
| 59 | + Alternatively, you should use vbetool (6) instead. | |
| 59 | 60 | |
| 60 | 61 | (6) other radeon systems, where vbetool is enough to bring system back |
| 61 | − to life. It needs text console to be working. Do vbetool vbestate | |
| 62 | − save > /tmp/delme; echo 3 > /proc/acpi/sleep; vbetool post; vbetool | |
| 63 | − vbestate restore < /tmp/delme; setfont <whatever>, and your video | |
| 64 | − should work. | |
| 62 | + to life. It needs text console to be working. Do vbetool vbestate | |
| 63 | + save > /tmp/delme; echo 3 > /proc/acpi/sleep; vbetool post; vbetool | |
| 64 | + vbestate restore < /tmp/delme; setfont <whatever>, and your video | |
| 65 | + should work. | |
| 65 | 66 | |
| 66 | 67 | (7) on some systems, it is possible to boot most of kernel, and then |
| 67 | − POSTing bios works. Ole Rohne has patch to do just that at | |
| 68 | − http://dev.gentoo.org/~marineam/patch-radeonfb-2.6.11-rc2-mm2. | |
| 68 | + POSTing bios works. Ole Rohne has patch to do just that at | |
| 69 | + http://dev.gentoo.org/~marineam/patch-radeonfb-2.6.11-rc2-mm2. | |
| 69 | 70 | |
| 70 | −(8) on some systems, you can use the video_post utility and or | |
| 71 | − do echo 3 > /sys/power/state && /usr/sbin/video_post - which will | |
| 72 | − initialize the display in console mode. If you are in X, you can switch | |
| 73 | − to a virtual terminal and back to X using CTRL+ALT+F1 - CTRL+ALT+F7 to get | |
| 74 | − the display working in graphical mode again. | |
| 71 | +(8) on some systems, you can use the video_post utility and or | |
| 72 | + do echo 3 > /sys/power/state && /usr/sbin/video_post - which will | |
| 73 | + initialize the display in console mode. If you are in X, you can switch | |
| 74 | + to a virtual terminal and back to X using CTRL+ALT+F1 - CTRL+ALT+F7 to get | |
| 75 | + the display working in graphical mode again. | |
| 75 | 76 | |
| 76 | 77 | Now, if you pass acpi_sleep=something, and it does not work with your |
| 77 | 78 | bios, you'll get a hard crash during resume. Be careful. Also it is |
| @@ -87,99 +88,126 @@ chance of working. · 9 unmodified lines | ||
| 87 | 88 | |
| 88 | 89 | Table of known working notebooks: |
| 89 | 90 | |
| 91 | + | |
| 92 | +=============================== =============================================== | |
| 90 | 93 | Model hack (or "how to do it") |
| 91 | −------------------------------------------------------------------------------ | |
| 94 | +=============================== =============================================== | |
| 92 | 95 | Acer Aspire 1406LC ole's late BIOS init (7), turn off DRI |
| 93 | 96 | Acer TM 230 s3_bios (2) |
| 94 | 97 | Acer TM 242FX vbetool (6) |
| 95 | 98 | Acer TM C110 video_post (8) |
| 96 | −Acer TM C300 vga=normal (only suspend on console, not in X), vbetool (6) or video_post (8) | |
| 99 | +Acer TM C300 vga=normal (only suspend on console, not in X), | |
| 100 | + vbetool (6) or video_post (8) | |
| 97 | 101 | Acer TM 4052LCi s3_bios (2) |
| 98 | 102 | Acer TM 636Lci s3_bios,s3_mode (4) |
| 99 | −Acer TM 650 (Radeon M7) vga=normal plus boot-radeon (5) gets text console back | |
| 100 | −Acer TM 660 ??? (*) | |
| 101 | −Acer TM 800 vga=normal, X patches, see webpage (5) or vbetool (6) | |
| 102 | −Acer TM 803 vga=normal, X patches, see webpage (5) or vbetool (6) | |
| 103 | +Acer TM 650 (Radeon M7) vga=normal plus boot-radeon (5) gets text | |
| 104 | + console back | |
| 105 | +Acer TM 660 ??? [#f1]_ | |
| 106 | +Acer TM 800 vga=normal, X patches, see webpage (5) | |
| 107 | + or vbetool (6) | |
| 108 | +Acer TM 803 vga=normal, X patches, see webpage (5) | |
| 109 | + or vbetool (6) | |
| 103 | 110 | Acer TM 803LCi vga=normal, vbetool (6) |
| 104 | 111 | Arima W730a vbetool needed (6) |
| 105 | −Asus L2400D s3_mode (3)(***) (S1 also works OK) | |
| 112 | +Asus L2400D s3_mode (3) [#f2]_ (S1 also works OK) | |
| 106 | 113 | Asus L3350M (SiS 740) (6) |
| 107 | 114 | Asus L3800C (Radeon M7) s3_bios (2) (S1 also works OK) |
| 108 | −Asus M6887Ne vga=normal, s3_bios (2), use radeon driver instead of fglrx in x.org | |
| 115 | +Asus M6887Ne vga=normal, s3_bios (2), use radeon driver | |
| 116 | + instead of fglrx in x.org | |
| 109 | 117 | Athlon64 desktop prototype s3_bios (2) |
| 110 | −Compal CL-50 ??? (*) | |
| 118 | +Compal CL-50 ??? [#f1]_ | |
| 111 | 119 | Compaq Armada E500 - P3-700 none (1) (S1 also works OK) |
| 112 | 120 | Compaq Evo N620c vga=normal, s3_bios (2) |
| 113 | 121 | Dell 600m, ATI R250 Lf none (1), but needs xorg-x11-6.8.1.902-1 |
| 114 | 122 | Dell D600, ATI RV250 vga=normal and X, or try vbestate (6) |
| 115 | −Dell D610 vga=normal and X (possibly vbestate (6) too, but not tested) | |
| 116 | −Dell Inspiron 4000 ??? (*) | |
| 117 | −Dell Inspiron 500m ??? (*) | |
| 123 | +Dell D610 vga=normal and X (possibly vbestate (6) too, | |
| 124 | + but not tested) | |
| 125 | +Dell Inspiron 4000 ??? [#f1]_ | |
| 126 | +Dell Inspiron 500m ??? [#f1]_ | |
| 118 | 127 | Dell Inspiron 510m ??? |
| 119 | 128 | Dell Inspiron 5150 vbetool needed (6) |
| 120 | −Dell Inspiron 600m ??? (*) | |
| 121 | −Dell Inspiron 8200 ??? (*) | |
| 122 | −Dell Inspiron 8500 ??? (*) | |
| 123 | −Dell Inspiron 8600 ??? (*) | |
| 124 | −eMachines athlon64 machines vbetool needed (6) (someone please get me model #s) | |
| 125 | −HP NC6000 s3_bios, may not use radeonfb (2); or vbetool (6) | |
| 126 | −HP NX7000 ??? (*) | |
| 127 | −HP Pavilion ZD7000 vbetool post needed, need open-source nv driver for X | |
| 129 | +Dell Inspiron 600m ??? [#f1]_ | |
| 130 | +Dell Inspiron 8200 ??? [#f1]_ | |
| 131 | +Dell Inspiron 8500 ??? [#f1]_ | |
| 132 | +Dell Inspiron 8600 ??? [#f1]_ | |
| 133 | +eMachines athlon64 machines vbetool needed (6) (someone please get | |
| 134 | + me model #s) | |
| 135 | +HP NC6000 s3_bios, may not use radeonfb (2); | |
| 136 | + or vbetool (6) | |
| 137 | +HP NX7000 ??? [#f1]_ | |
| 138 | +HP Pavilion ZD7000 vbetool post needed, need open-source nv | |
| 139 | + driver for X | |
| 128 | 140 | HP Omnibook XE3 athlon version none (1) |
| 129 | 141 | HP Omnibook XE3GC none (1), video is S3 Savage/IX-MV |
| 130 | 142 | HP Omnibook XE3L-GF vbetool (6) |
| 131 | 143 | HP Omnibook 5150 none (1), (S1 also works OK) |
| 132 | −IBM TP T20, model 2647-44G none (1), video is S3 Inc. 86C270-294 Savage/IX-MV, vesafb gets "interesting" but X work. | |
| 133 | −IBM TP A31 / Type 2652-M5G s3_mode (3) [works ok with BIOS 1.04 2002-08-23, but not at all with BIOS 1.11 2004-11-05 :-(] | |
| 144 | +IBM TP T20, model 2647-44G none (1), video is S3 Inc. 86C270-294 | |
| 145 | + Savage/IX-MV, vesafb gets "interesting" | |
| 146 | + but X work. | |
| 147 | +IBM TP A31 / Type 2652-M5G s3_mode (3) [works ok with | |
| 148 | + BIOS 1.04 2002-08-23, but not at all with | |
| 149 | + BIOS 1.11 2004-11-05 :-(] | |
| 134 | 150 | IBM TP R32 / Type 2658-MMG none (1) |
| 135 | −IBM TP R40 2722B3G ??? (*) | |
| 151 | +IBM TP R40 2722B3G ??? [#f1]_ | |
| 136 | 152 | IBM TP R50p / Type 1832-22U s3_bios (2) |
| 137 | 153 | IBM TP R51 none (1) |
| 138 | −IBM TP T30 236681A ??? (*) | |
| 154 | +IBM TP T30 236681A ??? [#f1]_ | |
| 139 | 155 | IBM TP T40 / Type 2373-MU4 none (1) |
| 140 | 156 | IBM TP T40p none (1) |
| 141 | 157 | IBM TP R40p s3_bios (2) |
| 142 | 158 | IBM TP T41p s3_bios (2), switch to X after resume |
| 143 | 159 | IBM TP T42 s3_bios (2) |
| 144 | 160 | IBM ThinkPad T42p (2373-GTG) s3_bios (2) |
| 145 | −IBM TP X20 ??? (*) | |
| 161 | +IBM TP X20 ??? [#f1]_ | |
| 146 | 162 | IBM TP X30 s3_bios, s3_mode (4) |
| 147 | −IBM TP X31 / Type 2672-XXH none (1), use radeontool (http://fdd.com/software/radeon/) to turn off backlight. | |
| 148 | −IBM TP X32 none (1), but backlight is on and video is trashed after long suspend. s3_bios,s3_mode (4) works too. Perhaps that gets better results? | |
| 163 | +IBM TP X31 / Type 2672-XXH none (1), use radeontool | |
| 164 | + (http://fdd.com/software/radeon/) to | |
| 165 | + turn off backlight. | |
| 166 | +IBM TP X32 none (1), but backlight is on and video is | |
| 167 | + trashed after long suspend. s3_bios, | |
| 168 | + s3_mode (4) works too. Perhaps that gets | |
| 169 | + better results? | |
| 149 | 170 | IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4) |
| 150 | −IBM TP 600e none(1), but a switch to console and back to X is needed | |
| 151 | −Medion MD4220 ??? (*) | |
| 171 | +IBM TP 600e none(1), but a switch to console and | |
| 172 | + back to X is needed | |
| 173 | +Medion MD4220 ??? [#f1]_ | |
| 152 | 174 | Samsung P35 vbetool needed (6) |
| 153 | 175 | Sharp PC-AR10 (ATI rage) none (1), backlight does not switch off |
| 154 | 176 | Sony Vaio PCG-C1VRX/K s3_bios (2) |
| 155 | −Sony Vaio PCG-F403 ??? (*) | |
| 177 | +Sony Vaio PCG-F403 ??? [#f1]_ | |
| 156 | 178 | Sony Vaio PCG-GRT995MP none (1), works with 'nv' X driver |
| 157 | −Sony Vaio PCG-GR7/K none (1), but needs radeonfb, use radeontool (http://fdd.com/software/radeon/) to turn off backlight. | |
| 158 | −Sony Vaio PCG-N505SN ??? (*) | |
| 179 | +Sony Vaio PCG-GR7/K none (1), but needs radeonfb, use | |
| 180 | + radeontool (http://fdd.com/software/radeon/) | |
| 181 | + to turn off backlight. | |
| 182 | +Sony Vaio PCG-N505SN ??? [#f1]_ | |
| 159 | 183 | Sony Vaio vgn-s260 X or boot-radeon can init it (5) |
| 160 | −Sony Vaio vgn-S580BH vga=normal, but suspend from X. Console will be blank unless you return to X. | |
| 184 | +Sony Vaio vgn-S580BH vga=normal, but suspend from X. Console will | |
| 185 | + be blank unless you return to X. | |
| 161 | 186 | Sony Vaio vgn-FS115B s3_bios (2),s3_mode (4) |
| 162 | 187 | Toshiba Libretto L5 none (1) |
| 163 | 188 | Toshiba Libretto 100CT/110CT vbetool (6) |
| 164 | 189 | Toshiba Portege 3020CT s3_mode (3) |
| 165 | 190 | Toshiba Satellite 4030CDT s3_mode (3) (S1 also works OK) |
| 166 | 191 | Toshiba Satellite 4080XCDT s3_mode (3) (S1 also works OK) |
| 167 | −Toshiba Satellite 4090XCDT ??? (*) | |
| 168 | −Toshiba Satellite P10-554 s3_bios,s3_mode (4)(****) | |
| 192 | +Toshiba Satellite 4090XCDT ??? [#f1]_ | |
| 193 | +Toshiba Satellite P10-554 s3_bios,s3_mode (4)[#f3]_ | |
| 169 | 194 | Toshiba M30 (2) xor X with nvidia driver using internal AGP |
| 170 | −Uniwill 244IIO ??? (*) | |
| 195 | +Uniwill 244IIO ??? [#f1]_ | |
| 196 | +=============================== =============================================== | |
| 171 | 197 | |
| 172 | 198 | Known working desktop systems |
| 173 | 199 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 174 | 200 | |
| 201 | +=================== ============================= ======================== | |
| 175 | 202 | Mainboard Graphics card hack (or "how to do it") |
| 176 | −------------------------------------------------------------------------------ | |
| 203 | +=================== ============================= ======================== | |
| 177 | 204 | Asus A7V8X nVidia RIVA TNT2 model 64 s3_bios,s3_mode (4) |
| 205 | +=================== ============================= ======================== | |
| 178 | 206 | |
| 179 | 207 | |
| 180 | −(*) from https://wiki.ubuntu.com/HoaryPMResults, not sure | |
| 181 | − which options to use. If you know, please tell me. | |
| 208 | +.. [#f1] from https://wiki.ubuntu.com/HoaryPMResults, not sure | |
| 209 | + which options to use. If you know, please tell me. | |
| 182 | 210 | |
| 183 | −(***) To be tested with a newer kernel. | |
| 211 | +.. [#f2] To be tested with a newer kernel. | |
| 184 | 212 | |
| 185 | −(****) Not with SMP kernel, UP only. | |
| 213 | +.. [#f3] Not with SMP kernel, UP only. | |
| @@ -117,7 +117,7 @@ PM support: · 116 unmodified lines | ||
| 117 | 117 | implemented") error. You should also try to make sure that your |
| 118 | 118 | driver uses as little power as possible when it's not doing |
| 119 | 119 | anything. For the driver testing instructions see |
| 120 | − Documentation/power/drivers-testing.txt and for a relatively | |
| 120 | + Documentation/power/drivers-testing.rst and for a relatively | |
| 121 | 121 | complete overview of the power management issues related to |
| 122 | 122 | drivers see :ref:`Documentation/driver-api/pm/devices.rst <driverapi_pm_devices>`. |
| 123 | 123 | |
| @@ -22,7 +22,7 @@ the highest. · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | The actual EM used by EAS is _not_ maintained by the scheduler, but by a |
| 24 | 24 | dedicated framework. For details about this framework and what it provides, |
| 25 | −please refer to its documentation (see Documentation/power/energy-model.txt). | |
| 25 | +please refer to its documentation (see Documentation/power/energy-model.rst). | |
| 26 | 26 | |
| 27 | 27 | |
| 28 | 28 | 2. Background and Terminology |
| @@ -81,7 +81,7 @@ through the arch_scale_cpu_capacity() callback. · 52 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | The rest of platform knowledge used by EAS is directly read from the Energy |
| 83 | 83 | Model (EM) framework. The EM of a platform is composed of a power cost table |
| 84 | −per 'performance domain' in the system (see Documentation/power/energy-model.txt | |
| 84 | +per 'performance domain' in the system (see Documentation/power/energy-model.rst | |
| 85 | 85 | for futher details about performance domains). |
| 86 | 86 | |
| 87 | 87 | 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. · 264 unmodified lines | ||
| 352 | 352 | EAS uses the EM of a platform to estimate the impact of scheduling decisions on |
| 353 | 353 | energy. So, your platform must provide power cost tables to the EM framework in |
| 354 | 354 | order to make EAS start. To do so, please refer to documentation of the |
| 355 | −independent EM framework in Documentation/power/energy-model.txt. | |
| 355 | +independent EM framework in Documentation/power/energy-model.rst. | |
| 356 | 356 | |
| 357 | 357 | Please also note that the scheduling domains need to be re-built after the |
| 358 | 358 | EM has been registered in order to start EAS. |
| @@ -151,7 +151,7 @@ At the runtime you can disable idle states with below methods: · 150 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | It is possible to disable CPU idle states by way of the PM QoS |
| 153 | 153 | subsystem, more specifically by using the "/dev/cpu_dma_latency" |
| 154 | −interface (see Documentation/power/pm_qos_interface.txt for more | |
| 154 | +interface (see Documentation/power/pm_qos_interface.rst for more | |
| 155 | 155 | details). As specified in the PM QoS documentation the requested |
| 156 | 156 | parameter will stay in effect until the file descriptor is released. |
| 157 | 157 | For example: |
| @@ -97,7 +97,7 @@ Linux 2.6: · 96 unmodified lines | ||
| 97 | 97 | 函数定义成返回 -ENOSYS(功能未实现)错误。你还应该尝试确 |
| 98 | 98 | 保你的驱动在什么都不干的情况下将耗电降到最低。要获得驱动 |
| 99 | 99 | 程序测试的指导,请参阅 |
| 100 | − Documentation/power/drivers-testing.txt。有关驱动程序电 | |
| 100 | + Documentation/power/drivers-testing.rst。有关驱动程序电 | |
| 101 | 101 | 源管理问题相对全面的概述,请参阅 |
| 102 | 102 | Documentation/driver-api/pm/devices.rst。 |
| 103 | 103 | |
| @@ -6446,7 +6446,7 @@ M: "Rafael J. Wysocki" <rjw@rjwysocki.net> · 6445 unmodified lines | ||
| 6446 | 6446 | M: Pavel Machek <pavel@ucw.cz> |
| 6447 | 6447 | L: linux-pm@vger.kernel.org |
| 6448 | 6448 | S: Supported |
| 6449 | −F: Documentation/power/freezing-of-tasks.txt | |
| 6449 | +F: Documentation/power/freezing-of-tasks.rst | |
| 6450 | 6450 | F: include/linux/freezer.h |
| 6451 | 6451 | F: kernel/freezer.c |
| 6452 | 6452 | |
| @@ -11764,7 +11764,7 @@ S: Maintained · 5311 unmodified lines | ||
| 11764 | 11764 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git |
| 11765 | 11765 | F: drivers/opp/ |
| 11766 | 11766 | F: include/linux/pm_opp.h |
| 11767 | −F: Documentation/power/opp.txt | |
| 11767 | +F: Documentation/power/opp.rst | |
| 11768 | 11768 | F: Documentation/devicetree/bindings/opp/ |
| 11769 | 11769 | |
| 11770 | 11770 | OPL4 DRIVER |
| @@ -2447,7 +2447,7 @@ menuconfig APM · 2446 unmodified lines | ||
| 2447 | 2447 | machines with more than one CPU. |
| 2448 | 2448 | |
| 2449 | 2449 | In order to use APM, you will need supporting software. For location |
| 2450 | − and more information, read <file:Documentation/power/apm-acpi.txt> | |
| 2450 | + and more information, read <file:Documentation/power/apm-acpi.rst> | |
| 2451 | 2451 | and the Battery Powered Linux mini-HOWTO, available from |
| 2452 | 2452 | <http://www.tldp.org/docs.html#howto>. |
| 2453 | 2453 | |
| @@ -1175,7 +1175,7 @@ struct skl_wm_params { · 1174 unmodified lines | ||
| 1175 | 1175 | * to be disabled. This shouldn't happen and we'll print some error messages in |
| 1176 | 1176 | * case it happens. |
| 1177 | 1177 | * |
| 1178 | − * For more, read the Documentation/power/runtime_pm.txt. | |
| 1178 | + * For more, read the Documentation/power/runtime_pm.rst. | |
| 1179 | 1179 | */ |
| 1180 | 1180 | struct i915_runtime_pm { |
| 1181 | 1181 | atomic_t wakeref_count; |
| @@ -10,4 +10,4 @@ config PM_OPP · 9 unmodified lines | ||
| 10 | 10 | OPP layer organizes the data internally using device pointers |
| 11 | 11 | representing individual voltage domains and provides SOC |
| 12 | 12 | implementations a ready to use framework to manage OPPs. |
| 13 | − For more information, read <file:Documentation/power/opp.txt> | |
| 13 | + For more information, read <file:Documentation/power/opp.rst> | |
| @@ -607,7 +607,7 @@ int power_supply_get_battery_info(struct power_supply *psy, · 606 unmodified lines | ||
| 607 | 607 | |
| 608 | 608 | /* The property and field names below must correspond to elements |
| 609 | 609 | * in enum power_supply_property. For reasoning, see |
| 610 | − * Documentation/power/power_supply_class.txt. | |
| 610 | + * Documentation/power/power_supply_class.rst. | |
| 611 | 611 | */ |
| 612 | 612 | |
| 613 | 613 | of_property_read_u32(battery_np, "energy-full-design-microwatt-hours", |
| @@ -52,7 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | * irq line disabled until the threaded handler has been run. |
| 53 | 53 | * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend. Does not guarantee |
| 54 | 54 | * that this interrupt will wake the system from a suspended |
| 55 | − * state. See Documentation/power/suspend-and-interrupts.txt | |
| 55 | + * state. See Documentation/power/suspend-and-interrupts.rst | |
| 56 | 56 | * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set |
| 57 | 57 | * IRQF_NO_THREAD - Interrupt cannot be threaded |
| 58 | 58 | * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device |
| @@ -807,7 +807,7 @@ struct module; · 806 unmodified lines | ||
| 807 | 807 | * @suspend_late: Put device into low power state. |
| 808 | 808 | * @resume_early: Wake device from low power state. |
| 809 | 809 | * @resume: Wake device from low power state. |
| 810 | − * (Please see Documentation/power/pci.txt for descriptions | |
| 810 | + * (Please see Documentation/power/pci.rst for descriptions | |
| 811 | 811 | * of PCI Power Management and the related functions.) |
| 812 | 812 | * @shutdown: Hook into reboot_notifier_list (kernel/sys.c). |
| 813 | 813 | * Intended to stop any idling DMA operations. |
| @@ -284,7 +284,7 @@ typedef struct pm_message { · 283 unmodified lines | ||
| 284 | 284 | * actions to be performed by a device driver's callbacks generally depend on |
| 285 | 285 | * the platform and subsystem the device belongs to. |
| 286 | 286 | * |
| 287 | − * Refer to Documentation/power/runtime_pm.txt for more information about the | |
| 287 | + * Refer to Documentation/power/runtime_pm.rst for more information about the | |
| 288 | 288 | * role of the @runtime_suspend(), @runtime_resume() and @runtime_idle() |
| 289 | 289 | * callbacks in device runtime power management. |
| 290 | 290 | */ |
| @@ -65,7 +65,7 @@ config HIBERNATION · 64 unmodified lines | ||
| 65 | 65 | need to run mkswap against the swap partition used for the suspend. |
| 66 | 66 | |
| 67 | 67 | It also works with swap files to a limited extent (for details see |
| 68 | − <file:Documentation/power/swsusp-and-swap-files.txt>). | |
| 68 | + <file:Documentation/power/swsusp-and-swap-files.rst>). | |
| 69 | 69 | |
| 70 | 70 | Right now you may boot without resuming and resume later but in the |
| 71 | 71 | meantime you cannot use the swap partition(s)/file(s) involved in |
| @@ -74,7 +74,7 @@ config HIBERNATION · 2 unmodified lines | ||
| 74 | 74 | MOUNT any journaled filesystems mounted before the suspend or they |
| 75 | 75 | will get corrupted in a nasty way. |
| 76 | 76 | |
| 77 | − For more information take a look at <file:Documentation/power/swsusp.txt>. | |
| 77 | + For more information take a look at <file:Documentation/power/swsusp.rst>. | |
| 78 | 78 | |
| 79 | 79 | config ARCH_SAVE_PAGE_KEYS |
| 80 | 80 | bool |
| @@ -255,7 +255,7 @@ config APM_EMULATION · 174 unmodified lines | ||
| 255 | 255 | notification of APM "events" (e.g. battery status change). |
| 256 | 256 | |
| 257 | 257 | In order to use APM, you will need supporting software. For location |
| 258 | − and more information, read <file:Documentation/power/apm-acpi.txt> | |
| 258 | + and more information, read <file:Documentation/power/apm-acpi.rst> | |
| 259 | 259 | and the Battery Powered Linux mini-HOWTO, available from |
| 260 | 260 | <http://www.tldp.org/docs.html#howto>. |
| 261 | 261 | |
| @@ -165,7 +165,7 @@ config CFG80211_DEFAULT_PS · 164 unmodified lines | ||
| 165 | 165 | |
| 166 | 166 | If this causes your applications to misbehave you should fix your |
| 167 | 167 | applications instead -- they need to register their network |
| 168 | − latency requirement, see Documentation/power/pm_qos_interface.txt. | |
| 168 | + latency requirement, see Documentation/power/pm_qos_interface.rst. | |
| 169 | 169 | |
| 170 | 170 | config CFG80211_DEBUGFS |
| 171 | 171 | bool "cfg80211 DebugFS entries" |