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

Commit 40c6b6b7 authored by Abhijeet Dharmapurikar's avatar Abhijeet Dharmapurikar
Browse files

devfreq: allow zero values in opp table



commit ab8f58ad ("PM / devfreq: Set
min/max_freq when adding the devfreq device") introduces a change
where an error in finding the ceil or floor is returned as a
zero frequency. This return of zero is treated as error condition
from the callsites.

It is perfectly valid for a device to have a zero frequency, usually
it denotes a power collapse. This valid return of zero frequency ends
up being treated as an error condition.

Fix it.

Change-Id: I5eb6fa622d6fe09207746b96dce05d0b58b233dc
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
parent b1d3f812
Loading
Loading
Loading
Loading
+22 −16
Original line number Diff line number Diff line
@@ -72,28 +72,28 @@ static struct devfreq *find_device_devfreq(struct device *dev)
	return ERR_PTR(-ENODEV);
}

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

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

	return min_freq;
}

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

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

@@ -494,20 +494,25 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
{
	struct devfreq *devfreq = container_of(nb, struct devfreq, nb);
	int ret;
	long freq;

	mutex_lock(&devfreq->lock);

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

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

	ret = update_devfreq(devfreq);
	mutex_unlock(&devfreq->lock);
@@ -562,6 +567,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
	struct devfreq *devfreq;
	struct devfreq_governor *governor;
	int err = 0;
	long freq;

	if (!dev || !profile || !governor_name) {
		dev_err(dev, "%s: Invalid parameters.\n", __func__);
@@ -606,21 +612,21 @@ struct devfreq *devfreq_add_device(struct device *dev,
		mutex_lock(&devfreq->lock);
	}

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

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

	dev_set_name(&devfreq->dev, "%s", dev_name(dev));
	err = device_register(&devfreq->dev);