Commit ff9c5120 authored by Viresh Kumar's avatar Viresh Kumar
Browse files

OPP: Use mutex locking guards



Use mutex locking guard in the OPP core.

No intentional functional impact.

Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
parent 8c5d8c0b
Loading
Loading
Loading
Loading
+79 −122
Original line number Diff line number Diff line
@@ -40,17 +40,14 @@ static DEFINE_XARRAY_ALLOC1(opp_configs);
static bool _find_opp_dev(const struct device *dev, struct opp_table *opp_table)
{
	struct opp_device *opp_dev;
	bool found = false;

	mutex_lock(&opp_table->lock);
	guard(mutex)(&opp_table->lock);

	list_for_each_entry(opp_dev, &opp_table->dev_list, node)
		if (opp_dev->dev == dev) {
			found = true;
			break;
		}
		if (opp_dev->dev == dev)
			return true;

	mutex_unlock(&opp_table->lock);
	return found;
	return false;
}

static struct opp_table *_find_opp_table_unlocked(struct device *dev)
@@ -78,18 +75,13 @@ static struct opp_table *_find_opp_table_unlocked(struct device *dev)
 */
struct opp_table *_find_opp_table(struct device *dev)
{
	struct opp_table *opp_table;

	if (IS_ERR_OR_NULL(dev)) {
		pr_err("%s: Invalid parameters\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	mutex_lock(&opp_table_lock);
	opp_table = _find_opp_table_unlocked(dev);
	mutex_unlock(&opp_table_lock);

	return opp_table;
	guard(mutex)(&opp_table_lock);
	return _find_opp_table_unlocked(dev);
}

/*
@@ -359,8 +351,7 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev)
	if (!uV)
		return 0;

	mutex_lock(&opp_table->lock);

	scoped_guard(mutex, &opp_table->lock) {
		for (i = 0; i < count; i++) {
			uV[i].min = ~0;
			uV[i].max = 0;
@@ -375,8 +366,7 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev)
					uV[i].max = opp->supplies[i].u_volt_max;
			}
		}

	mutex_unlock(&opp_table->lock);
	}

	/*
	 * The caller needs to ensure that opp_table (and hence the regulator)
@@ -438,15 +428,13 @@ int _get_opp_count(struct opp_table *opp_table)
	struct dev_pm_opp *opp;
	int count = 0;

	mutex_lock(&opp_table->lock);
	guard(mutex)(&opp_table->lock);

	list_for_each_entry(opp, &opp_table->opp_list, node) {
		if (opp->available)
			count++;
	}

	mutex_unlock(&opp_table->lock);

	return count;
}

@@ -535,7 +523,7 @@ static struct dev_pm_opp *_opp_table_find_key(struct opp_table *opp_table,
	if (assert && !assert(opp_table, index))
		return ERR_PTR(-EINVAL);

	mutex_lock(&opp_table->lock);
	guard(mutex)(&opp_table->lock);

	list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
		if (temp_opp->available == available) {
@@ -550,8 +538,6 @@ static struct dev_pm_opp *_opp_table_find_key(struct opp_table *opp_table,
		dev_pm_opp_get(opp);
	}

	mutex_unlock(&opp_table->lock);

	return opp;
}

@@ -1166,10 +1152,9 @@ static void _find_current_opp(struct device *dev, struct opp_table *opp_table)
	 * make special checks to validate current_opp.
	 */
	if (IS_ERR(opp)) {
		mutex_lock(&opp_table->lock);
		guard(mutex)(&opp_table->lock);
		opp = dev_pm_opp_get(list_first_entry(&opp_table->opp_list,
						      struct dev_pm_opp, node));
		mutex_unlock(&opp_table->lock);
	}

	opp_table->current_opp = opp;
@@ -1426,9 +1411,8 @@ struct opp_device *_add_opp_dev(const struct device *dev,
	/* Initialize opp-dev */
	opp_dev->dev = dev;

	mutex_lock(&opp_table->lock);
	scoped_guard(mutex, &opp_table->lock)
		list_add(&opp_dev->node, &opp_table->dev_list);
	mutex_unlock(&opp_table->lock);

	/* Create debugfs entries for the opp_table */
	opp_debug_register(opp_dev, opp_table);
@@ -1721,16 +1705,14 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq)
	if (!assert_single_clk(opp_table, 0))
		return;

	mutex_lock(&opp_table->lock);

	scoped_guard(mutex, &opp_table->lock) {
		list_for_each_entry(iter, &opp_table->opp_list, node) {
			if (iter->rates[0] == freq) {
				opp = iter;
				break;
			}
		}

	mutex_unlock(&opp_table->lock);
	}

	if (opp) {
		dev_pm_opp_put(opp);
@@ -1747,22 +1729,20 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_remove);
static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table,
					bool dynamic)
{
	struct dev_pm_opp *opp = NULL, *temp;
	struct dev_pm_opp *opp;

	mutex_lock(&opp_table->lock);
	list_for_each_entry(temp, &opp_table->opp_list, node) {
	guard(mutex)(&opp_table->lock);

	list_for_each_entry(opp, &opp_table->opp_list, node) {
		/*
		 * Refcount must be dropped only once for each OPP by OPP core,
		 * do that with help of "removed" flag.
		 */
		if (!temp->removed && dynamic == temp->dynamic) {
			opp = temp;
			break;
		}
		if (!opp->removed && dynamic == opp->dynamic)
			return opp;
	}

	mutex_unlock(&opp_table->lock);
	return opp;
	return NULL;
}

/*
@@ -1786,20 +1766,14 @@ static void _opp_remove_all(struct opp_table *opp_table, bool dynamic)

bool _opp_remove_all_static(struct opp_table *opp_table)
{
	mutex_lock(&opp_table->lock);

	if (!opp_table->parsed_static_opps) {
		mutex_unlock(&opp_table->lock);
	scoped_guard(mutex, &opp_table->lock) {
		if (!opp_table->parsed_static_opps)
			return false;
	}

	if (--opp_table->parsed_static_opps) {
		mutex_unlock(&opp_table->lock);
		if (--opp_table->parsed_static_opps)
			return true;
	}

	mutex_unlock(&opp_table->lock);

	_opp_remove_all(opp_table, false);
	return true;
}
@@ -2003,17 +1977,15 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
	struct list_head *head;
	int ret;

	mutex_lock(&opp_table->lock);
	scoped_guard(mutex, &opp_table->lock) {
		head = &opp_table->opp_list;

		ret = _opp_is_duplicate(dev, new_opp, opp_table, &head);
	if (ret) {
		mutex_unlock(&opp_table->lock);
		if (ret)
			return ret;
	}

		list_add(&new_opp->node, head);
	mutex_unlock(&opp_table->lock);
	}

	new_opp->opp_table = opp_table;
	kref_init(&new_opp->kref);
@@ -2660,17 +2632,16 @@ struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table,
		return ERR_PTR(-EBUSY);

	for (i = 0; i < src_table->required_opp_count; i++) {
		if (src_table->required_opp_tables[i] == dst_table) {
			mutex_lock(&src_table->lock);
		if (src_table->required_opp_tables[i] != dst_table)
			continue;

		scoped_guard(mutex, &src_table->lock) {
			list_for_each_entry(opp, &src_table->opp_list, node) {
				if (opp == src_opp) {
					dest_opp = dev_pm_opp_get(opp->required_opps[i]);
					break;
				}
			}

			mutex_unlock(&src_table->lock);
			break;
		}
	}
@@ -2702,7 +2673,6 @@ int dev_pm_opp_xlate_performance_state(struct opp_table *src_table,
				       unsigned int pstate)
{
	struct dev_pm_opp *opp;
	int dest_pstate = -EINVAL;
	int i;

	/*
@@ -2736,22 +2706,17 @@ int dev_pm_opp_xlate_performance_state(struct opp_table *src_table,
		return -EINVAL;
	}

	mutex_lock(&src_table->lock);
	guard(mutex)(&src_table->lock);

	list_for_each_entry(opp, &src_table->opp_list, node) {
		if (opp->level == pstate) {
			dest_pstate = opp->required_opps[i]->level;
			goto unlock;
		}
		if (opp->level == pstate)
			return opp->required_opps[i]->level;
	}

	pr_err("%s: Couldn't find matching OPP (%p: %p)\n", __func__, src_table,
	       dst_table);

unlock:
	mutex_unlock(&src_table->lock);

	return dest_pstate;
	return -EINVAL;
}

/**
@@ -2820,25 +2785,21 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
	if (!assert_single_clk(opp_table, 0))
		return -EINVAL;

	mutex_lock(&opp_table->lock);

	scoped_guard(mutex, &opp_table->lock) {
		/* Do we have the frequency? */
		list_for_each_entry(tmp_opp, &opp_table->opp_list, node) {
			if (tmp_opp->rates[0] == freq) {
				opp = dev_pm_opp_get(tmp_opp);

				/* Is update really needed? */
			if (opp->available == availability_req) {
				mutex_unlock(&opp_table->lock);
				if (opp->available == availability_req)
					return 0;
			}

				opp->available = availability_req;
				break;
			}
		}

	mutex_unlock(&opp_table->lock);
	}

	if (IS_ERR(opp))
		return PTR_ERR(opp);
@@ -2886,18 +2847,15 @@ int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
	if (!assert_single_clk(opp_table, 0))
		return -EINVAL;

	mutex_lock(&opp_table->lock);

	scoped_guard(mutex, &opp_table->lock) {
		/* Do we have the frequency? */
		list_for_each_entry(tmp_opp, &opp_table->opp_list, node) {
			if (tmp_opp->rates[0] == freq) {
				opp = dev_pm_opp_get(tmp_opp);

				/* Is update really needed? */
			if (opp->supplies->u_volt == u_volt) {
				mutex_unlock(&opp_table->lock);
				if (opp->supplies->u_volt == u_volt)
					return 0;
			}

				opp->supplies->u_volt = u_volt;
				opp->supplies->u_volt_min = u_volt_min;
@@ -2906,8 +2864,7 @@ int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
				break;
			}
		}

	mutex_unlock(&opp_table->lock);
	}

	if (IS_ERR(opp))
		return PTR_ERR(opp);
+1 −2
Original line number Diff line number Diff line
@@ -214,10 +214,9 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
	cpumask_clear(cpumask);

	if (opp_table->shared_opp == OPP_TABLE_ACCESS_SHARED) {
		mutex_lock(&opp_table->lock);
		guard(mutex)(&opp_table->lock);
		list_for_each_entry(opp_dev, &opp_table->dev_list, node)
			cpumask_set_cpu(opp_dev->dev->id, cpumask);
		mutex_unlock(&opp_table->lock);
	} else {
		cpumask_set_cpu(cpu_dev->id, cpumask);
	}
+25 −40
Original line number Diff line number Diff line
@@ -76,17 +76,12 @@ static struct dev_pm_opp *_find_opp_of_np(struct opp_table *opp_table,
{
	struct dev_pm_opp *opp;

	mutex_lock(&opp_table->lock);
	guard(mutex)(&opp_table->lock);

	list_for_each_entry(opp, &opp_table->opp_list, node) {
		if (opp->np == opp_np) {
			dev_pm_opp_get(opp);
			mutex_unlock(&opp_table->lock);
			return opp;
		if (opp->np == opp_np)
			return dev_pm_opp_get(opp);
	}
	}

	mutex_unlock(&opp_table->lock);

	return NULL;
}
@@ -105,19 +100,15 @@ static struct opp_table *_find_table_of_opp_np(struct device_node *opp_np)

	opp_table_np = of_get_parent(opp_np);
	if (!opp_table_np)
		goto err;
		return ERR_PTR(-ENODEV);

	guard(mutex)(&opp_table_lock);

	mutex_lock(&opp_table_lock);
	list_for_each_entry(opp_table, &opp_tables, node) {
		if (opp_table_np == opp_table->np) {
			dev_pm_opp_get_opp_table_ref(opp_table);
			mutex_unlock(&opp_table_lock);
			return opp_table;
		if (opp_table_np == opp_table->np)
			return dev_pm_opp_get_opp_table_ref(opp_table);
	}
	}
	mutex_unlock(&opp_table_lock);

err:
	return ERR_PTR(-ENODEV);
}

@@ -142,9 +133,8 @@ static void _opp_table_free_required_tables(struct opp_table *opp_table)
	opp_table->required_opp_count = 0;
	opp_table->required_opp_tables = NULL;

	mutex_lock(&opp_table_lock);
	guard(mutex)(&opp_table_lock);
	list_del(&opp_table->lazy);
	mutex_unlock(&opp_table_lock);
}

/*
@@ -201,9 +191,8 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
		 * The OPP table is not held while allocating the table, take it
		 * now to avoid corruption to the lazy_opp_tables list.
		 */
		mutex_lock(&opp_table_lock);
		guard(mutex)(&opp_table_lock);
		list_add(&opp_table->lazy, &lazy_opp_tables);
		mutex_unlock(&opp_table_lock);
	}
}

@@ -357,7 +346,7 @@ static void lazy_link_required_opp_table(struct opp_table *new_table)
	struct dev_pm_opp *opp;
	int i, ret;

	mutex_lock(&opp_table_lock);
	guard(mutex)(&opp_table_lock);

	list_for_each_entry_safe(opp_table, temp, &lazy_opp_tables, lazy) {
		struct device_node *opp_np __free(device_node);
@@ -408,8 +397,6 @@ static void lazy_link_required_opp_table(struct opp_table *new_table)
				_required_opps_available(opp, opp_table->required_opp_count);
		}
	}

	mutex_unlock(&opp_table_lock);
}

static int _bandwidth_supported(struct device *dev, struct opp_table *opp_table)
@@ -970,15 +957,14 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table)
	struct dev_pm_opp *opp;

	/* OPP table is already initialized for the device */
	mutex_lock(&opp_table->lock);
	scoped_guard(mutex, &opp_table->lock) {
		if (opp_table->parsed_static_opps) {
			opp_table->parsed_static_opps++;
		mutex_unlock(&opp_table->lock);
			return 0;
		}

		opp_table->parsed_static_opps = 1;
	mutex_unlock(&opp_table->lock);
	}

	/* We have opp-table node now, iterate over it and add OPPs */
	for_each_available_child_of_node(opp_table->np, np) {
@@ -1018,15 +1004,14 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
	const __be32 *val;
	int nr, ret = 0;

	mutex_lock(&opp_table->lock);
	scoped_guard(mutex, &opp_table->lock) {
		if (opp_table->parsed_static_opps) {
			opp_table->parsed_static_opps++;
		mutex_unlock(&opp_table->lock);
			return 0;
		}

		opp_table->parsed_static_opps = 1;
	mutex_unlock(&opp_table->lock);
	}

	prop = of_find_property(dev->of_node, "operating-points", NULL);
	if (!prop) {