Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cb437ac authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'pm-fixes' into fixes

* pm-fixes:
  cpufreq: Correct header guards typo
  cpufreq: check OF node /cpus presence before dereferencing it
  PM / devfreq: Fix compiler warnings for CONFIG_PM_DEVFREQ unset
  PM / QoS: Avoid possible deadlock related to sysfs access
  USB / PM: Don't try to hide PM QoS flags from usb_port_device_release()
parents fc1a7fe8 beb0ff39
Loading
Loading
Loading
Loading
+47 −13
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include "power.h"

static DEFINE_MUTEX(dev_pm_qos_mtx);
static DEFINE_MUTEX(dev_pm_qos_sysfs_mtx);

static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers);

@@ -216,12 +217,17 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
	struct pm_qos_constraints *c;
	struct pm_qos_flags *f;

	mutex_lock(&dev_pm_qos_mtx);
	mutex_lock(&dev_pm_qos_sysfs_mtx);

	/*
	 * If the device's PM QoS resume latency limit or PM QoS flags have been
	 * exposed to user space, they have to be hidden at this point.
	 */
	pm_qos_sysfs_remove_latency(dev);
	pm_qos_sysfs_remove_flags(dev);

	mutex_lock(&dev_pm_qos_mtx);

	__dev_pm_qos_hide_latency_limit(dev);
	__dev_pm_qos_hide_flags(dev);

@@ -254,6 +260,8 @@ void dev_pm_qos_constraints_destroy(struct device *dev)

 out:
	mutex_unlock(&dev_pm_qos_mtx);

	mutex_unlock(&dev_pm_qos_sysfs_mtx);
}

/**
@@ -558,6 +566,14 @@ static void __dev_pm_qos_drop_user_request(struct device *dev,
	kfree(req);
}

static void dev_pm_qos_drop_user_request(struct device *dev,
					 enum dev_pm_qos_req_type type)
{
	mutex_lock(&dev_pm_qos_mtx);
	__dev_pm_qos_drop_user_request(dev, type);
	mutex_unlock(&dev_pm_qos_mtx);
}

/**
 * dev_pm_qos_expose_latency_limit - Expose PM QoS latency limit to user space.
 * @dev: Device whose PM QoS latency limit is to be exposed to user space.
@@ -581,6 +597,8 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
		return ret;
	}

	mutex_lock(&dev_pm_qos_sysfs_mtx);

	mutex_lock(&dev_pm_qos_mtx);

	if (IS_ERR_OR_NULL(dev->power.qos))
@@ -591,27 +609,28 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
	if (ret < 0) {
		__dev_pm_qos_remove_request(req);
		kfree(req);
		mutex_unlock(&dev_pm_qos_mtx);
		goto out;
	}

	dev->power.qos->latency_req = req;

	mutex_unlock(&dev_pm_qos_mtx);

	ret = pm_qos_sysfs_add_latency(dev);
	if (ret)
		__dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
		dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);

 out:
	mutex_unlock(&dev_pm_qos_mtx);
	mutex_unlock(&dev_pm_qos_sysfs_mtx);
	return ret;
}
EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit);

static void __dev_pm_qos_hide_latency_limit(struct device *dev)
{
	if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) {
		pm_qos_sysfs_remove_latency(dev);
	if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req)
		__dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
}
}

/**
 * dev_pm_qos_hide_latency_limit - Hide PM QoS latency limit from user space.
@@ -619,9 +638,15 @@ static void __dev_pm_qos_hide_latency_limit(struct device *dev)
 */
void dev_pm_qos_hide_latency_limit(struct device *dev)
{
	mutex_lock(&dev_pm_qos_sysfs_mtx);

	pm_qos_sysfs_remove_latency(dev);

	mutex_lock(&dev_pm_qos_mtx);
	__dev_pm_qos_hide_latency_limit(dev);
	mutex_unlock(&dev_pm_qos_mtx);

	mutex_unlock(&dev_pm_qos_sysfs_mtx);
}
EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit);

@@ -649,6 +674,8 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val)
	}

	pm_runtime_get_sync(dev);
	mutex_lock(&dev_pm_qos_sysfs_mtx);

	mutex_lock(&dev_pm_qos_mtx);

	if (IS_ERR_OR_NULL(dev->power.qos))
@@ -659,16 +686,19 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val)
	if (ret < 0) {
		__dev_pm_qos_remove_request(req);
		kfree(req);
		mutex_unlock(&dev_pm_qos_mtx);
		goto out;
	}

	dev->power.qos->flags_req = req;

	mutex_unlock(&dev_pm_qos_mtx);

	ret = pm_qos_sysfs_add_flags(dev);
	if (ret)
		__dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
		dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);

 out:
	mutex_unlock(&dev_pm_qos_mtx);
	mutex_unlock(&dev_pm_qos_sysfs_mtx);
	pm_runtime_put(dev);
	return ret;
}
@@ -676,11 +706,9 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags);

static void __dev_pm_qos_hide_flags(struct device *dev)
{
	if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) {
		pm_qos_sysfs_remove_flags(dev);
	if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req)
		__dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
}
}

/**
 * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space.
@@ -689,9 +717,15 @@ static void __dev_pm_qos_hide_flags(struct device *dev)
void dev_pm_qos_hide_flags(struct device *dev)
{
	pm_runtime_get_sync(dev);
	mutex_lock(&dev_pm_qos_sysfs_mtx);

	pm_qos_sysfs_remove_flags(dev);

	mutex_lock(&dev_pm_qos_mtx);
	__dev_pm_qos_hide_flags(dev);
	mutex_unlock(&dev_pm_qos_mtx);

	mutex_unlock(&dev_pm_qos_sysfs_mtx);
	pm_runtime_put(dev);
}
EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags);
+8 −2
Original line number Diff line number Diff line
@@ -178,10 +178,16 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {

static int cpu0_cpufreq_probe(struct platform_device *pdev)
{
	struct device_node *np;
	struct device_node *np, *parent;
	int ret;

	for_each_child_of_node(of_find_node_by_path("/cpus"), np) {
	parent = of_find_node_by_path("/cpus");
	if (!parent) {
		pr_err("failed to find OF /cpus\n");
		return -ENOENT;
	}

	for_each_child_of_node(parent, np) {
		if (of_get_property(np, "operating-points", NULL))
			break;
	}
+3 −3
Original line number Diff line number Diff line
@@ -14,8 +14,8 @@
 * published by the Free Software Foundation.
 */

#ifndef _CPUFREQ_GOVERNER_H
#define _CPUFREQ_GOVERNER_H
#ifndef _CPUFREQ_GOVERNOR_H
#define _CPUFREQ_GOVERNOR_H

#include <linux/cpufreq.h>
#include <linux/kobject.h>
@@ -175,4 +175,4 @@ bool need_load_eval(struct cpu_dbs_common_info *cdbs,
		unsigned int sampling_rate);
int cpufreq_governor_dbs(struct dbs_data *dbs_data,
		struct cpufreq_policy *policy, unsigned int event);
#endif /* _CPUFREQ_GOVERNER_H */
#endif /* _CPUFREQ_GOVERNOR_H */
+0 −1
Original line number Diff line number Diff line
@@ -67,7 +67,6 @@ static void usb_port_device_release(struct device *dev)
{
	struct usb_port *port_dev = to_usb_port(dev);

	dev_pm_qos_hide_flags(dev);
	kfree(port_dev);
}

+8 −8
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ struct devfreq_simple_ondemand_data {
#endif

#else /* !CONFIG_PM_DEVFREQ */
static struct devfreq *devfreq_add_device(struct device *dev,
static inline struct devfreq *devfreq_add_device(struct device *dev,
					  struct devfreq_dev_profile *profile,
					  const char *governor_name,
					  void *data)
@@ -221,34 +221,34 @@ static struct devfreq *devfreq_add_device(struct device *dev,
	return NULL;
}

static int devfreq_remove_device(struct devfreq *devfreq)
static inline int devfreq_remove_device(struct devfreq *devfreq)
{
	return 0;
}

static int devfreq_suspend_device(struct devfreq *devfreq)
static inline int devfreq_suspend_device(struct devfreq *devfreq)
{
	return 0;
}

static int devfreq_resume_device(struct devfreq *devfreq)
static inline int devfreq_resume_device(struct devfreq *devfreq)
{
	return 0;
}

static struct opp *devfreq_recommended_opp(struct device *dev,
static inline struct opp *devfreq_recommended_opp(struct device *dev,
					   unsigned long *freq, u32 flags)
{
	return -EINVAL;
	return ERR_PTR(-EINVAL);
}

static int devfreq_register_opp_notifier(struct device *dev,
static inline int devfreq_register_opp_notifier(struct device *dev,
					 struct devfreq *devfreq)
{
	return -EINVAL;
}

static int devfreq_unregister_opp_notifier(struct device *dev,
static inline int devfreq_unregister_opp_notifier(struct device *dev,
					   struct devfreq *devfreq)
{
	return -EINVAL;