[PATCH] clk: add a function to retrieve a clk_hw instance from a clkspec definition

From: Boris Brezillon
Date: Fri Jan 15 2016 - 04:36:23 EST


of_clk_hw_get_from_provider() is providing a way to retrieve a clk_hw
instance from a clkspec definition. Which is usefull in case a clk driver
wants to get one of its own instance from a clkspec, without allocating a
new per-user clk struct.

Signed-off-by: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxxxxxxx>
---
drivers/clk/clk.c | 36 ++++++++++++++++++++++++++++++++++++
include/linux/clk-provider.h | 1 +
2 files changed, 37 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index f13c3f4..fbef1b7 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3001,6 +3001,42 @@ void of_clk_del_provider(struct device_node *np)
}
EXPORT_SYMBOL_GPL(of_clk_del_provider);

+/**
+ * of_clk_hw_get_from_provider() - Look for a clk_hw instance registered with
+ * the given clkspec definition.
+ * @clkspec: pointer to a clock specifier data structure
+ *
+ * This function looks up a struct clk_hw from the registered list of clock
+ * providers, an input is a clock specifier data structure as returned
+ * from the of_parse_phandle_with_args() function call.
+ */
+struct clk_hw *of_clk_hw_get_from_provider(struct of_phandle_args *clkspec)
+{
+ struct clk_hw *clk_hw = ERR_PTR(-EPROBE_DEFER);
+ struct of_clk_provider *provider;
+
+ if (!clkspec)
+ return ERR_PTR(-EINVAL);
+
+ /* Check if we have such a provider in our array */
+ mutex_lock(&of_clk_mutex);
+ list_for_each_entry(provider, &of_clk_providers, link) {
+ struct clk *clk = ERR_PTR(-EPROBE_DEFER);
+
+ if (provider->node == clkspec->np)
+ clk = provider->get(clkspec, provider->data);
+
+ if (!IS_ERR(clk)) {
+ clk_hw = __clk_get_hw(clk);
+ break;
+ }
+ }
+ mutex_unlock(&of_clk_mutex);
+
+ return clk_hw;
+}
+EXPORT_SYMBOL_GPL(of_clk_hw_get_from_provider);
+
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
const char *dev_id, const char *con_id)
{
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index c56988a..bb62517 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -645,6 +645,7 @@ void devm_clk_unregister(struct device *dev, struct clk *clk);
const char *__clk_get_name(const struct clk *clk);
const char *clk_hw_get_name(const struct clk_hw *hw);
struct clk_hw *__clk_get_hw(struct clk *clk);
+struct clk_hw *of_clk_hw_get_from_provider(struct of_phandle_args *clkspec);
unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,