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
This commit is contained in:
@@ -675,7 +675,7 @@ sub-domain of the parent domain.
|
|||||||
|
|
||||||
Support for power domains is provided through the :c:member:`pm_domain` field of
|
Support for power domains is provided through the :c:member:`pm_domain` field of
|
||||||
|struct device|. This field is a pointer to an object of type
|
|struct device|. This field is a pointer to an object of type
|
||||||
|struct dev_pm_domain|, defined in :file:`include/linux/pm.h``, providing a set
|
|struct dev_pm_domain|, defined in :file:`include/linux/pm.h`, providing a set
|
||||||
of power management callbacks analogous to the subsystem-level and device driver
|
of power management callbacks analogous to the subsystem-level and device driver
|
||||||
callbacks that are executed for the given device during all power transitions,
|
callbacks that are executed for the given device during all power transitions,
|
||||||
instead of the respective subsystem-level callbacks. Specifically, if a
|
instead of the respective subsystem-level callbacks. Specifically, if a
|
||||||
|
|||||||
@@ -1860,10 +1860,13 @@ void device_pm_check_callbacks(struct device *dev)
|
|||||||
{
|
{
|
||||||
spin_lock_irq(&dev->power.lock);
|
spin_lock_irq(&dev->power.lock);
|
||||||
dev->power.no_pm_callbacks =
|
dev->power.no_pm_callbacks =
|
||||||
(!dev->bus || pm_ops_is_empty(dev->bus->pm)) &&
|
(!dev->bus || (pm_ops_is_empty(dev->bus->pm) &&
|
||||||
(!dev->class || pm_ops_is_empty(dev->class->pm)) &&
|
!dev->bus->suspend && !dev->bus->resume)) &&
|
||||||
|
(!dev->class || (pm_ops_is_empty(dev->class->pm) &&
|
||||||
|
!dev->class->suspend && !dev->class->resume)) &&
|
||||||
(!dev->type || pm_ops_is_empty(dev->type->pm)) &&
|
(!dev->type || pm_ops_is_empty(dev->type->pm)) &&
|
||||||
(!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) &&
|
(!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) &&
|
||||||
(!dev->driver || pm_ops_is_empty(dev->driver->pm));
|
(!dev->driver || (pm_ops_is_empty(dev->driver->pm) &&
|
||||||
|
!dev->driver->suspend && !dev->driver->resume));
|
||||||
spin_unlock_irq(&dev->power.lock);
|
spin_unlock_irq(&dev->power.lock);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,11 +277,11 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
|
|||||||
mutex_unlock(&dev_pm_qos_sysfs_mtx);
|
mutex_unlock(&dev_pm_qos_sysfs_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dev_pm_qos_invalid_request(struct device *dev,
|
static bool dev_pm_qos_invalid_req_type(struct device *dev,
|
||||||
struct dev_pm_qos_request *req)
|
enum dev_pm_qos_req_type type)
|
||||||
{
|
{
|
||||||
return !req || (req->type == DEV_PM_QOS_LATENCY_TOLERANCE
|
return type == DEV_PM_QOS_LATENCY_TOLERANCE &&
|
||||||
&& !dev->power.set_latency_tolerance);
|
!dev->power.set_latency_tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __dev_pm_qos_add_request(struct device *dev,
|
static int __dev_pm_qos_add_request(struct device *dev,
|
||||||
@@ -290,7 +290,7 @@ static int __dev_pm_qos_add_request(struct device *dev,
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!dev || dev_pm_qos_invalid_request(dev, req))
|
if (!dev || !req || dev_pm_qos_invalid_req_type(dev, type))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (WARN(dev_pm_qos_request_active(req),
|
if (WARN(dev_pm_qos_request_active(req),
|
||||||
|
|||||||
@@ -106,6 +106,18 @@ static const struct of_device_id whitelist[] __initconst = {
|
|||||||
* platforms using "operating-points-v2" property.
|
* platforms using "operating-points-v2" property.
|
||||||
*/
|
*/
|
||||||
static const struct of_device_id blacklist[] __initconst = {
|
static const struct of_device_id blacklist[] __initconst = {
|
||||||
|
{ .compatible = "calxeda,highbank", },
|
||||||
|
{ .compatible = "calxeda,ecx-2000", },
|
||||||
|
|
||||||
|
{ .compatible = "marvell,armadaxp", },
|
||||||
|
|
||||||
|
{ .compatible = "nvidia,tegra124", },
|
||||||
|
|
||||||
|
{ .compatible = "st,stih407", },
|
||||||
|
{ .compatible = "st,stih410", },
|
||||||
|
|
||||||
|
{ .compatible = "sigma,tango4", },
|
||||||
|
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ static int ti_cpufreq_setup_syscon_register(struct ti_cpufreq_data *opp_data)
|
|||||||
|
|
||||||
static const struct of_device_id ti_cpufreq_of_match[] = {
|
static const struct of_device_id ti_cpufreq_of_match[] = {
|
||||||
{ .compatible = "ti,am33xx", .data = &am3x_soc_data, },
|
{ .compatible = "ti,am33xx", .data = &am3x_soc_data, },
|
||||||
{ .compatible = "ti,am4372", .data = &am4x_soc_data, },
|
{ .compatible = "ti,am43", .data = &am4x_soc_data, },
|
||||||
{ .compatible = "ti,dra7", .data = &dra7_soc_data },
|
{ .compatible = "ti,dra7", .data = &dra7_soc_data },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -104,13 +104,13 @@ static int __init arm_idle_init(void)
|
|||||||
ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
|
ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
ret = ret ? : -ENODEV;
|
ret = ret ? : -ENODEV;
|
||||||
goto out_fail;
|
goto init_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cpuidle_register_driver(drv);
|
ret = cpuidle_register_driver(drv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to register cpuidle driver\n");
|
pr_err("Failed to register cpuidle driver\n");
|
||||||
goto out_fail;
|
goto init_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -149,6 +149,8 @@ static int __init arm_idle_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
init_fail:
|
||||||
|
kfree(drv);
|
||||||
out_fail:
|
out_fail:
|
||||||
while (--cpu >= 0) {
|
while (--cpu >= 0) {
|
||||||
dev = per_cpu(cpuidle_devices, cpu);
|
dev = per_cpu(cpuidle_devices, cpu);
|
||||||
|
|||||||
@@ -838,7 +838,7 @@ struct dev_links_info {
|
|||||||
* @driver_data: Private pointer for driver specific info.
|
* @driver_data: Private pointer for driver specific info.
|
||||||
* @links: Links to suppliers and consumers of this device.
|
* @links: Links to suppliers and consumers of this device.
|
||||||
* @power: For device power management.
|
* @power: For device power management.
|
||||||
* See Documentation/power/admin-guide/devices.rst for details.
|
* See Documentation/driver-api/pm/devices.rst for details.
|
||||||
* @pm_domain: Provide callbacks that are executed during system suspend,
|
* @pm_domain: Provide callbacks that are executed during system suspend,
|
||||||
* hibernation, system resume and during runtime PM transitions
|
* hibernation, system resume and during runtime PM transitions
|
||||||
* along with subsystem-level and driver-level callbacks.
|
* along with subsystem-level and driver-level callbacks.
|
||||||
|
|||||||
Reference in New Issue
Block a user