sh: clkfwk: Consolidate the ALWAYS_ENABLED / NEEDS_INIT mess.
There is no real distinction here in behaviour, either a clock needs to
be enabled on initialiation or not. The ALWAYS_ENABLED flag was always
intended to only apply to clocks that were physically always on and could
simply not be disabled at all from software. Unfortunately over time this
was abused and the meaning became a bit blurry.
So, we kill off both of all of those paths now, as well as the newer
NEEDS_INIT flag, and consolidate on a CLK_ENABLE_ON_INIT. Clocks that
need to be enabled on initialization can set this, and it will purposely
enable them and bump the refcount up.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 0a06df8..c683be5 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -43,26 +43,26 @@
*/
static struct clk master_clk = {
.name = "master_clk",
- .flags = CLK_ALWAYS_ENABLED,
+ .flags = CLK_ENABLE_ON_INIT,
.rate = CONFIG_SH_PCLK_FREQ,
};
static struct clk module_clk = {
.name = "module_clk",
.parent = &master_clk,
- .flags = CLK_ALWAYS_ENABLED,
+ .flags = CLK_ENABLE_ON_INIT,
};
static struct clk bus_clk = {
.name = "bus_clk",
.parent = &master_clk,
- .flags = CLK_ALWAYS_ENABLED,
+ .flags = CLK_ENABLE_ON_INIT,
};
static struct clk cpu_clk = {
.name = "cpu_clk",
.parent = &master_clk,
- .flags = CLK_ALWAYS_ENABLED,
+ .flags = CLK_ENABLE_ON_INIT,
};
/*
@@ -93,39 +93,11 @@
}
}
-static void __clk_init(struct clk *clk)
-{
- /*
- * See if this is the first time we're enabling the clock, some
- * clocks that are always enabled still require "special"
- * initialization. This is especially true if the clock mode
- * changes and the clock needs to hunt for the proper set of
- * divisors to use before it can effectively recalc.
- */
-
- if (clk->flags & CLK_NEEDS_INIT) {
- if (clk->ops && clk->ops->init)
- clk->ops->init(clk);
-
- clk->flags &= ~CLK_NEEDS_INIT;
- }
-}
-
static int __clk_enable(struct clk *clk)
{
- if (!clk)
- return -EINVAL;
-
- clk->usecount++;
-
- /* nothing to do if always enabled */
- if (clk->flags & CLK_ALWAYS_ENABLED)
- return 0;
-
- if (clk->usecount == 1) {
- __clk_init(clk);
-
- __clk_enable(clk->parent);
+ if (clk->usecount++ == 0) {
+ if (clk->parent)
+ __clk_enable(clk->parent);
if (clk->ops && clk->ops->enable)
clk->ops->enable(clk);
@@ -139,6 +111,9 @@
unsigned long flags;
int ret;
+ if (!clk)
+ return -EINVAL;
+
spin_lock_irqsave(&clock_lock, flags);
ret = __clk_enable(clk);
spin_unlock_irqrestore(&clock_lock, flags);
@@ -149,21 +124,11 @@
static void __clk_disable(struct clk *clk)
{
- if (!clk)
- return;
-
- clk->usecount--;
-
- WARN_ON(clk->usecount < 0);
-
- if (clk->flags & CLK_ALWAYS_ENABLED)
- return;
-
- if (clk->usecount == 0) {
+ if (clk->usecount > 0 && !(--clk->usecount)) {
if (likely(clk->ops && clk->ops->disable))
clk->ops->disable(clk);
-
- __clk_disable(clk->parent);
+ if (likely(clk->parent))
+ __clk_disable(clk->parent);
}
}
@@ -171,6 +136,9 @@
{
unsigned long flags;
+ if (!clk)
+ return;
+
spin_lock_irqsave(&clock_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clock_lock, flags);
@@ -211,6 +179,7 @@
mutex_lock(&clock_list_sem);
INIT_LIST_HEAD(&clk->children);
+ clk->usecount = 0;
if (clk->parent)
list_add(&clk->sibling, &clk->parent->children);
@@ -218,19 +187,10 @@
list_add(&clk->sibling, &root_clks);
list_add(&clk->node, &clock_list);
- clk->usecount = 0;
- clk->flags |= CLK_NEEDS_INIT;
-
+ if (clk->ops->init)
+ clk->ops->init(clk);
mutex_unlock(&clock_list_sem);
- if (clk->flags & CLK_ALWAYS_ENABLED) {
- __clk_init(clk);
- pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name);
- if (clk->ops && clk->ops->enable)
- clk->ops->enable(clk);
- pr_debug( "Enabled.");
- }
-
return 0;
}
EXPORT_SYMBOL_GPL(clk_register);
@@ -244,6 +204,15 @@
}
EXPORT_SYMBOL_GPL(clk_unregister);
+static void clk_enable_init_clocks(void)
+{
+ struct clk *clkp;
+
+ list_for_each_entry(clkp, &clock_list, node)
+ if (clkp->flags & CLK_ENABLE_ON_INIT)
+ clk_enable(clkp);
+}
+
unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
@@ -404,9 +373,7 @@
p += sprintf(p, "%-12s\t: %ld.%02ldMHz\t%s\n", clk->name,
rate / 1000000, (rate % 1000000) / 10000,
- ((clk->flags & CLK_ALWAYS_ENABLED) ||
- clk->usecount > 0) ?
- "enabled" : "disabled");
+ (clk->usecount > 0) ? "enabled" : "disabled");
}
return p - buf;
@@ -496,6 +463,9 @@
/* Kick the child clocks.. */
recalculate_root_clocks();
+ /* Enable the necessary init clocks */
+ clk_enable_init_clocks();
+
return ret;
}