Russell King - ARM Linux <[email protected]> writes: > On Fri, Oct 16, 2009 at 12:09:17PM -0700, Kevin Hilman wrote: >> From: Sekhar Nori <[email protected]> >> >> The clk_set_parent() API is implemented to enable re-parenting >> clocks in the clock tree. >> >> This is useful in DVFS and helps by shifting clocks to an asynchronous >> domain where supported by hardware >> >> Signed-off-by: Sekhar Nori <[email protected]> >> Signed-off-by: Kevin Hilman <[email protected]> >> --- >> arch/arm/mach-davinci/clock.c | 23 +++++++++++++++++++++++ >> 1 files changed, 23 insertions(+), 0 deletions(-) >> >> diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c >> index 09e0e1c..12ceeea 100644 >> --- a/arch/arm/mach-davinci/clock.c >> +++ b/arch/arm/mach-davinci/clock.c >> @@ -141,6 +141,29 @@ int clk_set_rate(struct clk *clk, unsigned long rate) >> } >> EXPORT_SYMBOL(clk_set_rate); >> >> +int clk_set_parent(struct clk *clk, struct clk *parent) >> +{ >> + unsigned long flags; >> + >> + if (clk == NULL || IS_ERR(clk)) >> + return -EINVAL; >> + >> + mutex_lock(&clocks_mutex); >> + clk->parent = parent; >> + list_del_init(&clk->childnode); >> + list_add(&clk->childnode, &clk->parent->children); >> + mutex_unlock(&clocks_mutex); > > This is bad, and is suffering from precisely the same problem which > OMAP suffered from: > > 1. it takes no notice of whether the clk is in use. > 2. it takes no notice of whether the parent clocks are being used. > > The result is that using clk_set_parent() on a clk_enable()'d clock, > you totally destroy the usecounting of the parent clocks, leading to > the clock tree usecount becoming totally buggered up. > > Either refuse to change the parent of an already clk_enable()'d clock, > or do proper usecount fixups when changing the parent.
Russell, thanks for the review. Here's an updated version which refuses to reparent on an enabled clock. This updated one is now part of davinci-next. Kevin >From f8bd6879db197ce5e2016cffe4b8b2df811e3ee6 Mon Sep 17 00:00:00 2001 From: Sekhar Nori <[email protected]> Date: Mon, 31 Aug 2009 15:48:04 +0530 Subject: [PATCH 13/46] davinci: support re-parenting a clock in the clock framework The clk_set_parent() API is implemented to enable re-parenting clocks in the clock tree. This is useful in DVFS and helps by shifting clocks to an asynchronous domain where supported by hardware Signed-off-by: Sekhar Nori <[email protected]> Signed-off-by: Kevin Hilman <[email protected]> --- arch/arm/mach-davinci/clock.c | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 09e0e1c..e7696fc 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -141,6 +141,33 @@ int clk_set_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL(clk_set_rate); +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + unsigned long flags; + + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + /* Cannot change parent on enabled clock */ + if (WARN_ON(clk->usecount)) + return -EINVAL; + + mutex_lock(&clocks_mutex); + clk->parent = parent; + list_del_init(&clk->childnode); + list_add(&clk->childnode, &clk->parent->children); + mutex_unlock(&clocks_mutex); + + spin_lock_irqsave(&clockfw_lock, flags); + if (clk->recalc) + clk->rate = clk->recalc(clk); + propagate_rate(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + int clk_register(struct clk *clk) { if (clk == NULL || IS_ERR(clk)) -- 1.6.4.3 _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
