From: Álvaro Fernández Rojas Date: Wed, 28 May 2025 07:10:29 +0000 (+0200) Subject: generic: 6.6: backport devm_clk_get_optional_enabled_with_rate X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=268c352e44956a3e7fe86e68ad727ba57b0a75a5;p=thirdparty%2Fopenwrt.git generic: 6.6: backport devm_clk_get_optional_enabled_with_rate This is needed for mac80211 v6.14.5 update. 9934a1bd45b2b clk: provide devm_clk_get_optional_enabled_with_rate() https://github.com/torvalds/linux/commit/9934a1bd45b2b03f6d1204a6ae2780d3b009799f Signed-off-by: Álvaro Fernández Rojas --- diff --git a/target/linux/generic/backport-6.6/920-v6.12-clk-provide-devm_clk_get_optional_enabled_with_rate.patch b/target/linux/generic/backport-6.6/920-v6.12-clk-provide-devm_clk_get_optional_enabled_with_rate.patch new file mode 100644 index 00000000000..4a8e5c4c6e6 --- /dev/null +++ b/target/linux/generic/backport-6.6/920-v6.12-clk-provide-devm_clk_get_optional_enabled_with_rate.patch @@ -0,0 +1,104 @@ +From 9934a1bd45b2b03f6d1204a6ae2780d3b009799f Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski +Date: Mon, 5 Aug 2024 10:57:31 +0200 +Subject: [PATCH] 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: Bartosz Golaszewski +Link: https://lore.kernel.org/r/20240805-clk-new-helper-v2-1-e5fdd1e1d729@linaro.org +Signed-off-by: Stephen Boyd +--- + drivers/clk/clk-devres.c | 28 ++++++++++++++++++++++++++++ + include/linux/clk.h | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 61 insertions(+) + +--- a/drivers/clk/clk-devres.c ++++ b/drivers/clk/clk-devres.c +@@ -99,6 +99,34 @@ struct clk *devm_clk_get_optional_enable + } + 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; +--- a/include/linux/clk.h ++++ b/include/linux/clk.h +@@ -608,6 +608,32 @@ struct clk *devm_clk_get_optional_prepar + 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. + * @dev: device for clock "consumer" +@@ -948,6 +974,13 @@ static inline struct clk *devm_clk_get_o + { + 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)