diff options
author | Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | 2013-11-09 14:24:19 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-11-11 09:26:59 +0100 |
commit | feb1e38b433a07645e91924df248f6eac93a383e (patch) | |
tree | bb92c01e5f23b18b8308640cfc90a05f9811285c /drivers/clk/clk.c | |
parent | fa1a406f7245c5482a17014d5b97e8948352e5a5 (diff) | |
download | barebox-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.c | 37 |
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) |