aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-22 23:28:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-22 23:28:59 -0400
commit6876eb3720813560c4c6728d6347da6558c53df7 (patch)
treefd10993f69c3f880305a331e96a260f4b2df9fed
parentd32e5f44a5aeb9c1febaf16db45bf888a3f66725 (diff)
parentd84c97f8f77bc4124256e76864f125f45ad53744 (diff)
Merge tag 'pm-4.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These fix a cpufreq regression introduced by recent changes related to the generic DT driver, an initialization time memory leak in cpuidle on ARM, a PM core bug that may cause system suspend/resume to fail on some systems, a request type validation issue in the PM QoS framework and two documentation-related issues. Specifics: - Fix a regression in cpufreq on systems using DT as the source of CPU configuration information where two different code paths attempt to create the cpufreq-dt device object (there can be only one) and fix up the "compatible" matching for some TI platforms on top of that (Viresh Kumar, Dave Gerlach). - Fix an initialization time memory leak in cpuidle on ARM which occurs if the cpuidle driver initialization fails (Stefan Wahren). - Fix a PM core function that checks whether or not there are any system suspend/resume callbacks for a device, but forgets to check legacy callbacks which then may be skipped incorrectly and the system may crash and/or the device may become unusable after a suspend-resume cycle (Rafael Wysocki). - Fix request type validation for latency tolerance PM QoS requests which may lead to unexpected behavior (Jan Schönherr). - Fix a broken link to PM documentation from a header file and a typo in a PM document (Geert Uytterhoeven, Rafael Wysocki)" * tag 'pm-4.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpufreq: ti-cpufreq: Support additional am43xx platforms ARM: cpuidle: Avoid memleak if init fail cpufreq: dt-platdev: Add some missing platforms to the blacklist PM: core: Fix device_pm_check_callbacks() PM: docs: Drop an excess character from devices.rst PM / QoS: Use the correct variable to check the QoS request type driver core: Fix link to device power management documentation
-rw-r--r--Documentation/driver-api/pm/devices.rst2
-rw-r--r--drivers/base/power/main.c9
-rw-r--r--drivers/base/power/qos.c10
-rw-r--r--drivers/cpufreq/cpufreq-dt-platdev.c12
-rw-r--r--drivers/cpufreq/ti-cpufreq.c2
-rw-r--r--drivers/cpuidle/cpuidle-arm.c6
-rw-r--r--include/linux/device.h2
7 files changed, 30 insertions, 13 deletions
diff --git a/Documentation/driver-api/pm/devices.rst b/Documentation/driver-api/pm/devices.rst
index bedd32388dac..a0dc2879a152 100644
--- a/Documentation/driver-api/pm/devices.rst
+++ b/Documentation/driver-api/pm/devices.rst
@@ -675,7 +675,7 @@ sub-domain of the parent domain.
675 675
676Support for power domains is provided through the :c:member:`pm_domain` field of 676Support for power domains is provided through the :c:member:`pm_domain` field of
677|struct device|. This field is a pointer to an object of type 677|struct device|. This field is a pointer to an object of type
678|struct dev_pm_domain|, defined in :file:`include/linux/pm.h``, providing a set 678|struct dev_pm_domain|, defined in :file:`include/linux/pm.h`, providing a set
679of power management callbacks analogous to the subsystem-level and device driver 679of power management callbacks analogous to the subsystem-level and device driver
680callbacks that are executed for the given device during all power transitions, 680callbacks that are executed for the given device during all power transitions,
681instead of the respective subsystem-level callbacks. Specifically, if a 681instead of the respective subsystem-level callbacks. Specifically, if a
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index ea1732ed7a9d..770b1539a083 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1860,10 +1860,13 @@ void device_pm_check_callbacks(struct device *dev)
1860{ 1860{
1861 spin_lock_irq(&dev->power.lock); 1861 spin_lock_irq(&dev->power.lock);
1862 dev->power.no_pm_callbacks = 1862 dev->power.no_pm_callbacks =
1863 (!dev->bus || pm_ops_is_empty(dev->bus->pm)) && 1863 (!dev->bus || (pm_ops_is_empty(dev->bus->pm) &&
1864 (!dev->class || pm_ops_is_empty(dev->class->pm)) && 1864 !dev->bus->suspend && !dev->bus->resume)) &&
1865 (!dev->class || (pm_ops_is_empty(dev->class->pm) &&
1866 !dev->class->suspend && !dev->class->resume)) &&
1865 (!dev->type || pm_ops_is_empty(dev->type->pm)) && 1867 (!dev->type || pm_ops_is_empty(dev->type->pm)) &&
1866 (!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) && 1868 (!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) &&
1867 (!dev->driver || pm_ops_is_empty(dev->driver->pm)); 1869 (!dev->driver || (pm_ops_is_empty(dev->driver->pm) &&
1870 !dev->driver->suspend && !dev->driver->resume));
1868 spin_unlock_irq(&dev->power.lock); 1871 spin_unlock_irq(&dev->power.lock);
1869} 1872}
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index f850daeffba4..277d43a83f53 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -277,11 +277,11 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
277 mutex_unlock(&dev_pm_qos_sysfs_mtx); 277 mutex_unlock(&dev_pm_qos_sysfs_mtx);
278} 278}
279 279
280static bool dev_pm_qos_invalid_request(struct device *dev, 280static bool dev_pm_qos_invalid_req_type(struct device *dev,
281 struct dev_pm_qos_request *req) 281 enum dev_pm_qos_req_type type)
282{ 282{
283 return !req || (req->type == DEV_PM_QOS_LATENCY_TOLERANCE 283 return type == DEV_PM_QOS_LATENCY_TOLERANCE &&
284 && !dev->power.set_latency_tolerance); 284 !dev->power.set_latency_tolerance;
285} 285}
286 286
287static int __dev_pm_qos_add_request(struct device *dev, 287static int __dev_pm_qos_add_request(struct device *dev,
@@ -290,7 +290,7 @@ static int __dev_pm_qos_add_request(struct device *dev,
290{ 290{
291 int ret = 0; 291 int ret = 0;
292 292
293 if (!dev || dev_pm_qos_invalid_request(dev, req)) 293 if (!dev || !req || dev_pm_qos_invalid_req_type(dev, type))
294 return -EINVAL; 294 return -EINVAL;
295 295
296 if (WARN(dev_pm_qos_request_active(req), 296 if (WARN(dev_pm_qos_request_active(req),
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index a020da7940d6..430edadca527 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -106,6 +106,18 @@ static const struct of_device_id whitelist[] __initconst = {
106 * platforms using "operating-points-v2" property. 106 * platforms using "operating-points-v2" property.
107 */ 107 */
108static const struct of_device_id blacklist[] __initconst = { 108static const struct of_device_id blacklist[] __initconst = {
109 { .compatible = "calxeda,highbank", },
110 { .compatible = "calxeda,ecx-2000", },
111
112 { .compatible = "marvell,armadaxp", },
113
114 { .compatible = "nvidia,tegra124", },
115
116 { .compatible = "st,stih407", },
117 { .compatible = "st,stih410", },
118
119 { .compatible = "sigma,tango4", },
120
109 { } 121 { }
110}; 122};
111 123
diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
index b29cd3398463..4bf47de6101f 100644
--- a/drivers/cpufreq/ti-cpufreq.c
+++ b/drivers/cpufreq/ti-cpufreq.c
@@ -190,7 +190,7 @@ static int ti_cpufreq_setup_syscon_register(struct ti_cpufreq_data *opp_data)
190 190
191static const struct of_device_id ti_cpufreq_of_match[] = { 191static const struct of_device_id ti_cpufreq_of_match[] = {
192 { .compatible = "ti,am33xx", .data = &am3x_soc_data, }, 192 { .compatible = "ti,am33xx", .data = &am3x_soc_data, },
193 { .compatible = "ti,am4372", .data = &am4x_soc_data, }, 193 { .compatible = "ti,am43", .data = &am4x_soc_data, },
194 { .compatible = "ti,dra7", .data = &dra7_soc_data }, 194 { .compatible = "ti,dra7", .data = &dra7_soc_data },
195 {}, 195 {},
196}; 196};
diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 7080c384ad5d..52a75053ee03 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -104,13 +104,13 @@ static int __init arm_idle_init(void)
104 ret = dt_init_idle_driver(drv, arm_idle_state_match, 1); 104 ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
105 if (ret <= 0) { 105 if (ret <= 0) {
106 ret = ret ? : -ENODEV; 106 ret = ret ? : -ENODEV;
107 goto out_fail; 107 goto init_fail;
108 } 108 }
109 109
110 ret = cpuidle_register_driver(drv); 110 ret = cpuidle_register_driver(drv);
111 if (ret) { 111 if (ret) {
112 pr_err("Failed to register cpuidle driver\n"); 112 pr_err("Failed to register cpuidle driver\n");
113 goto out_fail; 113 goto init_fail;
114 } 114 }
115 115
116 /* 116 /*
@@ -149,6 +149,8 @@ static int __init arm_idle_init(void)
149 } 149 }
150 150
151 return 0; 151 return 0;
152init_fail:
153 kfree(drv);
152out_fail: 154out_fail:
153 while (--cpu >= 0) { 155 while (--cpu >= 0) {
154 dev = per_cpu(cpuidle_devices, cpu); 156 dev = per_cpu(cpuidle_devices, cpu);
diff --git a/include/linux/device.h b/include/linux/device.h
index c6f27207dbe8..1d2607923a24 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -838,7 +838,7 @@ struct dev_links_info {
838 * @driver_data: Private pointer for driver specific info. 838 * @driver_data: Private pointer for driver specific info.
839 * @links: Links to suppliers and consumers of this device. 839 * @links: Links to suppliers and consumers of this device.
840 * @power: For device power management. 840 * @power: For device power management.
841 * See Documentation/power/admin-guide/devices.rst for details. 841 * See Documentation/driver-api/pm/devices.rst for details.
842 * @pm_domain: Provide callbacks that are executed during system suspend, 842 * @pm_domain: Provide callbacks that are executed during system suspend,
843 * hibernation, system resume and during runtime PM transitions 843 * hibernation, system resume and during runtime PM transitions
844 * along with subsystem-level and driver-level callbacks. 844 * along with subsystem-level and driver-level callbacks.