[PATCH] clk: Allocate and add clock lookups from clk_register()

Viresh Kumar viresh.kumar at st.com
Fri Apr 13 02:34:57 EDT 2012


clock lookups are required for few clocks for which we do clk_get() or
clk_get_sys(). Adding clock lookups for them with new clock framework, would
mean a lot of code for each platform. Simplify this by doing this allocation and
addition to global list in clk_register() only.

This is done on request by the caller, i.e. only if user passes valid pointers
in "dev_id" OR "con_id" fields.

A lot of changes at other places/files/comments are also required, that i would
do separately. This is the initial version to get initial feedback.

Pointer to original discussion:
http://www.spinics.net/lists/arm-kernel/msg169133.html

Signed-off-by: Viresh Kumar <viresh.kumar at st.com>
---
 drivers/clk/clk.c            |   33 ++++++++++++++++++++++++++-------
 include/linux/clk-provider.h |    4 +++-
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 2bcce5a..16ce136 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -9,6 +9,7 @@
  * Standard functionality for the common clock API.  See Documentation/clk.txt
  */
 
+#include <linux/clkdev.h>
 #include <linux/clk-private.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -1341,7 +1342,8 @@ out:
  */
 struct clk *clk_register(struct device *dev, const char *name,
 		const struct clk_ops *ops, struct clk_hw *hw,
-		const char **parent_names, u8 num_parents, unsigned long flags)
+		const char **parent_names, u8 num_parents, unsigned long flags,
+		struct clk_lookup **cl, const char *dev_id, const char *con_id)
 {
 	int i, ret = -ENOMEM;
 	struct clk *clk;
@@ -1365,7 +1367,7 @@ struct clk *clk_register(struct device *dev, const char *name,
 
 	if (!clk->parent_names) {
 		pr_err("%s: could not allocate clk->parent_names\n", __func__);
-		goto fail_parent_names;
+		goto free_clk;
 	}
 
 	/* copy each string name in case parent_names is __initdata */
@@ -1373,19 +1375,36 @@ struct clk *clk_register(struct device *dev, const char *name,
 		clk->parent_names[i] = kstrdup(parent_names[i], GFP_KERNEL);
 		if (!clk->parent_names[i]) {
 			pr_err("%s: could not copy parent_names\n", __func__);
-			goto fail_parent_names_copy;
+			goto free_parents;
 		}
 	}
 
 	ret = __clk_init(dev, clk);
-	if (!ret)
-		return clk;
+	if (ret)
+		goto free_parents;
+
+	if (dev_id || con_id) {
+		struct clk_lookup *lookup;
+
+		lookup = clkdev_alloc(clk, dev_id, con_id);
+		if (!lookup) {
+			ret = ENODEV;
+			goto free_parents;
+		}
+
+		clkdev_add(lookup);
+
+		if (cl)
+			*cl = lookup;
+	}
+
+	return clk;
 
-fail_parent_names_copy:
+free_parents:
 	while (--i >= 0)
 		kfree(clk->parent_names[i]);
 	kfree(clk->parent_names);
-fail_parent_names:
+free_clk:
 	kfree(clk);
 fail_out:
 	return ERR_PTR(ret);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 8bb93c4..a50119d 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -12,6 +12,7 @@
 #define __LINUX_CLK_PROVIDER_H
 
 #include <linux/clk.h>
+#include <linux/clkdev.h>
 
 #ifdef CONFIG_COMMON_CLK
 
@@ -281,7 +282,8 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
  */
 struct clk *clk_register(struct device *dev, const char *name,
 		const struct clk_ops *ops, struct clk_hw *hw,
-		const char **parent_names, u8 num_parents, unsigned long flags);
+		const char **parent_names, u8 num_parents, unsigned long flags,
+		struct clk_lookup **cl, const char *dev_id, const char *con_id);
 
 /* helper functions */
 const char *__clk_get_name(struct clk *clk);
-- 
1.7.9




More information about the linux-arm-kernel mailing list