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

OPP: Migrate set-regulators API to use set-config helpers



Now that we have a central API to handle all OPP table configurations,
migrate the set-regulators family of helpers to use the new
infrastructure.

The return type and parameter to the APIs change a bit due to this,
update the current users as well in the same commit in order to avoid
breaking builds.

Reviewed-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
parent 25a18559
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -29,9 +29,9 @@ struct private_data {

	cpumask_var_t cpus;
	struct device *cpu_dev;
	struct opp_table *opp_table;
	struct cpufreq_frequency_table *freq_table;
	bool have_static_opps;
	int opp_token;
};

static LIST_HEAD(priv_list);
@@ -220,9 +220,9 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
	 */
	reg_name[0] = find_supply_name(cpu_dev);
	if (reg_name[0]) {
		priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, reg_name);
		if (IS_ERR(priv->opp_table)) {
			ret = PTR_ERR(priv->opp_table);
		priv->opp_token = dev_pm_opp_set_regulators(cpu_dev, reg_name);
		if (priv->opp_token < 0) {
			ret = priv->opp_token;
			if (ret != -EPROBE_DEFER)
				dev_err(cpu_dev, "failed to set regulators: %d\n",
					ret);
@@ -294,7 +294,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
out:
	if (priv->have_static_opps)
		dev_pm_opp_of_cpumask_remove_table(priv->cpus);
	dev_pm_opp_put_regulators(priv->opp_table);
	dev_pm_opp_put_regulators(priv->opp_token);
free_cpumask:
	free_cpumask_var(priv->cpus);
	return ret;
@@ -308,7 +308,7 @@ static void dt_cpufreq_release(void)
		dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table);
		if (priv->have_static_opps)
			dev_pm_opp_of_cpumask_remove_table(priv->cpus);
		dev_pm_opp_put_regulators(priv->opp_table);
		dev_pm_opp_put_regulators(priv->opp_token);
		free_cpumask_var(priv->cpus);
		list_del(&priv->node);
	}
+7 −12
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ struct exynos_bus {

	unsigned long curr_freq;

	struct opp_table *opp_table;
	int opp_token;
	struct clk *clk;
	unsigned int ratio;
};
@@ -161,8 +161,7 @@ static void exynos_bus_exit(struct device *dev)

	dev_pm_opp_of_remove_table(dev);
	clk_disable_unprepare(bus->clk);
	dev_pm_opp_put_regulators(bus->opp_table);
	bus->opp_table = NULL;
	dev_pm_opp_put_regulators(bus->opp_token);
}

static void exynos_bus_passive_exit(struct device *dev)
@@ -179,18 +178,16 @@ static int exynos_bus_parent_parse_of(struct device_node *np,
					struct exynos_bus *bus)
{
	struct device *dev = bus->dev;
	struct opp_table *opp_table;
	const char *supplies[] = { "vdd", NULL };
	int i, ret, count, size;

	opp_table = dev_pm_opp_set_regulators(dev, supplies);
	if (IS_ERR(opp_table)) {
		ret = PTR_ERR(opp_table);
	ret = dev_pm_opp_set_regulators(dev, supplies);
	if (ret < 0) {
		dev_err(dev, "failed to set regulators %d\n", ret);
		return ret;
	}

	bus->opp_table = opp_table;
	bus->opp_token = ret;

	/*
	 * Get the devfreq-event devices to get the current utilization of
@@ -236,8 +233,7 @@ static int exynos_bus_parent_parse_of(struct device_node *np,
	return 0;

err_regulator:
	dev_pm_opp_put_regulators(bus->opp_table);
	bus->opp_table = NULL;
	dev_pm_opp_put_regulators(bus->opp_token);

	return ret;
}
@@ -459,8 +455,7 @@ static int exynos_bus_probe(struct platform_device *pdev)
	dev_pm_opp_of_remove_table(dev);
	clk_disable_unprepare(bus->clk);
err_reg:
	dev_pm_opp_put_regulators(bus->opp_table);
	bus->opp_table = NULL;
	dev_pm_opp_put_regulators(bus->opp_token);

	return ret;
}
+19 −72
Original line number Diff line number Diff line
@@ -991,8 +991,8 @@ static int _set_opp_custom(const struct opp_table *opp_table,
	int size;

	/*
	 * We support this only if dev_pm_opp_set_regulators() was called
	 * earlier.
	 * We support this only if dev_pm_opp_set_config() was called
	 * earlier to set regulators.
	 */
	if (opp_table->sod_supplies) {
		size = sizeof(*old_opp->supplies) * opp_table->regulator_count;
@@ -2097,7 +2097,7 @@ void dev_pm_opp_put_prop_name(struct opp_table *opp_table)
EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);

/**
 * dev_pm_opp_set_regulators() - Set regulator names for the device
 * _opp_set_regulators() - Set regulator names for the device
 * @dev: Device for which regulator name is being set.
 * @names: Array of pointers to the names of the regulator.
 * @count: Number of regulators.
@@ -2108,12 +2108,11 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
 *
 * This must be called before any OPPs are initialized for the device.
 */
struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
static int _opp_set_regulators(struct opp_table *opp_table, struct device *dev,
			       const char * const names[])
{
	struct dev_pm_opp_supply *supplies;
	const char * const *temp = names;
	struct opp_table *opp_table;
	struct regulator *reg;
	int count = 0, ret, i;

@@ -2122,29 +2121,17 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
		count++;

	if (!count)
		return ERR_PTR(-EINVAL);

	opp_table = _add_opp_table(dev, false);
	if (IS_ERR(opp_table))
		return opp_table;

	/* This should be called before OPPs are initialized */
	if (WARN_ON(!list_empty(&opp_table->opp_list))) {
		ret = -EBUSY;
		goto err;
	}
		return -EINVAL;

	/* Another CPU that shares the OPP table has set the regulators ? */
	if (opp_table->regulators)
		return opp_table;
		return 0;

	opp_table->regulators = kmalloc_array(count,
					      sizeof(*opp_table->regulators),
					      GFP_KERNEL);
	if (!opp_table->regulators) {
		ret = -ENOMEM;
		goto err;
	}
	if (!opp_table->regulators)
		return -ENOMEM;

	for (i = 0; i < count; i++) {
		reg = regulator_get_optional(dev, names[i]);
@@ -2174,7 +2161,7 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
	}
	mutex_unlock(&opp_table->lock);

	return opp_table;
	return 0;

free_regulators:
	while (i != 0)
@@ -2183,26 +2170,20 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
	kfree(opp_table->regulators);
	opp_table->regulators = NULL;
	opp_table->regulator_count = -1;
err:
	dev_pm_opp_put_opp_table(opp_table);

	return ERR_PTR(ret);
	return ret;
}
EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulators);

/**
 * dev_pm_opp_put_regulators() - Releases resources blocked for regulator
 * @opp_table: OPP table returned from dev_pm_opp_set_regulators().
 * _opp_put_regulators() - Releases resources blocked for regulator
 * @opp_table: OPP table returned from _opp_set_regulators().
 */
void dev_pm_opp_put_regulators(struct opp_table *opp_table)
static void _opp_put_regulators(struct opp_table *opp_table)
{
	int i;

	if (unlikely(!opp_table))
		return;

	if (!opp_table->regulators)
		goto put_opp_table;
		return;

	if (opp_table->enabled) {
		for (i = opp_table->regulator_count - 1; i >= 0; i--)
@@ -2225,40 +2206,7 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
	kfree(opp_table->regulators);
	opp_table->regulators = NULL;
	opp_table->regulator_count = -1;

put_opp_table:
	dev_pm_opp_put_opp_table(opp_table);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators);

static void devm_pm_opp_regulators_release(void *data)
{
	dev_pm_opp_put_regulators(data);
}

/**
 * devm_pm_opp_set_regulators() - Set regulator names for the device
 * @dev: Device for which regulator name is being set.
 * @names: Array of pointers to the names of the regulator.
 * @count: Number of regulators.
 *
 * This is a resource-managed variant of dev_pm_opp_set_regulators().
 *
 * Return: 0 on success and errorno otherwise.
 */
int devm_pm_opp_set_regulators(struct device *dev,
			       const char * const names[])
{
	struct opp_table *opp_table;

	opp_table = dev_pm_opp_set_regulators(dev, names);
	if (IS_ERR(opp_table))
		return PTR_ERR(opp_table);

	return devm_add_action_or_reset(dev, devm_pm_opp_regulators_release,
					opp_table);
}
EXPORT_SYMBOL_GPL(devm_pm_opp_set_regulators);

/**
 * dev_pm_opp_set_clkname() - Set clk name for the device
@@ -2633,7 +2581,7 @@ static void _opp_clear_config(struct opp_config_data *data)
	if (data->flags & OPP_CONFIG_GENPD)
		dev_pm_opp_detach_genpd(data->opp_table);
	if (data->flags & OPP_CONFIG_REGULATOR)
		dev_pm_opp_put_regulators(data->opp_table);
		_opp_put_regulators(data->opp_table);
	if (data->flags & OPP_CONFIG_SUPPORTED_HW)
		dev_pm_opp_put_supported_hw(data->opp_table);
	if (data->flags & OPP_CONFIG_REGULATOR_HELPER)
@@ -2758,11 +2706,10 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config)

	/* Configure supplies */
	if (config->regulator_names) {
		err = dev_pm_opp_set_regulators(dev, config->regulator_names);
		if (IS_ERR(err)) {
			ret = PTR_ERR(err);
		ret = _opp_set_regulators(opp_table, dev,
					  config->regulator_names);
		if (ret)
			goto err;
		}

		data->flags |= OPP_CONFIG_REGULATOR;
	}
+28 −16
Original line number Diff line number Diff line
@@ -189,9 +189,6 @@ void dev_pm_opp_put_supported_hw(struct opp_table *opp_table);
int devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count);
struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name);
void dev_pm_opp_put_prop_name(struct opp_table *opp_table);
struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[]);
void dev_pm_opp_put_regulators(struct opp_table *opp_table);
int devm_pm_opp_set_regulators(struct device *dev, const char * const names[]);
struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name);
void dev_pm_opp_put_clkname(struct opp_table *opp_table);
int devm_pm_opp_set_clkname(struct device *dev, const char *name);
@@ -409,19 +406,6 @@ static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, con

static inline void dev_pm_opp_put_prop_name(struct opp_table *opp_table) {}

static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[])
{
	return ERR_PTR(-EOPNOTSUPP);
}

static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {}

static inline int devm_pm_opp_set_regulators(struct device *dev,
					     const char * const names[])
{
	return -EOPNOTSUPP;
}

static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name)
{
	return ERR_PTR(-EOPNOTSUPP);
@@ -606,4 +590,32 @@ static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_ta
}
#endif

/* OPP Configuration helpers */

/* Regulators helpers */
static inline int dev_pm_opp_set_regulators(struct device *dev,
					    const char * const names[])
{
	struct dev_pm_opp_config config = {
		.regulator_names = names,
	};

	return dev_pm_opp_set_config(dev, &config);
}

static inline void dev_pm_opp_put_regulators(int token)
{
	dev_pm_opp_clear_config(token);
}

static inline int devm_pm_opp_set_regulators(struct device *dev,
					     const char * const names[])
{
	struct dev_pm_opp_config config = {
		.regulator_names = names,
	};

	return devm_pm_opp_set_config(dev, &config);
}

#endif		/* __LINUX_OPP_H__ */