aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-11-11 19:54:23 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-11-11 19:54:23 -0500
commitb9f659b810c1f98298f9e756e49920d641a1fd95 (patch)
treed77f5c63df7f506208be2de4e08474797534de10
parente6251f009bc27ea2c774aefde5dca6b5d2142df4 (diff)
parentcd16f3dcdb1817956277fbeee0746ae1eb4f851a (diff)
Merge tag 'pm-4.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These fix two bugs in error code paths in the PM core (system-wide suspend of devices), a device reference leak in the boot-time suspend test code and a cpupower utility regression from the 4.7 cycle. Specifics: - Prevent the PM core from attempting to suspend parent devices if any of their children, whose suspend callbacks were invoked asynchronously, have failed to suspend during the "late" and "noirq" phases of system-wide suspend of devices (Brian Norris). - Prevent the boot-time system suspend test code from leaking a reference to the RTC device used by it (Johan Hovold). - Fix cpupower to use the return value of one of its library functions correctly and restore the correct behavior of it when used for setting cpufreq tunables broken during the 4.7 development cycle (Laura Abbott)" * tag 'pm-4.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM / sleep: don't suspend parent when async child suspend_{noirq, late} fails PM / sleep: fix device reference leak in test_suspend cpupower: Correct return type of cpu_power_is_cpu_online() in cpufreq-set
-rw-r--r--drivers/base/power/main.c8
-rw-r--r--kernel/power/suspend_test.c4
-rw-r--r--tools/power/cpupower/utils/cpufreq-set.c7
3 files changed, 9 insertions, 10 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index e44944f4be77..2932a5bd892f 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1027,6 +1027,8 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
1027 TRACE_DEVICE(dev); 1027 TRACE_DEVICE(dev);
1028 TRACE_SUSPEND(0); 1028 TRACE_SUSPEND(0);
1029 1029
1030 dpm_wait_for_children(dev, async);
1031
1030 if (async_error) 1032 if (async_error)
1031 goto Complete; 1033 goto Complete;
1032 1034
@@ -1038,8 +1040,6 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
1038 if (dev->power.syscore || dev->power.direct_complete) 1040 if (dev->power.syscore || dev->power.direct_complete)
1039 goto Complete; 1041 goto Complete;
1040 1042
1041 dpm_wait_for_children(dev, async);
1042
1043 if (dev->pm_domain) { 1043 if (dev->pm_domain) {
1044 info = "noirq power domain "; 1044 info = "noirq power domain ";
1045 callback = pm_noirq_op(&dev->pm_domain->ops, state); 1045 callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -1174,6 +1174,8 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
1174 1174
1175 __pm_runtime_disable(dev, false); 1175 __pm_runtime_disable(dev, false);
1176 1176
1177 dpm_wait_for_children(dev, async);
1178
1177 if (async_error) 1179 if (async_error)
1178 goto Complete; 1180 goto Complete;
1179 1181
@@ -1185,8 +1187,6 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
1185 if (dev->power.syscore || dev->power.direct_complete) 1187 if (dev->power.syscore || dev->power.direct_complete)
1186 goto Complete; 1188 goto Complete;
1187 1189
1188 dpm_wait_for_children(dev, async);
1189
1190 if (dev->pm_domain) { 1190 if (dev->pm_domain) {
1191 info = "late power domain "; 1191 info = "late power domain ";
1192 callback = pm_late_early_op(&dev->pm_domain->ops, state); 1192 callback = pm_late_early_op(&dev->pm_domain->ops, state);
diff --git a/kernel/power/suspend_test.c b/kernel/power/suspend_test.c
index 084452e34a12..bdff5ed57f10 100644
--- a/kernel/power/suspend_test.c
+++ b/kernel/power/suspend_test.c
@@ -203,8 +203,10 @@ static int __init test_suspend(void)
203 203
204 /* RTCs have initialized by now too ... can we use one? */ 204 /* RTCs have initialized by now too ... can we use one? */
205 dev = class_find_device(rtc_class, NULL, NULL, has_wakealarm); 205 dev = class_find_device(rtc_class, NULL, NULL, has_wakealarm);
206 if (dev) 206 if (dev) {
207 rtc = rtc_class_open(dev_name(dev)); 207 rtc = rtc_class_open(dev_name(dev));
208 put_device(dev);
209 }
208 if (!rtc) { 210 if (!rtc) {
209 printk(warn_no_rtc); 211 printk(warn_no_rtc);
210 return 0; 212 return 0;
diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c
index b4bf76971dc9..1eef0aed6423 100644
--- a/tools/power/cpupower/utils/cpufreq-set.c
+++ b/tools/power/cpupower/utils/cpufreq-set.c
@@ -296,7 +296,7 @@ int cmd_freq_set(int argc, char **argv)
296 struct cpufreq_affected_cpus *cpus; 296 struct cpufreq_affected_cpus *cpus;
297 297
298 if (!bitmask_isbitset(cpus_chosen, cpu) || 298 if (!bitmask_isbitset(cpus_chosen, cpu) ||
299 cpupower_is_cpu_online(cpu)) 299 cpupower_is_cpu_online(cpu) != 1)
300 continue; 300 continue;
301 301
302 cpus = cpufreq_get_related_cpus(cpu); 302 cpus = cpufreq_get_related_cpus(cpu);
@@ -316,10 +316,7 @@ int cmd_freq_set(int argc, char **argv)
316 cpu <= bitmask_last(cpus_chosen); cpu++) { 316 cpu <= bitmask_last(cpus_chosen); cpu++) {
317 317
318 if (!bitmask_isbitset(cpus_chosen, cpu) || 318 if (!bitmask_isbitset(cpus_chosen, cpu) ||
319 cpupower_is_cpu_online(cpu)) 319 cpupower_is_cpu_online(cpu) != 1)
320 continue;
321
322 if (cpupower_is_cpu_online(cpu) != 1)
323 continue; 320 continue;
324 321
325 printf(_("Setting cpu: %d\n"), cpu); 322 printf(_("Setting cpu: %d\n"), cpu);