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

Commit 990a848d authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'pm-devfreq' and 'pm-tools'

* pm-devfreq:
  PM / devfreq: Define the constant governor name
  PM / devfreq: Remove unneeded conditional statement
  PM / devfreq: Show the all available frequencies
  PM / devfreq: Change return type of devfreq_set_freq_table()
  PM / devfreq: Use the available min/max frequency
  Revert "PM / devfreq: Add show_one macro to delete the duplicate code"
  PM / devfreq: Set min/max_freq when adding the devfreq device

* pm-tools:
  tools/power/cpupower: add libcpupower.so.0.0.1 to .gitignore
  tools/power/cpupower: Add 64 bit library detection
  MAINTAINERS: add maintainer for tools/power/cpupower
  cpupower: Fix no-rounding MHz frequency output
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -3636,6 +3636,8 @@ F: drivers/cpufreq/arm_big_little_dt.c


CPU POWER MONITORING SUBSYSTEM
CPU POWER MONITORING SUBSYSTEM
M:	Thomas Renninger <trenn@suse.com>
M:	Thomas Renninger <trenn@suse.com>
M:	Shuah Khan <shuahkh@osg.samsung.com>
M:	Shuah Khan <shuah@kernel.org>
L:	linux-pm@vger.kernel.org
L:	linux-pm@vger.kernel.org
S:	Maintained
S:	Maintained
F:	tools/power/cpupower/
F:	tools/power/cpupower/
+100 −39
Original line number Original line Diff line number Diff line
@@ -28,6 +28,9 @@
#include <linux/of.h>
#include <linux/of.h>
#include "governor.h"
#include "governor.h"


#define MAX(a,b)	((a > b) ? a : b)
#define MIN(a,b)	((a < b) ? a : b)

static struct class *devfreq_class;
static struct class *devfreq_class;


/*
/*
@@ -69,6 +72,34 @@ static struct devfreq *find_device_devfreq(struct device *dev)
	return ERR_PTR(-ENODEV);
	return ERR_PTR(-ENODEV);
}
}


static unsigned long find_available_min_freq(struct devfreq *devfreq)
{
	struct dev_pm_opp *opp;
	unsigned long min_freq = 0;

	opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &min_freq);
	if (IS_ERR(opp))
		min_freq = 0;
	else
		dev_pm_opp_put(opp);

	return min_freq;
}

static unsigned long find_available_max_freq(struct devfreq *devfreq)
{
	struct dev_pm_opp *opp;
	unsigned long max_freq = ULONG_MAX;

	opp = dev_pm_opp_find_freq_floor(devfreq->dev.parent, &max_freq);
	if (IS_ERR(opp))
		max_freq = 0;
	else
		dev_pm_opp_put(opp);

	return max_freq;
}

/**
/**
 * devfreq_get_freq_level() - Lookup freq_table for the frequency
 * devfreq_get_freq_level() - Lookup freq_table for the frequency
 * @devfreq:	the devfreq instance
 * @devfreq:	the devfreq instance
@@ -85,11 +116,7 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq)
	return -EINVAL;
	return -EINVAL;
}
}


/**
static int set_freq_table(struct devfreq *devfreq)
 * devfreq_set_freq_table() - Initialize freq_table for the frequency
 * @devfreq:	the devfreq instance
 */
static void devfreq_set_freq_table(struct devfreq *devfreq)
{
{
	struct devfreq_dev_profile *profile = devfreq->profile;
	struct devfreq_dev_profile *profile = devfreq->profile;
	struct dev_pm_opp *opp;
	struct dev_pm_opp *opp;
@@ -99,7 +126,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
	/* Initialize the freq_table from OPP table */
	/* Initialize the freq_table from OPP table */
	count = dev_pm_opp_get_opp_count(devfreq->dev.parent);
	count = dev_pm_opp_get_opp_count(devfreq->dev.parent);
	if (count <= 0)
	if (count <= 0)
		return;
		return -EINVAL;


	profile->max_state = count;
	profile->max_state = count;
	profile->freq_table = devm_kcalloc(devfreq->dev.parent,
	profile->freq_table = devm_kcalloc(devfreq->dev.parent,
@@ -108,7 +135,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
					GFP_KERNEL);
					GFP_KERNEL);
	if (!profile->freq_table) {
	if (!profile->freq_table) {
		profile->max_state = 0;
		profile->max_state = 0;
		return;
		return -ENOMEM;
	}
	}


	for (i = 0, freq = 0; i < profile->max_state; i++, freq++) {
	for (i = 0, freq = 0; i < profile->max_state; i++, freq++) {
@@ -116,11 +143,13 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
		if (IS_ERR(opp)) {
		if (IS_ERR(opp)) {
			devm_kfree(devfreq->dev.parent, profile->freq_table);
			devm_kfree(devfreq->dev.parent, profile->freq_table);
			profile->max_state = 0;
			profile->max_state = 0;
			return;
			return PTR_ERR(opp);
		}
		}
		dev_pm_opp_put(opp);
		dev_pm_opp_put(opp);
		profile->freq_table[i] = freq;
		profile->freq_table[i] = freq;
	}
	}

	return 0;
}
}


/**
/**
@@ -227,7 +256,7 @@ static int devfreq_notify_transition(struct devfreq *devfreq,
int update_devfreq(struct devfreq *devfreq)
int update_devfreq(struct devfreq *devfreq)
{
{
	struct devfreq_freqs freqs;
	struct devfreq_freqs freqs;
	unsigned long freq, cur_freq;
	unsigned long freq, cur_freq, min_freq, max_freq;
	int err = 0;
	int err = 0;
	u32 flags = 0;
	u32 flags = 0;


@@ -245,19 +274,21 @@ int update_devfreq(struct devfreq *devfreq)
		return err;
		return err;


	/*
	/*
	 * Adjust the frequency with user freq and QoS.
	 * Adjust the frequency with user freq, QoS and available freq.
	 *
	 *
	 * List from the highest priority
	 * List from the highest priority
	 * max_freq
	 * max_freq
	 * min_freq
	 * min_freq
	 */
	 */
	max_freq = MIN(devfreq->scaling_max_freq, devfreq->max_freq);
	min_freq = MAX(devfreq->scaling_min_freq, devfreq->min_freq);


	if (devfreq->min_freq && freq < devfreq->min_freq) {
	if (min_freq && freq < min_freq) {
		freq = devfreq->min_freq;
		freq = min_freq;
		flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
		flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
	}
	}
	if (devfreq->max_freq && freq > devfreq->max_freq) {
	if (max_freq && freq > max_freq) {
		freq = devfreq->max_freq;
		freq = max_freq;
		flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */
		flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */
	}
	}


@@ -280,7 +311,6 @@ int update_devfreq(struct devfreq *devfreq)
	freqs.new = freq;
	freqs.new = freq;
	devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE);
	devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE);


	if (devfreq->profile->freq_table)
	if (devfreq_update_status(devfreq, freq))
	if (devfreq_update_status(devfreq, freq))
		dev_err(&devfreq->dev,
		dev_err(&devfreq->dev,
			"Couldn't update frequency transition information.\n");
			"Couldn't update frequency transition information.\n");
@@ -466,6 +496,19 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
	int ret;
	int ret;


	mutex_lock(&devfreq->lock);
	mutex_lock(&devfreq->lock);

	devfreq->scaling_min_freq = find_available_min_freq(devfreq);
	if (!devfreq->scaling_min_freq) {
		mutex_unlock(&devfreq->lock);
		return -EINVAL;
	}

	devfreq->scaling_max_freq = find_available_max_freq(devfreq);
	if (!devfreq->scaling_max_freq) {
		mutex_unlock(&devfreq->lock);
		return -EINVAL;
	}

	ret = update_devfreq(devfreq);
	ret = update_devfreq(devfreq);
	mutex_unlock(&devfreq->lock);
	mutex_unlock(&devfreq->lock);


@@ -555,10 +598,28 @@ struct devfreq *devfreq_add_device(struct device *dev,


	if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
	if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
		mutex_unlock(&devfreq->lock);
		mutex_unlock(&devfreq->lock);
		devfreq_set_freq_table(devfreq);
		err = set_freq_table(devfreq);
		if (err < 0)
			goto err_out;
		mutex_lock(&devfreq->lock);
		mutex_lock(&devfreq->lock);
	}
	}


	devfreq->min_freq = find_available_min_freq(devfreq);
	if (!devfreq->min_freq) {
		mutex_unlock(&devfreq->lock);
		err = -EINVAL;
		goto err_dev;
	}
	devfreq->scaling_min_freq = devfreq->min_freq;

	devfreq->max_freq = find_available_max_freq(devfreq);
	if (!devfreq->max_freq) {
		mutex_unlock(&devfreq->lock);
		err = -EINVAL;
		goto err_dev;
	}
	devfreq->scaling_max_freq = devfreq->max_freq;

	dev_set_name(&devfreq->dev, "devfreq%d",
	dev_set_name(&devfreq->dev, "devfreq%d",
				atomic_inc_return(&devfreq_no));
				atomic_inc_return(&devfreq_no));
	err = device_register(&devfreq->dev);
	err = device_register(&devfreq->dev);
@@ -1082,6 +1143,14 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
	return ret;
	return ret;
}
}


static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct devfreq *df = to_devfreq(dev);

	return sprintf(buf, "%lu\n", MAX(df->scaling_min_freq, df->min_freq));
}

static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
			      const char *buf, size_t count)
{
{
@@ -1108,17 +1177,15 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
	mutex_unlock(&df->lock);
	mutex_unlock(&df->lock);
	return ret;
	return ret;
}
}
static DEVICE_ATTR_RW(min_freq);


#define show_one(name)						\
static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
static ssize_t name##_show					\
			     char *buf)
(struct device *dev, struct device_attribute *attr, char *buf)	\
{
{								\
	struct devfreq *df = to_devfreq(dev);
	return sprintf(buf, "%lu\n", to_devfreq(dev)->name);	\
}
show_one(min_freq);
show_one(max_freq);


static DEVICE_ATTR_RW(min_freq);
	return sprintf(buf, "%lu\n", MIN(df->scaling_max_freq, df->max_freq));
}
static DEVICE_ATTR_RW(max_freq);
static DEVICE_ATTR_RW(max_freq);


static ssize_t available_frequencies_show(struct device *d,
static ssize_t available_frequencies_show(struct device *d,
@@ -1126,22 +1193,16 @@ static ssize_t available_frequencies_show(struct device *d,
					  char *buf)
					  char *buf)
{
{
	struct devfreq *df = to_devfreq(d);
	struct devfreq *df = to_devfreq(d);
	struct device *dev = df->dev.parent;
	struct dev_pm_opp *opp;
	ssize_t count = 0;
	ssize_t count = 0;
	unsigned long freq = 0;
	int i;


	do {
	mutex_lock(&df->lock);
		opp = dev_pm_opp_find_freq_ceil(dev, &freq);
		if (IS_ERR(opp))
			break;


		dev_pm_opp_put(opp);
	for (i = 0; i < df->profile->max_state; i++)
		count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
		count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
				   "%lu ", freq);
				"%lu ", df->profile->freq_table[i]);
		freq++;
	} while (1);


	mutex_unlock(&df->lock);
	/* Truncate the trailing space */
	/* Truncate the trailing space */
	if (count)
	if (count)
		count--;
		count--;
+3 −2
Original line number Original line Diff line number Diff line
@@ -436,7 +436,8 @@ static int exynos_bus_probe(struct platform_device *pdev)
	ondemand_data->downdifferential = 5;
	ondemand_data->downdifferential = 5;


	/* Add devfreq device to monitor and handle the exynos bus */
	/* Add devfreq device to monitor and handle the exynos bus */
	bus->devfreq = devm_devfreq_add_device(dev, profile, "simple_ondemand",
	bus->devfreq = devm_devfreq_add_device(dev, profile,
						DEVFREQ_GOV_SIMPLE_ONDEMAND,
						ondemand_data);
						ondemand_data);
	if (IS_ERR(bus->devfreq)) {
	if (IS_ERR(bus->devfreq)) {
		dev_err(dev, "failed to add devfreq device\n");
		dev_err(dev, "failed to add devfreq device\n");
@@ -488,7 +489,7 @@ static int exynos_bus_probe(struct platform_device *pdev)
	passive_data->parent = parent_devfreq;
	passive_data->parent = parent_devfreq;


	/* Add devfreq device for exynos bus with passive governor */
	/* Add devfreq device for exynos bus with passive governor */
	bus->devfreq = devm_devfreq_add_device(dev, profile, "passive",
	bus->devfreq = devm_devfreq_add_device(dev, profile, DEVFREQ_GOV_PASSIVE,
						passive_data);
						passive_data);
	if (IS_ERR(bus->devfreq)) {
	if (IS_ERR(bus->devfreq)) {
		dev_err(dev,
		dev_err(dev,
+1 −1
Original line number Original line Diff line number Diff line
@@ -183,7 +183,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
}
}


static struct devfreq_governor devfreq_passive = {
static struct devfreq_governor devfreq_passive = {
	.name = "passive",
	.name = DEVFREQ_GOV_PASSIVE,
	.immutable = 1,
	.immutable = 1,
	.get_target_freq = devfreq_passive_get_target_freq,
	.get_target_freq = devfreq_passive_get_target_freq,
	.event_handler = devfreq_passive_event_handler,
	.event_handler = devfreq_passive_event_handler,
+1 −1
Original line number Original line Diff line number Diff line
@@ -42,7 +42,7 @@ static int devfreq_performance_handler(struct devfreq *devfreq,
}
}


static struct devfreq_governor devfreq_performance = {
static struct devfreq_governor devfreq_performance = {
	.name = "performance",
	.name = DEVFREQ_GOV_PERFORMANCE,
	.get_target_freq = devfreq_performance_func,
	.get_target_freq = devfreq_performance_func,
	.event_handler = devfreq_performance_handler,
	.event_handler = devfreq_performance_handler,
};
};
Loading