Commit 9934a1bd authored by Bartosz Golaszewski's avatar Bartosz Golaszewski Committed by Stephen Boyd
Browse files

clk: provide devm_clk_get_optional_enabled_with_rate()



There are clock users in the kernel that can't use
devm_clk_get_optional_enabled() as they need to set rate after getting
the clock and before enabling it. Provide a managed helper that wraps
these operations in the correct order.

Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Link: https://lore.kernel.org/r/20240805-clk-new-helper-v2-1-e5fdd1e1d729@linaro.org


Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 706ae644
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -99,6 +99,34 @@ struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
}
EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);

struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev,
						    const char *id,
						    unsigned long rate)
{
	struct clk *clk;
	int ret;

	clk = __devm_clk_get(dev, id, clk_get_optional, NULL,
			     clk_disable_unprepare);
	if (IS_ERR(clk))
		return ERR_CAST(clk);

	ret = clk_set_rate(clk, rate);
	if (ret)
		goto out_put_clk;

	ret = clk_prepare_enable(clk);
	if (ret)
		goto out_put_clk;

	return clk;

out_put_clk:
	devm_clk_put(dev, clk);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled_with_rate);

struct clk_bulk_devres {
	struct clk_bulk_data *clks;
	int num_clks;
+33 −0
Original line number Diff line number Diff line
@@ -640,6 +640,32 @@ struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id);
 */
struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id);

/**
 * devm_clk_get_optional_enabled_with_rate - devm_clk_get_optional() +
 *                                           clk_set_rate() +
 *                                           clk_prepare_enable()
 * @dev: device for clock "consumer"
 * @id: clock consumer ID
 * @rate: new clock rate
 *
 * Context: May sleep.
 *
 * Return: a struct clk corresponding to the clock producer, or
 * valid IS_ERR() condition containing errno.  The implementation
 * uses @dev and @id to determine the clock consumer, and thereby
 * the clock producer.  If no such clk is found, it returns NULL
 * which serves as a dummy clk.  That's the only difference compared
 * to devm_clk_get_enabled().
 *
 * The returned clk (if valid) is prepared and enabled and rate was set.
 *
 * The clock will automatically be disabled, unprepared and freed
 * when the device is unbound from the bus.
 */
struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev,
						    const char *id,
						    unsigned long rate);

/**
 * devm_get_clk_from_child - lookup and obtain a managed reference to a
 *			     clock producer from child node.
@@ -982,6 +1008,13 @@ static inline struct clk *devm_clk_get_optional_enabled(struct device *dev,
	return NULL;
}

static inline struct clk *
devm_clk_get_optional_enabled_with_rate(struct device *dev, const char *id,
					unsigned long rate)
{
	return NULL;
}

static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
						 struct clk_bulk_data *clks)
{