summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-12-07 10:34:31 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2013-03-15 09:53:30 +0100
commit87eebfe9662506ca1d699150a27f6d524ac79a51 (patch)
tree5fb0451d104d144c359afef23f576dc22fe7a6c9 /drivers/clk/clk.c
parentd34aca4c09615870b694820dc21049bd1e77030e (diff)
downloadbarebox-87eebfe9662506ca1d699150a27f6d524ac79a51.tar.gz
barebox-87eebfe9662506ca1d699150a27f6d524ac79a51.tar.xz
clk: Add is_enabled callback
This allows us to better detect whether a clk is enabled or not. - If we can ask a clk, ask it. If it's enabled, go on and ask parents - If we can't ask it, but it can be enabled, depend on the enable_count. if it's positive, go on and ask parents - If we can't ask it and it cannot be enabled, assume it is enabled and ask parents. This makes the CLK_ALWAYS_ENABLED unnecessary, since the fixed clk now always returns 1 in its is_enabled callback. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index cb94755c5a..690a0c63da 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -46,9 +46,6 @@ int clk_enable(struct clk *clk)
if (IS_ERR(clk))
return PTR_ERR(clk);
- if (clk->flags & CLK_ALWAYS_ENABLED)
- return 0;
-
if (!clk->enable_count) {
ret = clk_parent_enable(clk);
if (ret)
@@ -73,9 +70,6 @@ void clk_disable(struct clk *clk)
if (IS_ERR(clk))
return;
- if (clk->flags & CLK_ALWAYS_ENABLED)
- return;
-
if (!clk->enable_count)
return;
@@ -211,23 +205,60 @@ int clk_register(struct clk *clk)
list_add_tail(&clk->list, &clks);
- if (clk->flags & CLK_ALWAYS_ENABLED) {
- clk->enable_count = 1;
+ return 0;
+}
+
+int clk_is_enabled(struct clk *clk)
+{
+ int enabled;
+
+ if (IS_ERR(clk))
+ return 0;
+
+ if (clk->ops->is_enabled) {
+ /*
+ * If we can ask a clk, do it
+ */
+ enabled = clk->ops->is_enabled(clk);
+ } else {
+ if (clk->ops->enable) {
+ /*
+ * If we can't ask a clk, but it can be enabled,
+ * depend on the enable_count.
+ */
+ enabled = clk->enable_count;
+ } else {
+ /*
+ * We can't ask a clk, it has no enable op,
+ * so assume it's enabled and go on and ask
+ * the parent.
+ */
+ enabled = 1;
+ }
}
- return 0;
+ if (!enabled)
+ return 0;
+
+ clk = clk_get_parent(clk);
+
+ if (IS_ERR(clk))
+ return 1;
+
+ return clk_is_enabled(clk);
+}
+
+int clk_is_enabled_always(struct clk *clk)
+{
+ return 1;
}
static void dump_one(struct clk *clk, int verbose, int indent)
{
struct clk *c;
- char *always = "";
-
- if (clk->flags & CLK_ALWAYS_ENABLED)
- always = "always ";
- printf("%*s%s (rate %ld, %s%sabled)\n", indent * 4, "", clk->name, clk_get_rate(clk),
- always, clk->enable_count ? "en" : "dis");
+ printf("%*s%s (rate %ld, %sabled)\n", indent * 4, "", clk->name, clk_get_rate(clk),
+ clk_is_enabled(clk) ? "en" : "dis");
if (verbose) {
if (clk->num_parents > 1) {