Thread (41 messages) 41 messages, 6 authors, 2013-08-16

[PATCH v1 03/14] clk: Add of_clk_match() for device drivers

From: Tomasz Figa <hidden>
Date: 2013-07-25 08:12:27
Also in: linux-arm-msm, lkml

Hi Stephen,

On Wednesday 24 of July 2013 17:43:31 Stephen Boyd wrote:
In similar fashion as of_regulator_match() add an of_clk_match()
function that finds an initializes clock init_data structs from
devicetree. Drivers should use this API to find clocks that their
device is providing and then iterate over their match table
registering the clocks with the init data parsed.
I think all you need here is declaring all your clock drivers using 
CLK_OF_DECLARE() macro. Then they will be automatically probed by 
of_clk_init(). See last lines of drivers/clk/clk-fixed-rate.c for an 
example.

Best regards,
Tomasz
quoted hunk ↗ jump to hunk
Signed-off-by: Stephen Boyd <redacted>
---
 drivers/clk/clk.c            | 64
++++++++++++++++++++++++++++++++++++++++++++
include/linux/clk-provider.h | 16 +++++++++++
 2 files changed, 80 insertions(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index ea8e951b..1e3e0db 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2289,4 +2289,68 @@ err:
 	return -ENOMEM;
 }
 EXPORT_SYMBOL_GPL(of_init_clk_data);
+
+/**
+ * of_clk_match() - Scan and match clock providers from the DT node of
a device + * @dev: device initializing clock providers
+ * @matches: match table of clocks
+ * @num_matches: number of entries in @matches
+ *
+ * This function uses a match table specified by the clock driver to
parse + * clock init data from the device tree. @dev is expected to be
a device with + * a 'clocks' child node containing a set of child
nodes, each providing the + * init data for one clock. The data parsed
from a child node will be matched + * to a clock based on the child
node's name. Note that the match table is + * modified in place.
+ *
+ * Returns the number of matches found or a negative error code on
failure. + */
+int of_clk_match(struct device *dev, struct of_clk_match *matches,
+		 int num_matches)
+{
+	int count = 0;
+	int err, i;
+	struct device_node *np, *clocks;
+	struct clk_init_data *init;
+
+	clocks = of_find_node_by_name(dev->of_node, "clocks");
+	if (!clocks)
+		return -EINVAL;
+
+	for (i = 0; i < num_matches; i++) {
+		struct of_clk_match *match = &matches[i];
+		match->init_data = NULL;
+		match->of_node = NULL;
+	}
+
+	for_each_available_child_of_node(clocks, np) {
+		for (i = 0; i < num_matches; i++) {
+			struct of_clk_match *match = &matches[i];
+			if (match->of_node)
+				continue;
+
+			if (strcmp(match->name, np->name))
+				continue;
+
+			init = devm_kzalloc(dev, sizeof(*init), 
GFP_KERNEL);
+			if (!init)
+				return -ENOMEM;
+
+			err = of_init_clk_data(np, init);
+			if (err) {
+				dev_err(dev,
+					"failed to parse DT for clock 
%s\n",
quoted hunk ↗ jump to hunk
+					np->name);
+				return err;
+			}
+			match->of_node = np;
+			match->init_data = init;
+			count++;
+			break;
+		}
+	}
+
+	return count;
+}
+EXPORT_SYMBOL_GPL(of_clk_match);
 #endif
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 18d6362..484f8ad 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -461,6 +461,13 @@ struct clk_onecell_data {
 		__used __section(__clk_of_table)		\
 		= { .compatible = compat, .data = fn };

+struct of_clk_match {
+	const char *name;
+	void *driver_data;
+	struct clk_init_data *init_data;
+	struct device_node *of_node;
+};
+
 #ifdef CONFIG_OF
 int of_clk_add_provider(struct device_node *np,
 			struct clk *(*clk_src_get)(struct of_phandle_args 
*args,
quoted hunk ↗ jump to hunk
@@ -475,6 +482,9 @@ const char *of_clk_get_parent_name(struct
device_node *np, int index); void of_clk_init(const struct of_device_id
*matches);
 int of_init_clk_data(struct device_node *np, struct clk_init_data
*init);

+int of_clk_match(struct device *dev, struct of_clk_match *matches,
+		 int num_matches);
+
 #else /* !CONFIG_OF */

 static inline int of_clk_add_provider(struct device_node *np,
@@ -508,6 +518,12 @@ of_init_clk_data(struct device_node *np, struct
clk_init_data *init) {
 	return 0;
 }
+static inline int
+of_clk_match(struct device *dev, struct of_clk_match *matches, int
num_matches) +{
+
+	return 0;
+}
 #endif /* CONFIG_OF */
 #endif /* CONFIG_COMMON_CLK */
 #endif /* CLK_PROVIDER_H */
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help