summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>2013-11-09 14:24:19 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2013-11-11 09:26:59 +0100
commitfeb1e38b433a07645e91924df248f6eac93a383e (patch)
treebb92c01e5f23b18b8308640cfc90a05f9811285c /drivers/clk/clk.c
parentfa1a406f7245c5482a17014d5b97e8948352e5a5 (diff)
downloadbarebox-feb1e38b433a07645e91924df248f6eac93a383e.tar.gz
barebox-feb1e38b433a07645e91924df248f6eac93a383e.tar.xz
clk: add of_clk_init and CLK_OF_DECLARE macro
This add barebox versions of of_clk_init for parsing and registering clock providers from DT. Also, a macro CLK_OF_DECLARE is added, that allows to put init callbacks into its own section that can be linked in the binary. Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 5942e29c48..31d73c028c 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -271,6 +271,10 @@ struct of_clk_provider {
void *data;
};
+extern struct of_device_id __clk_of_table_start[];
+const struct of_device_id __clk_of_table_sentinel
+ __attribute__ ((unused,section (".__clk_of_table_end")));
+
static LIST_HEAD(of_clk_providers);
struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
@@ -355,6 +359,39 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
return clk;
}
+
+/**
+ * of_clk_init() - Scan and init clock providers from the DT
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: array of compatible values and init functions for providers.
+ *
+ * This function scans the device tree for matching clock providers and
+ * calls their initialization functions
+ *
+ * Returns 0 on success, < 0 on failure.
+ */
+int of_clk_init(struct device_node *root, const struct of_device_id *matches)
+{
+ const struct of_device_id *match;
+ int rc;
+
+ if (!root)
+ root = of_find_node_by_path("/");
+ if (!root)
+ return -EINVAL;
+ if (!matches)
+ matches = __clk_of_table_start;
+
+ for_each_matching_node_and_match(root, matches, &match) {
+ of_clk_init_cb_t clk_init_cb = (of_clk_init_cb_t)match->data;
+ rc = clk_init_cb(root);
+ if (rc)
+ pr_err("%s: failed to init clock for %s: %d\n",
+ __func__, root->full_name, rc);
+ }
+
+ return 0;
+}
#endif
static void dump_one(struct clk *clk, int verbose, int indent)