From b3cacf318172757783d8272fc333284dd4f50140 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 7 May 2009 10:31:39 +0000 Subject: sh: call clock framework init() callback once Make sure that clk->ops->init() only gets called once in the case of CLK_ALWAYS_ENABLED. Without this patch the init() callback may be called multiple times. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 1dc896483b59..099373ae57d8 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -99,15 +99,18 @@ static int __clk_enable(struct clk *clk) * changes and the clock needs to hunt for the proper set of * divisors to use before it can effectively recalc. */ + + if (clk->flags & CLK_ALWAYS_ENABLED) { + kref_get(&clk->kref); + return 0; + } + if (unlikely(atomic_read(&clk->kref.refcount) == 1)) if (clk->ops && clk->ops->init) clk->ops->init(clk); kref_get(&clk->kref); - if (clk->flags & CLK_ALWAYS_ENABLED) - return 0; - if (likely(clk->ops && clk->ops->enable)) clk->ops->enable(clk); -- cgit v1.2.3 From 4f5ecaa05493dfddf155b40224b951592bfce325 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 8 May 2009 08:23:29 +0000 Subject: sh: clock framework update, fix count and kill off kref This patch updates the clock framework use count code. With this patch the enable() and disable() callbacks only get called when counting from and to zero. While at it the kref stuff gets replaced with an int. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 69 +++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 32 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 099373ae57d8..133dbe403341 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -90,7 +89,7 @@ static void propagate_rate(struct clk *clk) } } -static int __clk_enable(struct clk *clk) +static void __clk_init(struct clk *clk) { /* * See if this is the first time we're enabling the clock, some @@ -100,19 +99,33 @@ static int __clk_enable(struct clk *clk) * divisors to use before it can effectively recalc. */ - if (clk->flags & CLK_ALWAYS_ENABLED) { - kref_get(&clk->kref); - return 0; - } - - if (unlikely(atomic_read(&clk->kref.refcount) == 1)) + if (clk->flags & CLK_NEEDS_INIT) { if (clk->ops && clk->ops->init) clk->ops->init(clk); - kref_get(&clk->kref); + 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); - if (likely(clk->ops && clk->ops->enable)) - clk->ops->enable(clk); + __clk_enable(clk->parent); + + if (clk->ops && clk->ops->enable) + clk->ops->enable(clk); + } return 0; } @@ -122,11 +135,6 @@ int clk_enable(struct clk *clk) unsigned long flags; int ret; - if (!clk) - return -EINVAL; - - clk_enable(clk->parent); - spin_lock_irqsave(&clock_lock, flags); ret = __clk_enable(clk); spin_unlock_irqrestore(&clock_lock, flags); @@ -135,21 +143,23 @@ int clk_enable(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_enable); -static void clk_kref_release(struct kref *kref) -{ - /* Nothing to do */ -} - static void __clk_disable(struct clk *clk) { - int count = kref_put(&clk->kref, clk_kref_release); + if (!clk) + return; + + clk->usecount--; + + WARN_ON(clk->usecount < 0); if (clk->flags & CLK_ALWAYS_ENABLED) return; - if (!count) { /* count reaches zero, disable the clock */ + if (clk->usecount == 0) { if (likely(clk->ops && clk->ops->disable)) clk->ops->disable(clk); + + __clk_disable(clk->parent); } } @@ -157,14 +167,9 @@ void clk_disable(struct clk *clk) { unsigned long flags; - if (!clk) - return; - spin_lock_irqsave(&clock_lock, flags); __clk_disable(clk); spin_unlock_irqrestore(&clock_lock, flags); - - clk_disable(clk->parent); } EXPORT_SYMBOL_GPL(clk_disable); @@ -173,14 +178,14 @@ int clk_register(struct clk *clk) mutex_lock(&clock_list_sem); list_add(&clk->node, &clock_list); - kref_init(&clk->kref); + clk->usecount = 0; + clk->flags |= CLK_NEEDS_INIT; 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->init) - clk->ops->init(clk); if (clk->ops && clk->ops->enable) clk->ops->enable(clk); pr_debug( "Enabled."); @@ -356,7 +361,7 @@ static int show_clocks(char *buf, char **start, off_t off, p += sprintf(p, "%-12s\t: %ld.%02ldMHz\t%s\n", clk->name, rate / 1000000, (rate % 1000000) / 10000, ((clk->flags & CLK_ALWAYS_ENABLED) || - (atomic_read(&clk->kref.refcount) != 1)) ? + clk->usecount > 0) ? "enabled" : "disabled"); } -- cgit v1.2.3 From 8be5f1a68f2c14082939dd54e7037dcee2eb54f8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 19:53:55 +0900 Subject: sh: Kill off the remnants of the old timer code. Now with all of the TMU users moved over to the new TMU driver, and the old TMU driver killed off, the left-over infrastructure can go along with it. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 133dbe403341..f54769f455b1 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -26,7 +26,6 @@ #include #include #include -#include static LIST_HEAD(clock_list); static DEFINE_SPINLOCK(clock_lock); -- cgit v1.2.3