diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-power | 29 | ||||
-rw-r--r-- | Documentation/kernel-parameters.txt | 7 | ||||
-rw-r--r-- | Documentation/power/states.txt | 87 | ||||
-rw-r--r-- | kernel/power/main.c | 12 | ||||
-rw-r--r-- | kernel/power/suspend.c | 32 |
5 files changed, 119 insertions, 48 deletions
diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power index 64c9276e9421..f4551816329e 100644 --- a/Documentation/ABI/testing/sysfs-power +++ b/Documentation/ABI/testing/sysfs-power | |||
@@ -7,19 +7,30 @@ Description: | |||
7 | subsystem. | 7 | subsystem. |
8 | 8 | ||
9 | What: /sys/power/state | 9 | What: /sys/power/state |
10 | Date: August 2006 | 10 | Date: May 2014 |
11 | Contact: Rafael J. Wysocki <rjw@rjwysocki.net> | 11 | Contact: Rafael J. Wysocki <rjw@rjwysocki.net> |
12 | Description: | 12 | Description: |
13 | The /sys/power/state file controls the system power state. | 13 | The /sys/power/state file controls system sleep states. |
14 | Reading from this file returns what states are supported, | 14 | Reading from this file returns the available sleep state |
15 | which is hard-coded to 'freeze' (Low-Power Idle), 'standby' | 15 | labels, which may be "mem", "standby", "freeze" and "disk" |
16 | (Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk' | 16 | (hibernation). The meanings of the first three labels depend on |
17 | (Suspend-to-Disk). | 17 | the relative_sleep_states command line argument as follows: |
18 | 1) relative_sleep_states = 1 | ||
19 | "mem", "standby", "freeze" represent non-hibernation sleep | ||
20 | states from the deepest ("mem", always present) to the | ||
21 | shallowest ("freeze"). "standby" and "freeze" may or may | ||
22 | not be present depending on the capabilities of the | ||
23 | platform. "freeze" can only be present if "standby" is | ||
24 | present. | ||
25 | 2) relative_sleep_states = 0 (default) | ||
26 | "mem" - "suspend-to-RAM", present if supported. | ||
27 | "standby" - "power-on suspend", present if supported. | ||
28 | "freeze" - "suspend-to-idle", always present. | ||
18 | 29 | ||
19 | Writing to this file one of these strings causes the system to | 30 | Writing to this file one of these strings causes the system to |
20 | transition into that state. Please see the file | 31 | transition into the corresponding state, if available. See |
21 | Documentation/power/states.txt for a description of each of | 32 | Documentation/power/states.txt for a description of what |
22 | these states. | 33 | "suspend-to-RAM", "power-on suspend" and "suspend-to-idle" mean. |
23 | 34 | ||
24 | What: /sys/power/disk | 35 | What: /sys/power/disk |
25 | Date: September 2006 | 36 | Date: September 2006 |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 43842177b771..e19a88b63eeb 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2889,6 +2889,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2889 | [KNL, SMP] Set scheduler's default relax_domain_level. | 2889 | [KNL, SMP] Set scheduler's default relax_domain_level. |
2890 | See Documentation/cgroups/cpusets.txt. | 2890 | See Documentation/cgroups/cpusets.txt. |
2891 | 2891 | ||
2892 | relative_sleep_states= | ||
2893 | [SUSPEND] Use sleep state labeling where the deepest | ||
2894 | state available other than hibernation is always "mem". | ||
2895 | Format: { "0" | "1" } | ||
2896 | 0 -- Traditional sleep state labels. | ||
2897 | 1 -- Relative sleep state labels. | ||
2898 | |||
2892 | reserve= [KNL,BUGS] Force the kernel to ignore some iomem area | 2899 | reserve= [KNL,BUGS] Force the kernel to ignore some iomem area |
2893 | 2900 | ||
2894 | reservetop= [X86-32] | 2901 | reservetop= [X86-32] |
diff --git a/Documentation/power/states.txt b/Documentation/power/states.txt index 442d43df9b25..50f3ef9177c1 100644 --- a/Documentation/power/states.txt +++ b/Documentation/power/states.txt | |||
@@ -1,62 +1,87 @@ | |||
1 | System Power Management Sleep States | ||
1 | 2 | ||
2 | System Power Management States | 3 | (C) 2014 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
3 | 4 | ||
5 | The kernel supports up to four system sleep states generically, although three | ||
6 | of them depend on the platform support code to implement the low-level details | ||
7 | for each state. | ||
4 | 8 | ||
5 | The kernel supports four power management states generically, though | 9 | The states are represented by strings that can be read or written to the |
6 | one is generic and the other three are dependent on platform support | 10 | /sys/power/state file. Those strings may be "mem", "standby", "freeze" and |
7 | code to implement the low-level details for each state. | 11 | "disk", where the last one always represents hibernation (Suspend-To-Disk) and |
8 | This file describes each state, what they are | 12 | the meaning of the remaining ones depends on the relative_sleep_states command |
9 | commonly called, what ACPI state they map to, and what string to write | 13 | line argument. |
10 | to /sys/power/state to enter that state | ||
11 | 14 | ||
12 | state: Freeze / Low-Power Idle | 15 | For relative_sleep_states=1, the strings "mem", "standby" and "freeze" label the |
16 | available non-hibernation sleep states from the deepest to the shallowest, | ||
17 | respectively. In that case, "mem" is always present in /sys/power/state, | ||
18 | because there is at least one non-hibernation sleep state in every system. If | ||
19 | the given system supports two non-hibernation sleep states, "standby" is present | ||
20 | in /sys/power/state in addition to "mem". If the system supports three | ||
21 | non-hibernation sleep states, "freeze" will be present in /sys/power/state in | ||
22 | addition to "mem" and "standby". | ||
23 | |||
24 | For relative_sleep_states=0, which is the default, the following descriptions | ||
25 | apply. | ||
26 | |||
27 | state: Suspend-To-Idle | ||
13 | ACPI state: S0 | 28 | ACPI state: S0 |
14 | String: "freeze" | 29 | Label: "freeze" |
15 | 30 | ||
16 | This state is a generic, pure software, light-weight, low-power state. | 31 | This state is a generic, pure software, light-weight, system sleep state. |
17 | It allows more energy to be saved relative to idle by freezing user | 32 | It allows more energy to be saved relative to runtime idle by freezing user |
18 | space and putting all I/O devices into low-power states (possibly | 33 | space and putting all I/O devices into low-power states (possibly |
19 | lower-power than available at run time), such that the processors can | 34 | lower-power than available at run time), such that the processors can |
20 | spend more time in their idle states. | 35 | spend more time in their idle states. |
21 | This state can be used for platforms without Standby/Suspend-to-RAM | 36 | |
37 | This state can be used for platforms without Power-On Suspend/Suspend-to-RAM | ||
22 | support, or it can be used in addition to Suspend-to-RAM (memory sleep) | 38 | support, or it can be used in addition to Suspend-to-RAM (memory sleep) |
23 | to provide reduced resume latency. | 39 | to provide reduced resume latency. It is always supported. |
24 | 40 | ||
25 | 41 | ||
26 | State: Standby / Power-On Suspend | 42 | State: Standby / Power-On Suspend |
27 | ACPI State: S1 | 43 | ACPI State: S1 |
28 | String: "standby" | 44 | Label: "standby" |
29 | 45 | ||
30 | This state offers minimal, though real, power savings, while providing | 46 | This state, if supported, offers moderate, though real, power savings, while |
31 | a very low-latency transition back to a working system. No operating | 47 | providing a relatively low-latency transition back to a working system. No |
32 | state is lost (the CPU retains power), so the system easily starts up | 48 | operating state is lost (the CPU retains power), so the system easily starts up |
33 | again where it left off. | 49 | again where it left off. |
34 | 50 | ||
35 | We try to put devices in a low-power state equivalent to D1, which | 51 | In addition to freezing user space and putting all I/O devices into low-power |
36 | also offers low power savings, but low resume latency. Not all devices | 52 | states, which is done for Suspend-To-Idle too, nonboot CPUs are taken offline |
37 | support D1, and those that don't are left on. | 53 | and all low-level system functions are suspended during transitions into this |
54 | state. For this reason, it should allow more energy to be saved relative to | ||
55 | Suspend-To-Idle, but the resume latency will generally be greater than for that | ||
56 | state. | ||
38 | 57 | ||
39 | 58 | ||
40 | State: Suspend-to-RAM | 59 | State: Suspend-to-RAM |
41 | ACPI State: S3 | 60 | ACPI State: S3 |
42 | String: "mem" | 61 | Label: "mem" |
43 | 62 | ||
44 | This state offers significant power savings as everything in the | 63 | This state, if supported, offers significant power savings as everything in the |
45 | system is put into a low-power state, except for memory, which is | 64 | system is put into a low-power state, except for memory, which should be placed |
46 | placed in self-refresh mode to retain its contents. | 65 | into the self-refresh mode to retain its contents. All of the steps carried out |
66 | when entering Power-On Suspend are also carried out during transitions to STR. | ||
67 | Additional operations may take place depending on the platform capabilities. In | ||
68 | particular, on ACPI systems the kernel passes control to the BIOS (platform | ||
69 | firmware) as the last step during STR transitions and that usually results in | ||
70 | powering down some more low-level components that aren't directly controlled by | ||
71 | the kernel. | ||
47 | 72 | ||
48 | System and device state is saved and kept in memory. All devices are | 73 | System and device state is saved and kept in memory. All devices are suspended |
49 | suspended and put into D3. In many cases, all peripheral buses lose | 74 | and put into low-power states. In many cases, all peripheral buses lose power |
50 | power when entering STR, so devices must be able to handle the | 75 | when entering STR, so devices must be able to handle the transition back to the |
51 | transition back to the On state. | 76 | "on" state. |
52 | 77 | ||
53 | For at least ACPI, STR requires some minimal boot-strapping code to | 78 | For at least ACPI, STR requires some minimal boot-strapping code to resume the |
54 | resume the system from STR. This may be true on other platforms. | 79 | system from it. This may be the case on other platforms too. |
55 | 80 | ||
56 | 81 | ||
57 | State: Suspend-to-disk | 82 | State: Suspend-to-disk |
58 | ACPI State: S4 | 83 | ACPI State: S4 |
59 | String: "disk" | 84 | Label: "disk" |
60 | 85 | ||
61 | This state offers the greatest power savings, and can be used even in | 86 | This state offers the greatest power savings, and can be used even in |
62 | the absence of low-level platform support for power management. This | 87 | the absence of low-level platform support for power management. This |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 9f51f0ab3d86..573410d6647e 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -279,14 +279,14 @@ static inline void pm_print_times_init(void) {} | |||
279 | struct kobject *power_kobj; | 279 | struct kobject *power_kobj; |
280 | 280 | ||
281 | /** | 281 | /** |
282 | * state - control system power state. | 282 | * state - control system sleep states. |
283 | * | 283 | * |
284 | * show() returns what states are supported, which is hard-coded to | 284 | * show() returns available sleep state labels, which may be "mem", "standby", |
285 | * 'freeze' (Low-Power Idle), 'standby' (Power-On Suspend), | 285 | * "freeze" and "disk" (hibernation). See Documentation/power/states.txt for a |
286 | * 'mem' (Suspend-to-RAM), and 'disk' (Suspend-to-Disk). | 286 | * description of what they mean. |
287 | * | 287 | * |
288 | * store() accepts one of those strings, translates it into the | 288 | * store() accepts one of those strings, translates it into the proper |
289 | * proper enumerated value, and initiates a suspend transition. | 289 | * enumerated value, and initiates a suspend transition. |
290 | */ | 290 | */ |
291 | static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, | 291 | static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, |
292 | char *buf) | 292 | char *buf) |
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 00aca60904b0..338a6f147974 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c | |||
@@ -78,6 +78,26 @@ static bool valid_state(suspend_state_t state) | |||
78 | return suspend_ops && suspend_ops->valid && suspend_ops->valid(state); | 78 | return suspend_ops && suspend_ops->valid && suspend_ops->valid(state); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* | ||
82 | * If this is set, the "mem" label always corresponds to the deepest sleep state | ||
83 | * available, the "standby" label corresponds to the second deepest sleep state | ||
84 | * available (if any), and the "freeze" label corresponds to the remaining | ||
85 | * available sleep state (if there is one). | ||
86 | */ | ||
87 | static bool relative_states; | ||
88 | |||
89 | static int __init sleep_states_setup(char *str) | ||
90 | { | ||
91 | relative_states = !strncmp(str, "1", 1); | ||
92 | if (relative_states) { | ||
93 | pm_states[PM_SUSPEND_MEM].state = PM_SUSPEND_FREEZE; | ||
94 | pm_states[PM_SUSPEND_FREEZE].state = 0; | ||
95 | } | ||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | __setup("relative_sleep_states=", sleep_states_setup); | ||
100 | |||
81 | /** | 101 | /** |
82 | * suspend_set_ops - Set the global suspend method table. | 102 | * suspend_set_ops - Set the global suspend method table. |
83 | * @ops: Suspend operations to use. | 103 | * @ops: Suspend operations to use. |
@@ -85,12 +105,20 @@ static bool valid_state(suspend_state_t state) | |||
85 | void suspend_set_ops(const struct platform_suspend_ops *ops) | 105 | void suspend_set_ops(const struct platform_suspend_ops *ops) |
86 | { | 106 | { |
87 | suspend_state_t i; | 107 | suspend_state_t i; |
108 | int j = PM_SUSPEND_MAX - 1; | ||
88 | 109 | ||
89 | lock_system_sleep(); | 110 | lock_system_sleep(); |
90 | 111 | ||
91 | suspend_ops = ops; | 112 | suspend_ops = ops; |
92 | for (i = PM_SUSPEND_STANDBY; i <= PM_SUSPEND_MEM; i++) | 113 | for (i = PM_SUSPEND_MEM; i >= PM_SUSPEND_STANDBY; i--) |
93 | pm_states[i].state = valid_state(i) ? i : 0; | 114 | if (valid_state(i)) |
115 | pm_states[j--].state = i; | ||
116 | else if (!relative_states) | ||
117 | pm_states[j--].state = 0; | ||
118 | |||
119 | pm_states[j--].state = PM_SUSPEND_FREEZE; | ||
120 | while (j >= PM_SUSPEND_MIN) | ||
121 | pm_states[j--].state = 0; | ||
94 | 122 | ||
95 | unlock_system_sleep(); | 123 | unlock_system_sleep(); |
96 | } | 124 | } |