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 1dc896483b5..099373ae57d 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-70-g09d2 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/include/asm/clock.h | 4 +-- arch/sh/kernel/cpu/clock.c | 69 ++++++++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 34 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 2f6c9627bc1..b1f29199e4b 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -1,7 +1,6 @@ #ifndef __ASM_SH_CLOCK_H #define __ASM_SH_CLOCK_H -#include #include #include #include @@ -28,7 +27,7 @@ struct clk { struct clk *parent; struct clk_ops *ops; - struct kref kref; + int usecount; unsigned long rate; unsigned long flags; @@ -37,6 +36,7 @@ struct clk { #define CLK_ALWAYS_ENABLED (1 << 0) #define CLK_RATE_PROPAGATES (1 << 1) +#define CLK_NEEDS_INIT (1 << 2) /* Should be defined by processor-specific code */ void arch_init_clk_ops(struct clk_ops **, int type); diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 099373ae57d..133dbe40334 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-70-g09d2 From b68d8201433a91cabbcbeae48b53d8c1c426433a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 03:45:08 +0900 Subject: sh: clkfwk: Make recalc return an unsigned long. This is prep work for cleaning up some of the rate propagation bits. Trivial conversion. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 3 ++- arch/sh/kernel/cpu/clock.c | 35 ++++++++++++++++++---------------- arch/sh/kernel/cpu/sh2/clock-sh7619.c | 13 ++++++------- arch/sh/kernel/cpu/sh2a/clock-sh7201.c | 14 +++++++------- arch/sh/kernel/cpu/sh2a/clock-sh7203.c | 12 ++++++------ arch/sh/kernel/cpu/sh2a/clock-sh7206.c | 12 ++++++------ arch/sh/kernel/cpu/sh3/clock-sh3.c | 12 ++++++------ arch/sh/kernel/cpu/sh3/clock-sh7705.c | 12 ++++++------ arch/sh/kernel/cpu/sh3/clock-sh7706.c | 12 ++++++------ arch/sh/kernel/cpu/sh3/clock-sh7709.c | 12 ++++++------ arch/sh/kernel/cpu/sh3/clock-sh7710.c | 12 ++++++------ arch/sh/kernel/cpu/sh3/clock-sh7712.c | 8 ++++---- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 14 +++++++------- arch/sh/kernel/cpu/sh4/clock-sh4.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 31 +++++++++++++----------------- arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh4a/clock-sh7770.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 24 +++++++++++------------ arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 20 +++++++++---------- arch/sh/kernel/cpu/sh4a/clock-shx3.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh5/clock-sh5.c | 12 ++++++------ arch/sh/kernel/timers/timer-tmu.c | 16 +++++++--------- 23 files changed, 171 insertions(+), 175 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index b1f29199e4b..d63352b375c 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -12,7 +12,7 @@ struct clk_ops { void (*init)(struct clk *clk); void (*enable)(struct clk *clk); void (*disable)(struct clk *clk); - void (*recalc)(struct clk *clk); + unsigned long (*recalc)(struct clk *clk); int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); int (*set_parent)(struct clk *clk, struct clk *parent); long (*round_rate)(struct clk *clk, unsigned long rate); @@ -96,4 +96,5 @@ enum clk_sh_algo_id { IP_N1, }; + #endif /* __ASM_SH_CLOCK_H */ diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 133dbe40334..b022affb44c 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -75,6 +75,7 @@ static struct clk *onchip_clocks[] = { &cpu_clk, }; +/* Propagate rate to children */ static void propagate_rate(struct clk *clk) { struct clk *clkp; @@ -83,7 +84,7 @@ static void propagate_rate(struct clk *clk) if (likely(clkp->parent != clk)) continue; if (likely(clkp->ops && clkp->ops->recalc)) - clkp->ops->recalc(clkp); + clkp->rate = clkp->ops->recalc(clkp); if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) propagate_rate(clkp); } @@ -240,7 +241,7 @@ void clk_recalc_rate(struct clk *clk) unsigned long flags; spin_lock_irqsave(&clock_lock, flags); - clk->ops->recalc(clk); + clk->rate = clk->ops->recalc(clk); spin_unlock_irqrestore(&clock_lock, flags); } @@ -377,20 +378,22 @@ static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) switch (state.event) { case PM_EVENT_ON: /* Resumeing from hibernation */ - if (prev_state.event == PM_EVENT_FREEZE) { - list_for_each_entry(clkp, &clock_list, node) - if (likely(clkp->ops)) { - unsigned long rate = clkp->rate; - - if (likely(clkp->ops->set_parent)) - clkp->ops->set_parent(clkp, - clkp->parent); - if (likely(clkp->ops->set_rate)) - clkp->ops->set_rate(clkp, - rate, NO_CHANGE); - else if (likely(clkp->ops->recalc)) - clkp->ops->recalc(clkp); - } + if (prev_state.event != PM_EVENT_FREEZE) + break; + + list_for_each_entry(clkp, &clock_list, node) { + if (likely(clkp->ops)) { + unsigned long rate = clkp->rate; + + if (likely(clkp->ops->set_parent)) + clkp->ops->set_parent(clkp, + clkp->parent); + if (likely(clkp->ops->set_rate)) + clkp->ops->set_rate(clkp, + rate, NO_CHANGE); + else if (likely(clkp->ops->recalc)) + clkp->rate = clkp->ops->recalc(clkp); + } } break; case PM_EVENT_FREEZE: diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c index d2c15791799..26799139aa7 100644 --- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c @@ -38,28 +38,28 @@ static struct clk_ops sh7619_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FREQCR) & 0x0007); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7619_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { - clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; + return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; } static struct clk_ops sh7619_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { - clk->rate = clk->parent->rate; + return clk->parent->rate; } static struct clk_ops sh7619_cpu_clk_ops = { @@ -78,4 +78,3 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) if (idx < ARRAY_SIZE(sh7619_clk_ops)) *ops = sh7619_clk_ops[idx]; } - diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c index 4a5e5973233..7814c76159a 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c @@ -34,37 +34,37 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12}; static void master_clk_init(struct clk *clk) { - clk->rate = 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; + return 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; } static struct clk_ops sh7201_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FREQCR) & 0x0007); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7201_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FREQCR) & 0x0007); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7201_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7201_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c index fb781329848..f8c6933857b 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c @@ -46,29 +46,29 @@ static struct clk_ops sh7203_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FREQCR) & 0x0007); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7203_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FREQCR) & 0x0007); - clk->rate = clk->parent->rate / pfc_divisors[idx-2]; + return clk->parent->rate / pfc_divisors[idx-2]; } static struct clk_ops sh7203_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { - clk->rate = clk->parent->rate; + return clk->parent->rate; } static struct clk_ops sh7203_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c index 82d7f991ef6..c2268bdecee 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c @@ -41,29 +41,29 @@ static struct clk_ops sh7206_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FREQCR) & 0x0007); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7206_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { - clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; + return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; } static struct clk_ops sh7206_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FREQCR) & 0x0007); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7206_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh3/clock-sh3.c b/arch/sh/kernel/cpu/sh3/clock-sh3.c index c3c945958ba..27b8738f0b0 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh3.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh3.c @@ -38,36 +38,36 @@ static struct clk_ops sh3_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh3_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); - clk->rate = clk->parent->rate / stc_multipliers[idx]; + return clk->parent->rate / stc_multipliers[idx]; } static struct clk_ops sh3_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh3_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7705.c b/arch/sh/kernel/cpu/sh3/clock-sh7705.c index dfdbf3277fd..0ca8f2c3646 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7705.c @@ -39,30 +39,30 @@ static struct clk_ops sh7705_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = ctrl_inw(FRQCR) & 0x0003; - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7705_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8; - clk->rate = clk->parent->rate / stc_multipliers[idx]; + return clk->parent->rate / stc_multipliers[idx]; } static struct clk_ops sh7705_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4; - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7705_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7706.c b/arch/sh/kernel/cpu/sh3/clock-sh7706.c index 0cf96f9833b..4bf7887d310 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7706.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7706.c @@ -34,36 +34,36 @@ static struct clk_ops sh7706_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7706_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); - clk->rate = clk->parent->rate / stc_multipliers[idx]; + return clk->parent->rate / stc_multipliers[idx]; } static struct clk_ops sh7706_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7706_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c index b791a29fdb6..fa30b601773 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c @@ -41,12 +41,12 @@ static struct clk_ops sh7709_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7709_module_clk_ops = { @@ -56,25 +56,25 @@ static struct clk_ops sh7709_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = (frqcr & 0x0080) ? ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1; - clk->rate = clk->parent->rate * stc_multipliers[idx]; + return clk->parent->rate * stc_multipliers[idx]; } static struct clk_ops sh7709_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7709_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7710.c b/arch/sh/kernel/cpu/sh3/clock-sh7710.c index 4744c50ec44..030a58ba18a 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7710.c @@ -33,30 +33,30 @@ static struct clk_ops sh7710_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FRQCR) & 0x0007); - clk->rate = clk->parent->rate / md_table[idx]; + return clk->parent->rate / md_table[idx]; } static struct clk_ops sh7710_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8; - clk->rate = clk->parent->rate / md_table[idx]; + return clk->parent->rate / md_table[idx]; } static struct clk_ops sh7710_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4; - clk->rate = clk->parent->rate / md_table[idx]; + return clk->parent->rate / md_table[idx]; } static struct clk_ops sh7710_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7712.c b/arch/sh/kernel/cpu/sh3/clock-sh7712.c index 54f54df51ef..6428ee6c77e 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7712.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7712.c @@ -33,24 +33,24 @@ static struct clk_ops sh7712_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = frqcr & 0x0007; - clk->rate = clk->parent->rate / divisors[idx]; + return clk->parent->rate / divisors[idx]; } static struct clk_ops sh7712_module_clk_ops = { .recalc = module_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); int idx = (frqcr & 0x0030) >> 4; - clk->rate = clk->parent->rate / divisors[idx]; + return clk->parent->rate / divisors[idx]; } static struct clk_ops sh7712_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index a33429463e9..628d50ea6f6 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -21,10 +21,10 @@ static int frqcr3_divisors[] = { 1, 2, 3, 4, 6, 8, 16 }; static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 }; -static void emi_clk_recalc(struct clk *clk) +static unsigned long emi_clk_recalc(struct clk *clk) { int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007; - clk->rate = clk->parent->rate / frqcr3_divisors[idx]; + return clk->parent->rate / frqcr3_divisors[idx]; } static inline int frqcr3_lookup(struct clk *clk, unsigned long rate) @@ -50,10 +50,10 @@ static struct clk sh4202_emi_clk = { .ops = &sh4202_emi_clk_ops, }; -static void femi_clk_recalc(struct clk *clk) +static unsigned long femi_clk_recalc(struct clk *clk) { int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007; - clk->rate = clk->parent->rate / frqcr3_divisors[idx]; + return clk->parent->rate / frqcr3_divisors[idx]; } static struct clk_ops sh4202_femi_clk_ops = { @@ -90,10 +90,10 @@ static void shoc_clk_init(struct clk *clk) WARN_ON(i == ARRAY_SIZE(frqcr3_divisors)); /* Undefined clock */ } -static void shoc_clk_recalc(struct clk *clk) +static unsigned long shoc_clk_recalc(struct clk *clk) { int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007; - clk->rate = clk->parent->rate / frqcr3_divisors[idx]; + return clk->parent->rate / frqcr3_divisors[idx]; } static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) @@ -127,7 +127,7 @@ static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) frqcr3 |= tmp << 6; ctrl_outl(frqcr3, CPG2_FRQCR3); - clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; + return clk->parent->rate / frqcr3_divisors[tmp]; return 0; } diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4.c b/arch/sh/kernel/cpu/sh4/clock-sh4.c index dca9f87a12d..73294d9cd04 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4.c @@ -35,30 +35,30 @@ static struct clk_ops sh4_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FRQCR) & 0x0007); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh4_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FRQCR) >> 3) & 0x0007; - clk->rate = clk->parent->rate / bfc_divisors[idx]; + return clk->parent->rate / bfc_divisors[idx]; } static struct clk_ops sh4_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(FRQCR) >> 6) & 0x0007; - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh4_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 1ccdfc561fe..5b1427f1ed4 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -151,11 +151,11 @@ static int divisors2[] = { 4, 1, 8, 12, 16, 24, 32, 1, 48, 64, 72, 96, 1, 144 }; static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 }; #endif -static void master_clk_recalc(struct clk *clk) +static unsigned long master_clk_recalc(struct clk *clk) { unsigned frqcr = ctrl_inl(FRQCR); - clk->rate = CONFIG_SH_PCLK_FREQ * STCPLL(frqcr); + return CONFIG_SH_PCLK_FREQ * STCPLL(frqcr); } static void master_clk_init(struct clk *clk) @@ -166,12 +166,11 @@ static void master_clk_init(struct clk *clk) master_clk_recalc(clk); } - -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { unsigned long frqcr = ctrl_inl(FRQCR); - clk->rate = clk->parent->rate / STCPLL(frqcr); + return clk->parent->rate / STCPLL(frqcr); } #if defined(CONFIG_CPU_SUBTYPE_SH7724) @@ -283,14 +282,14 @@ static int sh7722_find_div_index(unsigned long parent_rate, unsigned rate) return index; } -static void sh7722_frqcr_recalc(struct clk *clk) +static unsigned long sh7722_frqcr_recalc(struct clk *clk) { struct frqcr_context ctx = sh7722_get_clk_context(clk->name); unsigned long frqcr = ctrl_inl(FRQCR); int index; index = (frqcr >> ctx.shift) & ctx.mask; - clk->rate = clk->parent->rate * 2 / divisors2[index]; + return clk->parent->rate * 2 / divisors2[index]; } static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate, @@ -439,11 +438,8 @@ static struct clk_ops sh7722_frqcr_clk_ops = { /* * clock ops methods for SIU A/B and IrDA clock - * */ - #ifndef CONFIG_CPU_SUBTYPE_SH7343 - static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id) { unsigned long r; @@ -458,12 +454,12 @@ static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id) return 0; } -static void sh7722_siu_recalc(struct clk *clk) +static unsigned long sh7722_siu_recalc(struct clk *clk) { unsigned long r; r = ctrl_inl(clk->arch_flags); - clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF]; + return clk->parent->rate * 2 / divisors2[r & 0xF]; } static int sh7722_siu_start_stop(struct clk *clk, int enable) @@ -525,12 +521,12 @@ static int sh7722_video_set_rate(struct clk *clk, unsigned long rate, return 0; } -static void sh7722_video_recalc(struct clk *clk) +static unsigned long sh7722_video_recalc(struct clk *clk) { unsigned long r; r = ctrl_inl(VCLKCR); - clk->rate = clk->parent->rate / ((r & 0x3F) + 1); + return clk->parent->rate / ((r & 0x3F) + 1); } static struct clk_ops sh7722_video_clk_ops = { @@ -627,7 +623,7 @@ static int sh7722_mstpcr_start_stop(struct clk *clk, int enable) break; default: return -EINVAL; - } + } r = ctrl_inl(reg); @@ -650,10 +646,9 @@ static void sh7722_mstpcr_disable(struct clk *clk) sh7722_mstpcr_start_stop(clk, 0); } -static void sh7722_mstpcr_recalc(struct clk *clk) +static unsigned long sh7722_mstpcr_recalc(struct clk *clk) { - if (clk->parent) - clk->rate = clk->parent->rate; + return clk->parent->rate; } static struct clk_ops sh7722_mstpcr_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index 3177d0d1e06..26630fb190c 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c @@ -29,29 +29,29 @@ static struct clk_ops sh7763_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> 4) & 0x07); - clk->rate = clk->parent->rate / p0fc_divisors[idx]; + return clk->parent->rate / p0fc_divisors[idx]; } static struct clk_ops sh7763_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> 16) & 0x07); - clk->rate = clk->parent->rate / bfc_divisors[idx]; + return clk->parent->rate / bfc_divisors[idx]; } static struct clk_ops sh7763_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { - clk->rate = clk->parent->rate; + return clk->parent->rate; } static struct clk_ops sh7763_cpu_clk_ops = { @@ -71,10 +71,10 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) *ops = sh7763_clk_ops[idx]; } -static void shyway_clk_recalc(struct clk *clk) +static unsigned long shyway_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> 20) & 0x07); - clk->rate = clk->parent->rate / cfc_divisors[idx]; + return clk->parent->rate / cfc_divisors[idx]; } static struct clk_ops sh7763_shyway_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c index 8e236062c72..e0b89676920 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c @@ -28,30 +28,30 @@ static struct clk_ops sh7770_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7770_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = (ctrl_inl(FRQCR) & 0x000f); - clk->rate = clk->parent->rate / bfc_divisors[idx]; + return clk->parent->rate / bfc_divisors[idx]; } static struct clk_ops sh7770_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7770_cpu_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index 01f3da619d3..ba8dacc4ba2 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -29,30 +29,30 @@ static struct clk_ops sh7780_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inl(FRQCR) & 0x0003); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7780_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); - clk->rate = clk->parent->rate / bfc_divisors[idx]; + return clk->parent->rate / bfc_divisors[idx]; } static struct clk_ops sh7780_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7780_cpu_clk_ops = { @@ -72,10 +72,10 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) *ops = sh7780_clk_ops[idx]; } -static void shyway_clk_recalc(struct clk *clk) +static unsigned long shyway_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); - clk->rate = clk->parent->rate / cfc_divisors[idx]; + return clk->parent->rate / cfc_divisors[idx]; } static struct clk_ops sh7780_shyway_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 27fa81bef6a..52691eaeb9b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -33,30 +33,30 @@ static struct clk_ops sh7785_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inl(FRQMR1) & 0x000f); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7785_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f); - clk->rate = clk->parent->rate / bfc_divisors[idx]; + return clk->parent->rate / bfc_divisors[idx]; } static struct clk_ops sh7785_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7785_cpu_clk_ops = { @@ -76,10 +76,10 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) *ops = sh7785_clk_ops[idx]; } -static void shyway_clk_recalc(struct clk *clk) +static unsigned long shyway_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003); - clk->rate = clk->parent->rate / sfc_divisors[idx]; + return clk->parent->rate / sfc_divisors[idx]; } static struct clk_ops sh7785_shyway_clk_ops = { @@ -92,10 +92,10 @@ static struct clk sh7785_shyway_clk = { .ops = &sh7785_shyway_clk_ops, }; -static void ddr_clk_recalc(struct clk *clk) +static unsigned long ddr_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003); - clk->rate = clk->parent->rate / mfc_divisors[idx]; + return clk->parent->rate / mfc_divisors[idx]; } static struct clk_ops sh7785_ddr_clk_ops = { @@ -108,10 +108,10 @@ static struct clk sh7785_ddr_clk = { .ops = &sh7785_ddr_clk_ops, }; -static void ram_clk_recalc(struct clk *clk) +static unsigned long ram_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 24) & 0x0003); - clk->rate = clk->parent->rate / ufc_divisors[idx]; + return clk->parent->rate / ufc_divisors[idx]; } static struct clk_ops sh7785_ram_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index f84a9c13447..2e00ff436c6 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -36,30 +36,30 @@ static struct clk_ops sh7786_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inl(FRQMR1) & 0x000f); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops sh7786_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f); - clk->rate = clk->parent->rate / bfc_divisors[idx]; + return clk->parent->rate / bfc_divisors[idx]; } static struct clk_ops sh7786_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops sh7786_cpu_clk_ops = { @@ -79,10 +79,10 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) *ops = sh7786_clk_ops[idx]; } -static void shyway_clk_recalc(struct clk *clk) +static unsigned long shyway_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003); - clk->rate = clk->parent->rate / sfc_divisors[idx]; + return clk->parent->rate / sfc_divisors[idx]; } static struct clk_ops sh7786_shyway_clk_ops = { @@ -95,10 +95,10 @@ static struct clk sh7786_shyway_clk = { .ops = &sh7786_shyway_clk_ops, }; -static void ddr_clk_recalc(struct clk *clk) +static unsigned long ddr_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003); - clk->rate = clk->parent->rate / mfc_divisors[idx]; + return clk->parent->rate / mfc_divisors[idx]; } static struct clk_ops sh7786_ddr_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index c630b29e06a..770934e6828 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -40,30 +40,30 @@ static struct clk_ops shx3_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK); - clk->rate = clk->parent->rate / pfc_divisors[idx]; + return clk->parent->rate / pfc_divisors[idx]; } static struct clk_ops shx3_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK); - clk->rate = clk->parent->rate / bfc_divisors[idx]; + return clk->parent->rate / bfc_divisors[idx]; } static struct clk_ops shx3_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK); - clk->rate = clk->parent->rate / ifc_divisors[idx]; + return clk->parent->rate / ifc_divisors[idx]; } static struct clk_ops shx3_cpu_clk_ops = { @@ -83,10 +83,10 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) *ops = shx3_clk_ops[idx]; } -static void shyway_clk_recalc(struct clk *clk) +static unsigned long shyway_clk_recalc(struct clk *clk) { int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK); - clk->rate = clk->parent->rate / cfc_divisors[idx]; + return clk->parent->rate / cfc_divisors[idx]; } static struct clk_ops shx3_shyway_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh5/clock-sh5.c b/arch/sh/kernel/cpu/sh5/clock-sh5.c index 5486324880e..7f864ebc51d 100644 --- a/arch/sh/kernel/cpu/sh5/clock-sh5.c +++ b/arch/sh/kernel/cpu/sh5/clock-sh5.c @@ -32,30 +32,30 @@ static struct clk_ops sh5_master_clk_ops = { .init = master_clk_init, }; -static void module_clk_recalc(struct clk *clk) +static unsigned long module_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(cprc_base) >> 12) & 0x0007; - clk->rate = clk->parent->rate / ifc_table[idx]; + return clk->parent->rate / ifc_table[idx]; } static struct clk_ops sh5_module_clk_ops = { .recalc = module_clk_recalc, }; -static void bus_clk_recalc(struct clk *clk) +static unsigned long bus_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(cprc_base) >> 3) & 0x0007; - clk->rate = clk->parent->rate / ifc_table[idx]; + return clk->parent->rate / ifc_table[idx]; } static struct clk_ops sh5_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static void cpu_clk_recalc(struct clk *clk) +static unsigned long cpu_clk_recalc(struct clk *clk) { int idx = (ctrl_inw(cprc_base) & 0x0007); - clk->rate = clk->parent->rate / ifc_table[idx]; + return clk->parent->rate / ifc_table[idx]; } static struct clk_ops sh5_cpu_clk_ops = { diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index fe8d8930ccb..a693dcdbe13 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -172,22 +172,19 @@ static void __init tmu_clk_init(struct clk *clk) clk->rate = clk_get_rate(clk->parent) / (4 << (divisor << 1)); } -static void tmu_clk_recalc(struct clk *clk) +static unsigned long tmu_clk_recalc(struct clk *clk) { int tmu_num = clk->name[3]-'0'; - unsigned long prev_rate = clk_get_rate(clk); + unsigned long new_rate; unsigned long flags; u8 divisor = ctrl_inw(TMU0_TCR+tmu_num*0xC) & 0x7; - clk->rate = clk_get_rate(clk->parent) / (4 << (divisor << 1)); - if(prev_rate==clk_get_rate(clk)) - return; - - if(tmu_num) - return; /* No more work on TMU1 */ + new_rate = clk_get_rate(clk->parent) / (4 << (divisor << 1)); + if (clk->rate == new_rate || tmu_num) + return clk->rate; /* No more work on TMU1 */ local_irq_save(flags); - tmus_are_scaled = (prev_rate > clk->rate); + tmus_are_scaled = (clk->rate > new_rate); _tmu_stop(TMU0); @@ -210,6 +207,7 @@ static void tmu_clk_recalc(struct clk *clk) _tmu_start(TMU0); local_irq_restore(flags); + return new_rate; } static struct clk_ops tmu_clk_ops = { -- cgit v1.2.3-70-g09d2 From a02cb230bb4fca04f091746c593de720a0e3a94a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 03:50:44 +0900 Subject: sh: clkfwk: Add a followparent_recalc() helper. This adds a followparent_recalc() helper for clocks that just follow the parent's rate. Switch over the few CPUs that use this scheme for some of their clocks. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 2 +- arch/sh/kernel/cpu/clock.c | 6 ++++++ arch/sh/kernel/cpu/sh2/clock-sh7619.c | 7 +------ arch/sh/kernel/cpu/sh2a/clock-sh7203.c | 7 +------ arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 7 +------ arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 7 +------ 6 files changed, 11 insertions(+), 25 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index d63352b375c..241f1c1d9ce 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -44,7 +44,7 @@ int __init arch_clk_init(void); /* arch/sh/kernel/cpu/clock.c */ int clk_init(void); - +unsigned long followparent_recalc(struct clk *clk); void clk_recalc_rate(struct clk *); int clk_register(struct clk *); diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index b022affb44c..17f6c078e85 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -90,6 +90,12 @@ static void propagate_rate(struct clk *clk) } } +/* Used for clocks that always have same value as the parent clock */ +unsigned long followparent_recalc(struct clk *clk) +{ + return clk->parent->rate; +} + static void __clk_init(struct clk *clk) { /* diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c index 26799139aa7..4fe863170e3 100644 --- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c @@ -57,13 +57,8 @@ static struct clk_ops sh7619_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static unsigned long cpu_clk_recalc(struct clk *clk) -{ - return clk->parent->rate; -} - static struct clk_ops sh7619_cpu_clk_ops = { - .recalc = cpu_clk_recalc, + .recalc = followparent_recalc, }; static struct clk_ops *sh7619_clk_ops[] = { diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c index f8c6933857b..94098696510 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c @@ -66,13 +66,8 @@ static struct clk_ops sh7203_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static unsigned long cpu_clk_recalc(struct clk *clk) -{ - return clk->parent->rate; -} - static struct clk_ops sh7203_cpu_clk_ops = { - .recalc = cpu_clk_recalc, + .recalc = followparent_recalc, }; static struct clk_ops *sh7203_clk_ops[] = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 5b1427f1ed4..4bdae84aa6b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -646,15 +646,10 @@ static void sh7722_mstpcr_disable(struct clk *clk) sh7722_mstpcr_start_stop(clk, 0); } -static unsigned long sh7722_mstpcr_recalc(struct clk *clk) -{ - return clk->parent->rate; -} - static struct clk_ops sh7722_mstpcr_clk_ops = { .enable = sh7722_mstpcr_enable, .disable = sh7722_mstpcr_disable, - .recalc = sh7722_mstpcr_recalc, + .recalc = followparent_recalc, }; #define MSTPCR(_name, _parent, regnr, bitnr) \ diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index 26630fb190c..db51cffc5d5 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c @@ -49,13 +49,8 @@ static struct clk_ops sh7763_bus_clk_ops = { .recalc = bus_clk_recalc, }; -static unsigned long cpu_clk_recalc(struct clk *clk) -{ - return clk->parent->rate; -} - static struct clk_ops sh7763_cpu_clk_ops = { - .recalc = cpu_clk_recalc, + .recalc = followparent_recalc, }; static struct clk_ops *sh7763_clk_ops[] = { -- cgit v1.2.3-70-g09d2 From b1f6cfe48c3cb1dfa77db3d2f42f765febaef9bc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 04:27:43 +0900 Subject: sh: clkfwk: refactor rate propagation. This resyncs the rate propagation strategy with the scheme used by the OMAP clock framework. Child clocks are tracked on a list under each parent and propagation happens there specifically rather than constantly iterating over the global clock list. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 9 ++- arch/sh/kernel/cpu/clock.c | 120 +++++++++++++++++++++------------ arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 8 +-- 3 files changed, 85 insertions(+), 52 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 241f1c1d9ce..5dc8b73a2bd 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -27,6 +27,9 @@ struct clk { struct clk *parent; struct clk_ops *ops; + struct list_head children; + struct list_head sibling; /* node for children */ + int usecount; unsigned long rate; @@ -35,7 +38,6 @@ struct clk { }; #define CLK_ALWAYS_ENABLED (1 << 0) -#define CLK_RATE_PROPAGATES (1 << 1) #define CLK_NEEDS_INIT (1 << 2) /* Should be defined by processor-specific code */ @@ -44,9 +46,10 @@ int __init arch_clk_init(void); /* arch/sh/kernel/cpu/clock.c */ int clk_init(void); -unsigned long followparent_recalc(struct clk *clk); +unsigned long followparent_recalc(struct clk *); +void recalculate_root_clocks(void); +void propagate_rate(struct clk *); void clk_recalc_rate(struct clk *); - int clk_register(struct clk *); void clk_unregister(struct clk *); diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 17f6c078e85..0a06df8cde2 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -1,11 +1,11 @@ /* * arch/sh/kernel/cpu/clock.c - SuperH clock framework * - * Copyright (C) 2005, 2006, 2007 Paul Mundt + * Copyright (C) 2005 - 2009 Paul Mundt * * This clock framework is derived from the OMAP version by: * - * Copyright (C) 2004 - 2005 Nokia Corporation + * Copyright (C) 2004 - 2008 Nokia Corporation * Written by Tuukka Tikkanen * * Modified for omap shared clock framework by Tony Lindgren @@ -43,20 +43,20 @@ static DEFINE_MUTEX(clock_list_sem); */ static struct clk master_clk = { .name = "master_clk", - .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, + .flags = CLK_ALWAYS_ENABLED, .rate = CONFIG_SH_PCLK_FREQ, }; static struct clk module_clk = { .name = "module_clk", .parent = &master_clk, - .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, + .flags = CLK_ALWAYS_ENABLED, }; static struct clk bus_clk = { .name = "bus_clk", .parent = &master_clk, - .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, + .flags = CLK_ALWAYS_ENABLED, }; static struct clk cpu_clk = { @@ -75,27 +75,24 @@ static struct clk *onchip_clocks[] = { &cpu_clk, }; +/* Used for clocks that always have same value as the parent clock */ +unsigned long followparent_recalc(struct clk *clk) +{ + return clk->parent->rate; +} + /* Propagate rate to children */ -static void propagate_rate(struct clk *clk) +void propagate_rate(struct clk *tclk) { struct clk *clkp; - list_for_each_entry(clkp, &clock_list, node) { - if (likely(clkp->parent != clk)) - continue; - if (likely(clkp->ops && clkp->ops->recalc)) + list_for_each_entry(clkp, &tclk->children, sibling) { + if (clkp->ops->recalc) clkp->rate = clkp->ops->recalc(clkp); - if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) - propagate_rate(clkp); + propagate_rate(clkp); } } -/* Used for clocks that always have same value as the parent clock */ -unsigned long followparent_recalc(struct clk *clk) -{ - return clk->parent->rate; -} - static void __clk_init(struct clk *clk) { /* @@ -180,10 +177,46 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_disable); +static LIST_HEAD(root_clks); + +/** + * recalculate_root_clocks - recalculate and propagate all root clocks + * + * Recalculates all root clocks (clocks with no parent), which if the + * clock's .recalc is set correctly, should also propagate their rates. + * Called at init. + */ +void recalculate_root_clocks(void) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &root_clks, sibling) { + if (clkp->ops->recalc) + clkp->rate = clkp->ops->recalc(clkp); + propagate_rate(clkp); + } +} + int clk_register(struct clk *clk) { + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + /* + * trap out already registered clocks + */ + if (clk->node.next || clk->node.prev) + return 0; + mutex_lock(&clock_list_sem); + INIT_LIST_HEAD(&clk->children); + + if (clk->parent) + list_add(&clk->sibling, &clk->parent->children); + else + list_add(&clk->sibling, &root_clks); + list_add(&clk->node, &clock_list); clk->usecount = 0; clk->flags |= CLK_NEEDS_INIT; @@ -205,6 +238,7 @@ EXPORT_SYMBOL_GPL(clk_register); void clk_unregister(struct clk *clk) { mutex_lock(&clock_list_sem); + list_del(&clk->sibling); list_del(&clk->node); mutex_unlock(&clock_list_sem); } @@ -231,50 +265,53 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) spin_lock_irqsave(&clock_lock, flags); ret = clk->ops->set_rate(clk, rate, algo_id); + if (ret == 0) { + if (clk->ops->recalc) + clk->rate = clk->ops->recalc(clk); + propagate_rate(clk); + } spin_unlock_irqrestore(&clock_lock, flags); } - if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) - propagate_rate(clk); - return ret; } EXPORT_SYMBOL_GPL(clk_set_rate_ex); void clk_recalc_rate(struct clk *clk) { - if (likely(clk->ops && clk->ops->recalc)) { - unsigned long flags; + unsigned long flags; - spin_lock_irqsave(&clock_lock, flags); - clk->rate = clk->ops->recalc(clk); - spin_unlock_irqrestore(&clock_lock, flags); - } + if (!clk->ops->recalc) + return; - if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) - propagate_rate(clk); + spin_lock_irqsave(&clock_lock, flags); + clk->rate = clk->ops->recalc(clk); + propagate_rate(clk); + spin_unlock_irqrestore(&clock_lock, flags); } EXPORT_SYMBOL_GPL(clk_recalc_rate); int clk_set_parent(struct clk *clk, struct clk *parent) { + unsigned long flags; int ret = -EINVAL; - struct clk *old; if (!parent || !clk) return ret; - old = clk->parent; - if (likely(clk->ops && clk->ops->set_parent)) { - unsigned long flags; - spin_lock_irqsave(&clock_lock, flags); - ret = clk->ops->set_parent(clk, parent); - spin_unlock_irqrestore(&clock_lock, flags); - clk->parent = (ret ? old : parent); - } + spin_lock_irqsave(&clock_lock, flags); + if (clk->usecount == 0) { + if (clk->ops->set_parent) + ret = clk->ops->set_parent(clk, parent); + if (ret == 0) { + if (clk->ops->recalc) + clk->rate = clk->ops->recalc(clk); + propagate_rate(clk); + } + } else + ret = -EBUSY; + spin_unlock_irqrestore(&clock_lock, flags); - if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) - propagate_rate(clk); return ret; } EXPORT_SYMBOL_GPL(clk_set_parent); @@ -457,8 +494,7 @@ int __init clk_init(void) ret |= arch_clk_init(); /* Kick the child clocks.. */ - propagate_rate(&master_clk); - propagate_rate(&bus_clk); + recalculate_root_clocks(); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 4bdae84aa6b..8e53829ca07 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -161,9 +161,7 @@ static unsigned long master_clk_recalc(struct clk *clk) static void master_clk_init(struct clk *clk) { clk->parent = NULL; - clk->flags |= CLK_RATE_PROPAGATES; - clk->rate = CONFIG_SH_PCLK_FREQ; - master_clk_recalc(clk); + clk->rate = master_clk_recalc(clk); } static unsigned long module_clk_recalc(struct clk *clk) @@ -541,19 +539,16 @@ static struct clk_ops sh7722_video_clk_ops = { static struct clk sh7722_umem_clock = { .name = "umem_clk", .ops = &sh7722_frqcr_clk_ops, - .flags = CLK_RATE_PROPAGATES, }; static struct clk sh7722_sh_clock = { .name = "sh_clk", .ops = &sh7722_frqcr_clk_ops, - .flags = CLK_RATE_PROPAGATES, }; static struct clk sh7722_peripheral_clock = { .name = "peripheral_clk", .ops = &sh7722_frqcr_clk_ops, - .flags = CLK_RATE_PROPAGATES, }; static struct clk sh7722_sdram_clock = { @@ -564,7 +559,6 @@ static struct clk sh7722_sdram_clock = { static struct clk sh7722_r_clock = { .name = "r_clk", .rate = 32768, - .flags = CLK_RATE_PROPAGATES, }; #if !defined(CONFIG_CPU_SUBTYPE_SH7343) &&\ -- cgit v1.2.3-70-g09d2 From 4ff29ff8e8723a41e7defd8bc78a7b16cbf940a2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 05:14:53 +0900 Subject: 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 --- arch/sh/include/asm/clock.h | 3 +- arch/sh/kernel/cpu/clock.c | 94 ++++++++++++---------------------- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 6 +-- arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 6 +-- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 4 +- arch/sh/kernel/cpu/sh4a/clock-shx3.c | 2 +- 8 files changed, 44 insertions(+), 75 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 5dc8b73a2bd..246f9ebbed2 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -37,8 +37,7 @@ struct clk { unsigned long arch_flags; }; -#define CLK_ALWAYS_ENABLED (1 << 0) -#define CLK_NEEDS_INIT (1 << 2) +#define CLK_ENABLE_ON_INIT (1 << 0) /* Should be defined by processor-specific code */ void arch_init_clk_ops(struct clk_ops **, int type); diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 0a06df8cde2..c683be5ba8b 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -43,26 +43,26 @@ static DEFINE_MUTEX(clock_list_sem); */ 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 @@ void propagate_rate(struct clk *tclk) } } -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 @@ int clk_enable(struct clk *clk) 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 @@ EXPORT_SYMBOL_GPL(clk_enable); 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 @@ 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); @@ -211,6 +179,7 @@ int clk_register(struct clk *clk) 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 @@ int clk_register(struct clk *clk) 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 @@ void clk_unregister(struct clk *clk) } 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 @@ 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) || - clk->usecount > 0) ? - "enabled" : "disabled"); + (clk->usecount > 0) ? "enabled" : "disabled"); } return p - buf; @@ -496,6 +463,9 @@ int __init clk_init(void) /* Kick the child clocks.. */ recalculate_root_clocks(); + /* Enable the necessary init clocks */ + clk_enable_init_clocks(); + return ret; } diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 628d50ea6f6..0caca9f99fe 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -46,7 +46,7 @@ static struct clk_ops sh4202_emi_clk_ops = { static struct clk sh4202_emi_clk = { .name = "emi_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh4202_emi_clk_ops, }; @@ -62,7 +62,7 @@ static struct clk_ops sh4202_femi_clk_ops = { static struct clk sh4202_femi_clk = { .name = "femi_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh4202_femi_clk_ops, }; @@ -140,7 +140,7 @@ static struct clk_ops sh4202_shoc_clk_ops = { static struct clk sh4202_shoc_clk = { .name = "shoc_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh4202_shoc_clk_ops, }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index db51cffc5d5..21bd70f9ee4 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c @@ -78,7 +78,7 @@ static struct clk_ops sh7763_shyway_clk_ops = { static struct clk sh7763_shyway_clk = { .name = "shyway_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh7763_shyway_clk_ops, }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index ba8dacc4ba2..4c11f8917e4 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -84,7 +84,7 @@ static struct clk_ops sh7780_shyway_clk_ops = { static struct clk sh7780_shyway_clk = { .name = "shyway_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh7780_shyway_clk_ops, }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 52691eaeb9b..edd432894bd 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -88,7 +88,7 @@ static struct clk_ops sh7785_shyway_clk_ops = { static struct clk sh7785_shyway_clk = { .name = "shyway_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh7785_shyway_clk_ops, }; @@ -104,7 +104,7 @@ static struct clk_ops sh7785_ddr_clk_ops = { static struct clk sh7785_ddr_clk = { .name = "ddr_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh7785_ddr_clk_ops, }; @@ -120,7 +120,7 @@ static struct clk_ops sh7785_ram_clk_ops = { static struct clk sh7785_ram_clk = { .name = "ram_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh7785_ram_clk_ops, }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 2e00ff436c6..2825494f85d 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -91,7 +91,7 @@ static struct clk_ops sh7786_shyway_clk_ops = { static struct clk sh7786_shyway_clk = { .name = "shyway_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh7786_shyway_clk_ops, }; @@ -107,7 +107,7 @@ static struct clk_ops sh7786_ddr_clk_ops = { static struct clk sh7786_ddr_clk = { .name = "ddr_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &sh7786_ddr_clk_ops, }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index 770934e6828..6e5c864cf40 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -95,7 +95,7 @@ static struct clk_ops shx3_shyway_clk_ops = { static struct clk shx3_shyway_clk = { .name = "shyway_clk", - .flags = CLK_ALWAYS_ENABLED, + .flags = CLK_ENABLE_ON_INIT, .ops = &shx3_shyway_clk_ops, }; -- cgit v1.2.3-70-g09d2 From ae891a4264c91246c0b4c22be68b9838747ae48d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 05:30:10 +0900 Subject: sh: clkfwk: Fix up the clk_enable() error path. There are a couple of instances where a clk_enable() can fail, which the SH-Mobile code presently handles, but doesn't get reported all the way back up. This fixes up the return type so the errors make it all the way down to the drivers. Additionally, we now also error out properly if the parent enable fails. Prep work for aggressively turning off unused clocks on boot. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 2 +- arch/sh/kernel/cpu/clock.c | 71 ++++++++++++++++++++++------------ arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 11 +++--- 3 files changed, 53 insertions(+), 31 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index e9fced9bd8f..5de72eef972 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -10,7 +10,7 @@ struct clk; struct clk_ops { void (*init)(struct clk *clk); - void (*enable)(struct clk *clk); + int (*enable)(struct clk *clk); void (*disable)(struct clk *clk); unsigned long (*recalc)(struct clk *clk); int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index c683be5ba8b..e027fe5898d 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -93,57 +93,78 @@ void propagate_rate(struct clk *tclk) } } -static int __clk_enable(struct clk *clk) +static void __clk_disable(struct clk *clk) { - if (clk->usecount++ == 0) { - if (clk->parent) - __clk_enable(clk->parent); - - if (clk->ops && clk->ops->enable) - clk->ops->enable(clk); + if (clk->usecount == 0) { + printk(KERN_ERR "Trying disable clock %s with 0 usecount\n", + clk->name); + WARN_ON(1); + return; } - return 0; + if (!(--clk->usecount)) { + if (likely(clk->ops && clk->ops->disable)) + clk->ops->disable(clk); + if (likely(clk->parent)) + __clk_disable(clk->parent); + } } -int clk_enable(struct clk *clk) +void clk_disable(struct clk *clk) { unsigned long flags; - int ret; if (!clk) - return -EINVAL; + return; spin_lock_irqsave(&clock_lock, flags); - ret = __clk_enable(clk); + __clk_disable(clk); spin_unlock_irqrestore(&clock_lock, flags); - - return ret; } -EXPORT_SYMBOL_GPL(clk_enable); +EXPORT_SYMBOL_GPL(clk_disable); -static void __clk_disable(struct clk *clk) +static int __clk_enable(struct clk *clk) { - if (clk->usecount > 0 && !(--clk->usecount)) { - if (likely(clk->ops && clk->ops->disable)) - clk->ops->disable(clk); - if (likely(clk->parent)) - __clk_disable(clk->parent); + int ret = 0; + + if (clk->usecount++ == 0) { + if (clk->parent) { + ret = __clk_enable(clk->parent); + if (unlikely(ret)) + goto err; + } + + if (clk->ops && clk->ops->enable) { + ret = clk->ops->enable(clk); + if (ret) { + if (clk->parent) + __clk_disable(clk->parent); + goto err; + } + } } + + return ret; +err: + clk->usecount--; + return ret; } -void clk_disable(struct clk *clk) +int clk_enable(struct clk *clk) { unsigned long flags; + int ret; if (!clk) - return; + return -EINVAL; spin_lock_irqsave(&clock_lock, flags); - __clk_disable(clk); + ret = __clk_enable(clk); spin_unlock_irqrestore(&clock_lock, flags); + + return ret; } -EXPORT_SYMBOL_GPL(clk_disable); +EXPORT_SYMBOL_GPL(clk_enable); static LIST_HEAD(root_clks); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index f777d00d4af..1c41db41de7 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -472,9 +472,9 @@ static int sh7722_siu_start_stop(struct clk *clk, int enable) return 0; } -static void sh7722_siu_enable(struct clk *clk) +static int sh7722_siu_enable(struct clk *clk) { - sh7722_siu_start_stop(clk, 1); + return sh7722_siu_start_stop(clk, 1); } static void sh7722_siu_disable(struct clk *clk) @@ -491,12 +491,13 @@ static struct clk_ops sh7722_siu_clk_ops = { #endif /* CONFIG_CPU_SUBTYPE_SH7343 */ -static void sh7722_video_enable(struct clk *clk) +static int sh7722_video_enable(struct clk *clk) { unsigned long r; r = ctrl_inl(VCLKCR); ctrl_outl( r & ~(1<<8), VCLKCR); + return 0; } static void sh7722_video_disable(struct clk *clk) @@ -630,9 +631,9 @@ static int sh7722_mstpcr_start_stop(struct clk *clk, int enable) return 0; } -static void sh7722_mstpcr_enable(struct clk *clk) +static int sh7722_mstpcr_enable(struct clk *clk) { - sh7722_mstpcr_start_stop(clk, 1); + return sh7722_mstpcr_start_stop(clk, 1); } static void sh7722_mstpcr_disable(struct clk *clk) -- cgit v1.2.3-70-g09d2 From aa87aa343f2cd236b5eccd643abd4df918ed5c4f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 05:51:05 +0900 Subject: sh: clkfwk: Improve the generic clk_set_parent() implementation. This causes the generic clk_set_parent() implementation to be a bit more intelligent. A clk_reparent() is added to move the clock over to the new parent's sibling list, which then allows the generic rate propagation code to succeed. This also becomes a nop if the new and old parents are unchanged. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 1 + arch/sh/kernel/cpu/clock.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 5de72eef972..fdb915608db 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -48,6 +48,7 @@ int clk_init(void); unsigned long followparent_recalc(struct clk *); void recalculate_root_clocks(void); void propagate_rate(struct clk *); +int clk_reparent(struct clk *child, struct clk *parent); void clk_recalc_rate(struct clk *); int clk_register(struct clk *); void clk_unregister(struct clk *); diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index e027fe5898d..e3d1de8a46f 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -81,6 +81,19 @@ unsigned long followparent_recalc(struct clk *clk) return clk->parent->rate; } +int clk_reparent(struct clk *child, struct clk *parent) +{ + list_del_init(&child->sibling); + if (parent) + list_add(&child->sibling, &parent->children); + child->parent = parent; + + /* now do the debugfs renaming to reattach the child + to the proper parent */ + + return 0; +} + /* Propagate rate to children */ void propagate_rate(struct clk *tclk) { @@ -288,12 +301,19 @@ int clk_set_parent(struct clk *clk, struct clk *parent) if (!parent || !clk) return ret; + if (clk->parent == parent) + return 0; spin_lock_irqsave(&clock_lock, flags); if (clk->usecount == 0) { if (clk->ops->set_parent) ret = clk->ops->set_parent(clk, parent); + else + ret = clk_reparent(clk, parent); + if (ret == 0) { + pr_debug("clock: set parent of %s to %s (new rate %ld)\n", + clk->name, clk->parent->name, clk->rate); if (clk->ops->recalc) clk->rate = clk->ops->recalc(clk); propagate_rate(clk); -- cgit v1.2.3-70-g09d2 From 007e8363b656768fe3f59c180824ff704680bb25 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 06:05:32 +0900 Subject: sh: clkfwk: Kill off clk_recalc_rate(). The only user for this is the SH-Mobile r_clk, which is now added as a root clock and can be kicked via propagate_rate() as usual. Given that, there is no longer any need for the special clk_recalc_rate(), so we kill it off. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 1 - arch/sh/kernel/cpu/clock.c | 14 -------------- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 2 +- 3 files changed, 1 insertion(+), 16 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index fdb915608db..6a2f4633337 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -49,7 +49,6 @@ unsigned long followparent_recalc(struct clk *); void recalculate_root_clocks(void); void propagate_rate(struct clk *); int clk_reparent(struct clk *child, struct clk *parent); -void clk_recalc_rate(struct clk *); int clk_register(struct clk *); void clk_unregister(struct clk *); diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index e3d1de8a46f..7a356de99d7 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -280,20 +280,6 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) } EXPORT_SYMBOL_GPL(clk_set_rate_ex); -void clk_recalc_rate(struct clk *clk) -{ - unsigned long flags; - - if (!clk->ops->recalc) - return; - - spin_lock_irqsave(&clock_lock, flags); - clk->rate = clk->ops->recalc(clk); - propagate_rate(clk); - spin_unlock_irqrestore(&clock_lock, flags); -} -EXPORT_SYMBOL_GPL(clk_recalc_rate); - int clk_set_parent(struct clk *clk, struct clk *parent) { unsigned long flags; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 1c41db41de7..426065b4326 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -912,7 +912,7 @@ int __init arch_clk_init(void) clk_put(clk); } - clk_recalc_rate(&sh7722_r_clock); /* make sure rate gets propagated */ + propagate_rate(&sh7722_r_clock); /* make sure rate gets propagated */ return 0; } -- cgit v1.2.3-70-g09d2 From 0dae89572cbcd5f676ea52a9448d9639d97a53d6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 06:18:09 +0900 Subject: sh: clkfwk: Wire up clk_get_sys() support. This stubs in clk_get_sys() from the ARM clkdev implementation. Tentatively conver the clk_get() lookup code to use this, and once the rest of the in-tree users are happy with this, it can replace the fallback lookups. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 7 ++++++ arch/sh/kernel/cpu/clock.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 6a2f4633337..e2f5bf1b4a9 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -37,6 +37,13 @@ struct clk { unsigned long arch_flags; }; +struct clk_lookup { + struct list_head node; + const char *dev_id; + const char *con_id; + struct clk *clk; +}; + #define CLK_ENABLE_ON_INIT (1 << 0) /* Should be defined by processor-specific code */ diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 7a356de99d7..34707b86776 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -10,6 +10,10 @@ * * Modified for omap shared clock framework by Tony Lindgren * + * With clkdev bits: + * + * Copyright (C) 2008 Russell King. + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -334,15 +338,70 @@ long clk_round_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL_GPL(clk_round_rate); +/* + * Find the correct struct clk for the device and connection ID. + * We do slightly fuzzy matching here: + * An entry with a NULL ID is assumed to be a wildcard. + * If an entry has a device ID, it must match + * If an entry has a connection ID, it must match + * Then we take the most specific entry - with the following + * order of precidence: dev+con > dev only > con only. + */ +static struct clk *clk_find(const char *dev_id, const char *con_id) +{ + struct clk_lookup *p; + struct clk *clk = NULL; + int match, best = 0; + + list_for_each_entry(p, &clock_list, node) { + match = 0; + if (p->dev_id) { + if (!dev_id || strcmp(p->dev_id, dev_id)) + continue; + match += 2; + } + if (p->con_id) { + if (!con_id || strcmp(p->con_id, con_id)) + continue; + match += 1; + } + if (match == 0) + continue; + + if (match > best) { + clk = p->clk; + best = match; + } + } + return clk; +} + +struct clk *clk_get_sys(const char *dev_id, const char *con_id) +{ + struct clk *clk; + + mutex_lock(&clock_list_sem); + clk = clk_find(dev_id, con_id); + mutex_unlock(&clock_list_sem); + + return clk ? clk : ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL_GPL(clk_get_sys); + /* * Returns a clock. Note that we first try to use device id on the bus * and clock name. If this fails, we try to use clock name only. */ struct clk *clk_get(struct device *dev, const char *id) { + const char *dev_id = dev ? dev_name(dev) : NULL; struct clk *p, *clk = ERR_PTR(-ENOENT); int idno; + clk = clk_get_sys(dev_id, id); + if (clk) + return clk; + if (dev == NULL || dev->bus != &platform_bus_type) idno = -1; else -- cgit v1.2.3-70-g09d2 From f3f8290cb3fa4aa627321530bb85d5f35e487433 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 16:07:40 +0900 Subject: sh: clkfwk: Handle clk_get_sys() returning an ERR_PTR. clk_get() needs to also perform an IS_ERR() check to see whether clk_get_sys() failed or not. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 2 +- 1 file changed, 1 insertion(+), 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 34707b86776..9e1fc133a47 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -399,7 +399,7 @@ struct clk *clk_get(struct device *dev, const char *id) int idno; clk = clk_get_sys(dev_id, id); - if (clk) + if (clk && !IS_ERR(clk)) return clk; if (dev == NULL || dev->bus != &platform_bus_type) -- cgit v1.2.3-70-g09d2 From 9fe5ee0efb1b1d4a0939bc4252a8427e3337d96a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 May 2009 19:29:04 +0900 Subject: sh: clkfwk: Use arch_clk_init() for on-chip clock registration. CPUs registering on-chip clocks should be using arch_clk_init() with the new scheme so that the CPUs have the opportunity to establish the topology prior to the initial root clock rate propagation. This ensures that CPUs with on-chip clocks that use CLK_ENABLE_ON_INIT are properly enabled at the initial propagation time, without having to further poke the root clocks. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 8 +------- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 3 +-- arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 3 +-- arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 3 +-- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 3 +-- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 3 +-- arch/sh/kernel/cpu/sh4a/clock-shx3.c | 3 +-- 7 files changed, 7 insertions(+), 19 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 9e1fc133a47..f833843a194 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -437,13 +437,7 @@ void clk_put(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_put); -void __init __attribute__ ((weak)) -arch_init_clk_ops(struct clk_ops **ops, int type) -{ -} - -int __init __attribute__ ((weak)) -arch_clk_init(void) +int __init __weak arch_clk_init(void) { return 0; } diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 435f4f12ffb..a72dc326d0b 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -150,7 +150,7 @@ static struct clk *sh4202_onchip_clocks[] = { &sh4202_shoc_clk, }; -static int __init sh4202_clk_init(void) +int __init arch_clk_init(void) { struct clk *clk = clk_get(NULL, "master_clk"); int i, ret = 0; @@ -166,4 +166,3 @@ static int __init sh4202_clk_init(void) return ret; } -arch_initcall(sh4202_clk_init); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index 0110da64a43..ce3d4e6319a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c @@ -90,7 +90,7 @@ static struct clk *sh7763_onchip_clocks[] = { &sh7763_shyway_clk, }; -static int __init sh7763_clk_init(void) +int __init arch_clk_init(void) { struct clk *clk = clk_get(NULL, "master_clk"); int i, ret = 0; @@ -106,4 +106,3 @@ static int __init sh7763_clk_init(void) return ret; } -arch_initcall(sh7763_clk_init); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index 0a22d50b109..38b8b1ddb28 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -96,7 +96,7 @@ static struct clk *sh7780_onchip_clocks[] = { &sh7780_shyway_clk, }; -static int __init sh7780_clk_init(void) +int __init arch_clk_init(void) { struct clk *clk = clk_get(NULL, "master_clk"); int i, ret = 0; @@ -112,4 +112,3 @@ static int __init sh7780_clk_init(void) return ret; } -arch_initcall(sh7780_clk_init); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 4dcd1f6f0cb..fa14f35bc11 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -134,7 +134,7 @@ static struct clk *sh7785_onchip_clocks[] = { &sh7785_ram_clk, }; -static int __init sh7785_clk_init(void) +int __init arch_clk_init(void) { struct clk *clk = clk_get(NULL, "master_clk"); int i, ret = 0; @@ -150,4 +150,3 @@ static int __init sh7785_clk_init(void) return ret; } -arch_initcall(sh7785_clk_init); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 825556fe230..7907002fa1d 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -120,7 +120,7 @@ static struct clk *sh7786_onchip_clocks[] = { &sh7786_ddr_clk, }; -static int __init sh7786_clk_init(void) +int __init arch_clk_init(void) { struct clk *clk = clk_get(NULL, "master_clk"); int i, ret = 0; @@ -136,4 +136,3 @@ static int __init sh7786_clk_init(void) return ret; } -arch_initcall(sh7786_clk_init); diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index 1eb149b0fe6..c14553e3e13 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -107,7 +107,7 @@ static struct clk *shx3_onchip_clocks[] = { &shx3_shyway_clk, }; -static int __init shx3_clk_init(void) +int __init arch_clk_init(void) { struct clk *clk = clk_get(NULL, "master_clk"); int i, ret = 0; @@ -123,4 +123,3 @@ static int __init shx3_clk_init(void) return ret; } -arch_initcall(shx3_clk_init); -- cgit v1.2.3-70-g09d2 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/Kconfig | 11 ---------- arch/sh/include/asm/timer.h | 28 ------------------------- arch/sh/kernel/Makefile_32 | 2 +- arch/sh/kernel/Makefile_64 | 2 +- arch/sh/kernel/cpu/clock.c | 1 - arch/sh/kernel/time.c | 29 ++------------------------ arch/sh/kernel/timers/Makefile | 5 ----- arch/sh/kernel/timers/timer.c | 46 ------------------------------------------ 8 files changed, 4 insertions(+), 120 deletions(-) delete mode 100644 arch/sh/include/asm/timer.h delete mode 100644 arch/sh/kernel/timers/Makefile delete mode 100644 arch/sh/kernel/timers/timer.c (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index e7b6406c96b..fb75c2d1928 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -494,17 +494,6 @@ config SH_TIMER_MTU2 help This enables build of the MTU2 timer driver. -config SH_TIMER_IRQ - int - default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || \ - CPU_SUBTYPE_SH7763 - default "86" if CPU_SUBTYPE_SH7619 - default "140" if CPU_SUBTYPE_SH7206 - default "142" if CPU_SUBTYPE_SH7203 && SH_CMT - default "153" if CPU_SUBTYPE_SH7203 && SH_MTU2 - default "238" if CPU_SUBTYPE_MXG - default "16" - config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" default "27000000" if CPU_SUBTYPE_SH7343 diff --git a/arch/sh/include/asm/timer.h b/arch/sh/include/asm/timer.h deleted file mode 100644 index f27a88bfdcc..00000000000 --- a/arch/sh/include/asm/timer.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __ASM_SH_TIMER_H -#define __ASM_SH_TIMER_H - -#include -#include -#include - -struct sys_timer_ops { - int (*init)(void); - int (*start)(void); - int (*stop)(void); -}; - -struct sys_timer { - const char *name; - - struct sys_device dev; - struct sys_timer_ops *ops; -}; - -extern struct sys_timer *sys_timer; - -/* arch/sh/kernel/timers/timer.c */ -struct sys_timer *get_sys_timer(void); - -extern struct clocksource clocksource_sh; - -#endif /* __ASM_SH_TIMER_H */ diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32 index aee08afe5ff..9411e3e31e6 100644 --- a/arch/sh/kernel/Makefile_32 +++ b/arch/sh/kernel/Makefile_32 @@ -14,7 +14,7 @@ obj-y := debugtraps.o idle.o io.o io_generic.o irq.o \ sys_sh.o sys_sh32.o syscalls_32.o time.o topology.o \ traps.o traps_32.o -obj-y += cpu/ timers/ +obj-y += cpu/ obj-$(CONFIG_VSYSCALL) += vsyscall/ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64 index c845a0d6197..67b9f6c6326 100644 --- a/arch/sh/kernel/Makefile_64 +++ b/arch/sh/kernel/Makefile_64 @@ -4,7 +4,7 @@ obj-y := debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \ ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \ syscalls_64.o time.o topology.o traps.o traps_64.o -obj-y += cpu/ timers/ +obj-y += cpu/ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o obj-$(CONFIG_MODULES) += sh_ksyms_64.o module.o diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 133dbe40334..f54769f455b 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); diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index a77838f539f..2edde32c764 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -22,9 +22,6 @@ #include #include #include -#include - -struct sys_timer *sys_timer; /* Dummy RTC ops */ static void null_rtc_get_time(struct timespec *tv) @@ -94,20 +91,9 @@ module_init(rtc_generic_init); void (*board_time_init)(void); -struct clocksource clocksource_sh = { - .name = "SuperH", -}; - unsigned long long sched_clock(void) { - unsigned long long cycles; - - /* jiffies based sched_clock if no clocksource is installed */ - if (!clocksource_sh.rating) - return (jiffies_64 - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ); - - cycles = clocksource_sh.read(&clocksource_sh); - return cyc2ns(&clocksource_sh, cycles); + return (jiffies_64 - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ); } static void __init sh_late_time_init(void) @@ -117,18 +103,7 @@ static void __init sh_late_time_init(void) * Run probe() for one "earlytimer" device. */ early_platform_driver_register_all("earlytimer"); - if (early_platform_driver_probe("earlytimer", 1, 0)) - return; - - /* - * Find the timer to use as the system timer, it will be - * initialized for us. - */ - sys_timer = get_sys_timer(); - if (unlikely(!sys_timer)) - panic("System timer missing.\n"); - - printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); + early_platform_driver_probe("earlytimer", 1, 0); } void __init time_init(void) diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile deleted file mode 100644 index fefd7edd413..00000000000 --- a/arch/sh/kernel/timers/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the various Linux/SuperH timers -# - -obj-y := timer.o diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c deleted file mode 100644 index f8812bd3b79..00000000000 --- a/arch/sh/kernel/timers/timer.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * arch/sh/kernel/timers/timer.c - Common timer code - * - * Copyright (C) 2005 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -static struct sys_timer *sys_timers[] = { - NULL, -}; - -static char timer_override[10]; -static int __init timer_setup(char *str) -{ - if (str) - strlcpy(timer_override, str, sizeof(timer_override)); - return 1; -} -__setup("timer=", timer_setup); - -struct sys_timer *get_sys_timer(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(sys_timers); i++) { - struct sys_timer *t = sys_timers[i]; - - if (unlikely(!t)) - break; - if (unlikely(timer_override[0])) - if ((strcmp(timer_override, t->name) != 0)) - continue; - if (likely(t->ops->init() == 0)) - return t; - } - - return NULL; -} -- cgit v1.2.3-70-g09d2 From af777ce42d3d51cdef353ce296d6f99dc503feef Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 May 2009 16:59:40 +0900 Subject: sh: clkfwk: module_clk -> peripheral_clk rename. For consistenct naming, and to allow us to fix up some confusion in the SH-Mobile clock framework, amongst other places. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 6 +++--- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 4 ++-- arch/sh/kernel/cpu/sh2a/setup-mxg.c | 6 +++--- arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 6 +++--- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 8 ++++---- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 10 +++++----- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 6 +++--- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 6 +++--- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 6 +++--- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 6 +++--- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 10 +++++----- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 6 +++--- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 18 +++++++++--------- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 24 ++++++++++++------------ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 12 ++++++------ arch/sh/kernel/cpu/sh5/setup-sh5.c | 6 +++--- drivers/i2c/busses/i2c-sh7760.c | 2 +- drivers/serial/sh-sci.c | 2 +- sound/oss/sh_dac_audio.c | 10 +++++----- 23 files changed, 103 insertions(+), 103 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 61ff227561d..0eedf939264 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -50,8 +50,8 @@ static struct clk master_clk = { .rate = CONFIG_SH_PCLK_FREQ, }; -static struct clk module_clk = { - .name = "module_clk", +static struct clk peripheral_clk = { + .name = "peripheral_clk", .parent = &master_clk, .flags = CLK_ENABLE_ON_INIT, }; @@ -73,7 +73,7 @@ static struct clk cpu_clk = { */ static struct clk *onchip_clocks[] = { &master_clk, - &module_clk, + &peripheral_clk, &bus_clk, &cpu_clk, }; diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 94ac27fc223..13798733f2d 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -115,7 +115,7 @@ static struct sh_timer_config cmt0_platform_data = { .name = "CMT0", .channel_offset = 0x02, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -147,7 +147,7 @@ static struct sh_timer_config cmt1_platform_data = { .name = "CMT1", .channel_offset = 0x08, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index a452d964906..869c2da4820 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -118,7 +118,7 @@ static struct sh_timer_config mtu2_0_platform_data = { .name = "MTU2_0", .channel_offset = -0x80, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -149,7 +149,7 @@ static struct sh_timer_config mtu2_1_platform_data = { .name = "MTU2_1", .channel_offset = -0x100, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -180,7 +180,7 @@ static struct sh_timer_config mtu2_2_platform_data = { .name = "MTU2_2", .channel_offset = 0x80, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index 772358b7685..d8febe12806 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -255,7 +255,7 @@ static struct sh_timer_config mtu2_0_platform_data = { .name = "MTU2_0", .channel_offset = -0x80, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -286,7 +286,7 @@ static struct sh_timer_config mtu2_1_platform_data = { .name = "MTU2_1", .channel_offset = -0x100, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -317,7 +317,7 @@ static struct sh_timer_config mtu2_2_platform_data = { .name = "MTU2_2", .channel_offset = 0x80, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index d7493418ba6..62e3039d239 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -211,7 +211,7 @@ static struct sh_timer_config cmt0_platform_data = { .name = "CMT0", .channel_offset = 0x02, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -243,7 +243,7 @@ static struct sh_timer_config cmt1_platform_data = { .name = "CMT1", .channel_offset = 0x08, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -275,7 +275,7 @@ static struct sh_timer_config mtu2_0_platform_data = { .name = "MTU2_0", .channel_offset = -0x80, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -306,7 +306,7 @@ static struct sh_timer_config mtu2_1_platform_data = { .name = "MTU2_1", .channel_offset = -0x100, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 2fc6bff5c5f..3e6f3d7a58b 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -171,7 +171,7 @@ static struct sh_timer_config cmt0_platform_data = { .name = "CMT0", .channel_offset = 0x02, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -203,7 +203,7 @@ static struct sh_timer_config cmt1_platform_data = { .name = "CMT1", .channel_offset = 0x08, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -235,7 +235,7 @@ static struct sh_timer_config mtu2_0_platform_data = { .name = "MTU2_0", .channel_offset = -0x80, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -266,7 +266,7 @@ static struct sh_timer_config mtu2_1_platform_data = { .name = "MTU2_1", .channel_offset = -0x100, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -297,7 +297,7 @@ static struct sh_timer_config mtu2_2_platform_data = { .name = "MTU2_2", .channel_offset = 0x80, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 39513664d5d..88f742fed9e 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -121,7 +121,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x02, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -152,7 +152,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0xe, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -183,7 +183,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1a, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 9412d915b84..c5630679858 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -149,7 +149,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x02, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -180,7 +180,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0xe, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -211,7 +211,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1a, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 07ff38d055a..efa76c8148f 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -125,7 +125,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x02, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -156,7 +156,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0xe, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -187,7 +187,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1a, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index d8b46f5dff6..5b2107798ed 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -128,7 +128,7 @@ static struct sh_timer_config cmt0_platform_data = { .name = "CMT0", .channel_offset = 0x10, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 125, }; @@ -160,7 +160,7 @@ static struct sh_timer_config cmt1_platform_data = { .name = "CMT1", .channel_offset = 0x20, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource cmt1_resources[] = { @@ -190,7 +190,7 @@ static struct sh_timer_config cmt2_platform_data = { .name = "CMT2", .channel_offset = 0x30, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource cmt2_resources[] = { @@ -220,7 +220,7 @@ static struct sh_timer_config cmt3_platform_data = { .name = "CMT3", .channel_offset = 0x40, .timer_bit = 3, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource cmt3_resources[] = { @@ -250,7 +250,7 @@ static struct sh_timer_config cmt4_platform_data = { .name = "CMT4", .channel_offset = 0x50, .timer_bit = 4, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource cmt4_resources[] = { @@ -280,7 +280,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x02, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -311,7 +311,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0xe, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -342,7 +342,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1a, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index be79fa13625..6d088d12359 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -38,7 +38,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -69,7 +69,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -100,7 +100,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 09da0c187d4..851672d15cf 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -65,7 +65,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -96,7 +96,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -127,7 +127,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -162,7 +162,7 @@ static struct sh_timer_config tmu3_platform_data = { .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -192,7 +192,7 @@ static struct sh_timer_config tmu4_platform_data = { .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index cd097335758..5b822519bd9 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -164,7 +164,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -195,7 +195,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -226,7 +226,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index c91f34c9aa8..f1e0c0d36da 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -118,7 +118,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -149,7 +149,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -180,7 +180,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -210,7 +210,7 @@ static struct sh_timer_config tmu3_platform_data = { .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -240,7 +240,7 @@ static struct sh_timer_config tmu4_platform_data = { .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -270,7 +270,7 @@ static struct sh_timer_config tmu5_platform_data = { .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index b61d6143aaa..12fb8752d4f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -81,7 +81,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -112,7 +112,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -143,7 +143,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -173,7 +173,7 @@ static struct sh_timer_config tmu3_platform_data = { .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -203,7 +203,7 @@ static struct sh_timer_config tmu4_platform_data = { .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -233,7 +233,7 @@ static struct sh_timer_config tmu5_platform_data = { .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { @@ -263,7 +263,7 @@ static struct sh_timer_config tmu6_platform_data = { .name = "TMU6", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu6_resources[] = { @@ -293,7 +293,7 @@ static struct sh_timer_config tmu7_platform_data = { .name = "TMU7", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu7_resources[] = { @@ -323,7 +323,7 @@ static struct sh_timer_config tmu8_platform_data = { .name = "TMU8", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu8_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index f1df0209506..715e05b431e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -18,7 +18,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -49,7 +49,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -80,7 +80,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -110,7 +110,7 @@ static struct sh_timer_config tmu3_platform_data = { .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -140,7 +140,7 @@ static struct sh_timer_config tmu4_platform_data = { .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -170,7 +170,7 @@ static struct sh_timer_config tmu5_platform_data = { .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index dc5d3e507a2..d7e77bc77e2 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -20,7 +20,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -51,7 +51,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -82,7 +82,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -112,7 +112,7 @@ static struct sh_timer_config tmu3_platform_data = { .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -142,7 +142,7 @@ static struct sh_timer_config tmu4_platform_data = { .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -172,7 +172,7 @@ static struct sh_timer_config tmu5_platform_data = { .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 2c464bf5a89..93e0d2c017e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -75,7 +75,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -106,7 +106,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -137,7 +137,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -167,7 +167,7 @@ static struct sh_timer_config tmu3_platform_data = { .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -197,7 +197,7 @@ static struct sh_timer_config tmu4_platform_data = { .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -227,7 +227,7 @@ static struct sh_timer_config tmu5_platform_data = { .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { @@ -257,7 +257,7 @@ static struct sh_timer_config tmu6_platform_data = { .name = "TMU6", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu6_resources[] = { @@ -287,7 +287,7 @@ static struct sh_timer_config tmu7_platform_data = { .name = "TMU7", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu7_resources[] = { @@ -317,7 +317,7 @@ static struct sh_timer_config tmu8_platform_data = { .name = "TMU8", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu8_resources[] = { @@ -347,7 +347,7 @@ static struct sh_timer_config tmu9_platform_data = { .name = "TMU9", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu9_resources[] = { @@ -377,7 +377,7 @@ static struct sh_timer_config tmu10_platform_data = { .name = "TMU10", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu10_resources[] = { @@ -407,7 +407,7 @@ static struct sh_timer_config tmu11_platform_data = { .name = "TMU11", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu11_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 9d5185b42f1..53c65fd9cce 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -53,7 +53,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -84,7 +84,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -115,7 +115,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -145,7 +145,7 @@ static struct sh_timer_config tmu3_platform_data = { .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -175,7 +175,7 @@ static struct sh_timer_config tmu4_platform_data = { .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -205,7 +205,7 @@ static struct sh_timer_config tmu5_platform_data = { .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index 678d69bdebb..f5ff1ac57fc 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -75,7 +75,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "module_clk", + .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -106,7 +106,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "module_clk", + .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -137,7 +137,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "module_clk", + .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c index baa28b73ae4..b9680f50f54 100644 --- a/drivers/i2c/busses/i2c-sh7760.c +++ b/drivers/i2c/busses/i2c-sh7760.c @@ -396,7 +396,7 @@ static int __devinit calc_CCR(unsigned long scl_hz) signed char cdf, cdfm; int scgd, scgdm, scgds; - mclk = clk_get(NULL, "module_clk"); + mclk = clk_get(NULL, "peripheral_clk"); if (IS_ERR(mclk)) { return PTR_ERR(mclk); } else { diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 4e3248d5860..fa4d52a6c03 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1084,7 +1084,7 @@ static void __devinit sci_init_single(struct platform_device *dev, sci_port->port.uartclk = CONFIG_CPU_CLOCK; #elif defined(CONFIG_HAVE_CLK) sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; - sci_port->dclk = clk_get(&dev->dev, "module_clk"); + sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); sci_port->enable = sci_clk_enable; sci_port->disable = sci_clk_disable; #else diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c index 78cfb66e4c5..6fa3140720b 100644 --- a/sound/oss/sh_dac_audio.c +++ b/sound/oss/sh_dac_audio.c @@ -95,18 +95,18 @@ static void dac_audio_stop(void) outw(v, HD64461_GPADR); } - sh_dac_output(0, CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL); + sh_dac_output(0, CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL); sh_dac_disable(CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL); } static void dac_audio_set_rate(void) { unsigned long interval; - struct clk *clk; + struct clk *clk; - clk = clk_get(NULL, "module_clk"); - interval = (clk_get_rate(clk) / 4) / rate; - clk_put(clk); + clk = clk_get(NULL, "peripheral_clk"); + interval = (clk_get_rate(clk) / 4) / rate; + clk_put(clk); ctrl_outl(interval, TMU1_TCOR); ctrl_outl(interval, TMU1_TCNT); } -- cgit v1.2.3-70-g09d2 From d672fef02738582bdeae6e77176e141eeb9169bc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 May 2009 17:03:09 +0900 Subject: sh: clkfwk: Handle NULL clkops for root clocks. root clocks may simply be placeholders for rate and ancestry information, and have no real associated operations of their own. Account for this, so we are still able to use these sorts of clocks for rate propagation. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 6 +++--- 1 file changed, 3 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 0eedf939264..2ced20f870d 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -103,7 +103,7 @@ void propagate_rate(struct clk *tclk) struct clk *clkp; list_for_each_entry(clkp, &tclk->children, sibling) { - if (clkp->ops->recalc) + if (clkp->ops && clkp->ops->recalc) clkp->rate = clkp->ops->recalc(clkp); propagate_rate(clkp); } @@ -196,7 +196,7 @@ void recalculate_root_clocks(void) struct clk *clkp; list_for_each_entry(clkp, &root_clks, sibling) { - if (clkp->ops->recalc) + if (clkp->ops && clkp->ops->recalc) clkp->rate = clkp->ops->recalc(clkp); propagate_rate(clkp); } @@ -224,7 +224,7 @@ int clk_register(struct clk *clk) list_add(&clk->sibling, &root_clks); list_add(&clk->node, &clock_list); - if (clk->ops->init) + if (clk->ops && clk->ops->init) clk->ops->init(clk); mutex_unlock(&clock_list_sem); -- cgit v1.2.3-70-g09d2 From 100890c55e326a9acb4429593c5ad2012c194564 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 May 2009 17:05:51 +0900 Subject: sh: clkfwk: Provide a generic clk_set_rate_ex() path for root clocks. In the case of root clocks (such as clkin oscillators, extal, etc.), the rate information is entirely platform dependent and needs to be lazily set and propagated from the platform code. This provides a method for establishing the rate update on these types of clocks that define no set_rate() op of their own. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 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 2ced20f870d..0a7755cc8a2 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -265,20 +265,27 @@ EXPORT_SYMBOL_GPL(clk_set_rate); int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) { int ret = -EOPNOTSUPP; + unsigned long flags; - if (likely(clk->ops && clk->ops->set_rate)) { - unsigned long flags; + spin_lock_irqsave(&clock_lock, flags); - spin_lock_irqsave(&clock_lock, flags); + if (likely(clk->ops && clk->ops->set_rate)) { ret = clk->ops->set_rate(clk, rate, algo_id); - if (ret == 0) { - if (clk->ops->recalc) - clk->rate = clk->ops->recalc(clk); - propagate_rate(clk); - } - spin_unlock_irqrestore(&clock_lock, flags); + if (ret != 0) + goto out_unlock; + } else { + clk->rate = rate; + ret = 0; } + if (clk->ops && clk->ops->recalc) + clk->rate = clk->ops->recalc(clk); + + propagate_rate(clk); + +out_unlock: + spin_unlock_irqrestore(&clock_lock, flags); + return ret; } EXPORT_SYMBOL_GPL(clk_set_rate_ex); -- cgit v1.2.3-70-g09d2 From 253b0887b3736160feac9ccdcf146a2073e41463 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 May 2009 17:38:11 +0900 Subject: sh: clkfwk: Rework legacy CPG clock handling. This moves out the old legacy CPG clocks to their own file, and converts over the existing users. With these clocks going away and each CPU dealing with them on their own, CPUs can gradually move over to the new interface. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 ++ arch/sh/include/asm/clock.h | 5 ++- arch/sh/include/asm/machvec.h | 2 + arch/sh/kernel/cpu/Makefile | 1 + arch/sh/kernel/cpu/clock-cpg.c | 60 +++++++++++++++++++++++++++++ arch/sh/kernel/cpu/clock.c | 70 +++++++--------------------------- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 5 ++- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 2 + arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 5 ++- arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 5 ++- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 5 ++- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 5 ++- arch/sh/kernel/cpu/sh4a/clock-shx3.c | 5 ++- 13 files changed, 110 insertions(+), 63 deletions(-) create mode 100644 arch/sh/kernel/cpu/clock-cpg.c (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index fb75c2d1928..d7990cd2f8d 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -513,6 +513,9 @@ config SH_PCLK_FREQ This is necessary for determining the reference clock value on platforms lacking an RTC. +config SH_CLK_CPG_LEGACY + def_bool y + config SH_CLK_MD int "CPU Mode Pin Setting" depends on CPU_SH2 diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index e2f5bf1b4a9..c27e844db0d 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -47,7 +47,7 @@ struct clk_lookup { #define CLK_ENABLE_ON_INIT (1 << 0) /* Should be defined by processor-specific code */ -void arch_init_clk_ops(struct clk_ops **, int type); +void __deprecated arch_init_clk_ops(struct clk_ops **, int type); int __init arch_clk_init(void); /* arch/sh/kernel/cpu/clock.c */ @@ -59,6 +59,9 @@ int clk_reparent(struct clk *child, struct clk *parent); int clk_register(struct clk *); void clk_unregister(struct clk *); +/* arch/sh/kernel/cpu/clock-cpg.c */ +int __init __deprecated cpg_clk_init(void); + /* the exported API, in addition to clk_set_rate */ /** * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h index 64b1c16a0f0..73d6d16fa06 100644 --- a/arch/sh/include/asm/machvec.h +++ b/arch/sh/include/asm/machvec.h @@ -46,6 +46,8 @@ struct sh_machine_vector { void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size); void (*mv_ioport_unmap)(void __iomem *); + + int (*mv_clk_init)(void); }; extern struct sh_machine_vector sh_mv; diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index 2600641a483..05105b980c2 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -17,5 +17,6 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/ obj-$(CONFIG_UBC_WAKEUP) += ubc.o obj-$(CONFIG_SH_ADC) += adc.o +obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o obj-y += irq/ init.o clock.o diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c new file mode 100644 index 00000000000..b4ca2004844 --- /dev/null +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -0,0 +1,60 @@ +#include +#include +#include + +static struct clk master_clk = { + .name = "master_clk", + .flags = CLK_ENABLE_ON_INIT, + .rate = CONFIG_SH_PCLK_FREQ, +}; + +static struct clk peripheral_clk = { + .name = "peripheral_clk", + .parent = &master_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static struct clk bus_clk = { + .name = "bus_clk", + .parent = &master_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static struct clk cpu_clk = { + .name = "cpu_clk", + .parent = &master_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +/* + * The ordering of these clocks matters, do not change it. + */ +static struct clk *onchip_clocks[] = { + &master_clk, + &peripheral_clk, + &bus_clk, + &cpu_clk, +}; + +int __init __deprecated cpg_clk_init(void) +{ + int i, ret = 0; + + for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { + struct clk *clk = onchip_clocks[i]; + arch_init_clk_ops(&clk->ops, i); + if (clk->ops) + ret |= clk_register(clk); + } + + return ret; +} + +/* + * Placeholder for compatability, until the lazy CPUs do this + * on their own. + */ +int __init __weak arch_clk_init(void) +{ + return cpg_clk_init(); +} diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 0a7755cc8a2..033f4662b59 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -30,54 +30,12 @@ #include #include #include +#include static LIST_HEAD(clock_list); static DEFINE_SPINLOCK(clock_lock); static DEFINE_MUTEX(clock_list_sem); -/* - * Each subtype is expected to define the init routines for these clocks, - * as each subtype (or processor family) will have these clocks at the - * very least. These are all provided through the CPG, which even some of - * the more quirky parts (such as ST40, SH4-202, etc.) still have. - * - * The processor-specific code is expected to register any additional - * clock sources that are of interest. - */ -static struct clk master_clk = { - .name = "master_clk", - .flags = CLK_ENABLE_ON_INIT, - .rate = CONFIG_SH_PCLK_FREQ, -}; - -static struct clk peripheral_clk = { - .name = "peripheral_clk", - .parent = &master_clk, - .flags = CLK_ENABLE_ON_INIT, -}; - -static struct clk bus_clk = { - .name = "bus_clk", - .parent = &master_clk, - .flags = CLK_ENABLE_ON_INIT, -}; - -static struct clk cpu_clk = { - .name = "cpu_clk", - .parent = &master_clk, - .flags = CLK_ENABLE_ON_INIT, -}; - -/* - * The ordering of these clocks matters, do not change it. - */ -static struct clk *onchip_clocks[] = { - &master_clk, - &peripheral_clk, - &bus_clk, - &cpu_clk, -}; - /* Used for clocks that always have same value as the parent clock */ unsigned long followparent_recalc(struct clk *clk) { @@ -443,10 +401,6 @@ void clk_put(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_put); -int __init __weak arch_clk_init(void) -{ - return 0; -} static int show_clocks(char *buf, char **start, off_t off, int len, int *eof, void *data) @@ -533,18 +487,22 @@ subsys_initcall(clk_sysdev_init); int __init clk_init(void) { - int i, ret = 0; - - BUG_ON(!master_clk.rate); - - for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { - struct clk *clk = onchip_clocks[i]; + int ret; - arch_init_clk_ops(&clk->ops, i); - ret |= clk_register(clk); + ret = arch_clk_init(); + if (unlikely(ret)) { + pr_err("%s: CPU clock registration failed.\n", __func__); + return ret; } - ret |= arch_clk_init(); + if (sh_mv.mv_clk_init) { + ret = sh_mv.mv_clk_init(); + if (unlikely(ret)) { + pr_err("%s: machvec clock initialization failed.\n", + __func__); + return ret; + } + } /* Kick the child clocks.. */ recalculate_root_clocks(); diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index a72dc326d0b..21421e34e7d 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -152,9 +152,12 @@ static struct clk *sh4202_onchip_clocks[] = { int __init arch_clk_init(void) { - struct clk *clk = clk_get(NULL, "master_clk"); + struct clk *clk; int i, ret = 0; + cpg_clk_init(); + + clk = clk_get(NULL, "master_clk"); for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) { struct clk *clkp = sh4202_onchip_clocks[i]; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 426065b4326..a98d7da67b9 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -892,6 +892,8 @@ int __init arch_clk_init(void) struct clk *clk; int i; + clk_cpg_init(); + clk = clk_get(NULL, "master_clk"); for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) { pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index ce3d4e6319a..370cd47642e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c @@ -92,9 +92,12 @@ static struct clk *sh7763_onchip_clocks[] = { int __init arch_clk_init(void) { - struct clk *clk = clk_get(NULL, "master_clk"); + struct clk *clk; int i, ret = 0; + cpg_clk_init(); + + clk = clk_get(NULL, "master_clk"); for (i = 0; i < ARRAY_SIZE(sh7763_onchip_clocks); i++) { struct clk *clkp = sh7763_onchip_clocks[i]; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index 38b8b1ddb28..a249d823578 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -98,9 +98,12 @@ static struct clk *sh7780_onchip_clocks[] = { int __init arch_clk_init(void) { - struct clk *clk = clk_get(NULL, "master_clk"); + struct clk *clk; int i, ret = 0; + cpg_clk_init(); + + clk = clk_get(NULL, "master_clk"); for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { struct clk *clkp = sh7780_onchip_clocks[i]; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index fa14f35bc11..bf5a0dacf8e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -136,9 +136,12 @@ static struct clk *sh7785_onchip_clocks[] = { int __init arch_clk_init(void) { - struct clk *clk = clk_get(NULL, "master_clk"); + struct clk *clk; int i, ret = 0; + cpg_clk_init(); + + clk = clk_get(NULL, "master_clk"); for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) { struct clk *clkp = sh7785_onchip_clocks[i]; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 7907002fa1d..a0e8869071a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -122,9 +122,12 @@ static struct clk *sh7786_onchip_clocks[] = { int __init arch_clk_init(void) { - struct clk *clk = clk_get(NULL, "master_clk"); + struct clk *clk; int i, ret = 0; + cpg_clk_init(); + + clk = clk_get(NULL, "master_clk"); for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) { struct clk *clkp = sh7786_onchip_clocks[i]; diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index c14553e3e13..23c27d32d98 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -109,9 +109,12 @@ static struct clk *shx3_onchip_clocks[] = { int __init arch_clk_init(void) { - struct clk *clk = clk_get(NULL, "master_clk"); + struct clk *clk; int i, ret = 0; + cpg_clk_init(); + + clk = clk_get(NULL, "master_clk"); for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) { struct clk *clkp = shx3_onchip_clocks[i]; -- cgit v1.2.3-70-g09d2 From cc96eace48fdf0f8925a74c6c1f7ffa512e458d2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 May 2009 20:28:15 +0900 Subject: sh: clkfwk: rate table construction and rounding for SH7785. This adds support for constructing a rate table by looking at potential divisors for a specified clock. Each FQRMR clock is given its own table. Presently each table is rebuilt when the parent propagates down a new rate, so some more logic needs to be added to do this more intelligently. Additionally, a fairly generic round_rate() implementation is then layered on top of it, which subsequently provides us with cpufreq support. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 1 + arch/sh/kernel/cpu/clock.c | 3 + arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 109 +++++++++++++++++++++++++++++---- 3 files changed, 100 insertions(+), 13 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 40cf3c07d7e..da681de1500 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -16,6 +16,7 @@ struct clk_ops { int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); int (*set_parent)(struct clk *clk, struct clk *parent); long (*round_rate)(struct clk *clk, unsigned long rate); + void (*build_rate_table)(struct clk *clk); }; struct clk { diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 033f4662b59..56c6e11fa83 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -63,6 +63,9 @@ void propagate_rate(struct clk *tclk) list_for_each_entry(clkp, &tclk->children, sibling) { if (clkp->ops && clkp->ops->recalc) clkp->rate = clkp->ops->recalc(clkp); + if (clkp->ops && clkp->ops->build_rate_table) + clkp->ops->build_rate_table(clkp); + propagate_rate(clkp); } } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 87584dc8192..b7a32dd1b2d 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -13,28 +13,43 @@ #include #include #include +#include #include #include static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18, 24, 32, 36, 48 }; struct clk_priv { - unsigned int shift; + unsigned int shift; + + /* allowable divisor bitmap */ + unsigned long div_bitmap; + + /* Supportable frequencies + termination entry */ + struct cpufreq_frequency_table freq_table[ARRAY_SIZE(div2)+1]; }; -#define FRQMR_CLK_DATA(_name, _shift) \ -static struct clk_priv _name##_data = { .shift = _shift, } +#define FRQMR_CLK_DATA(_name, _shift, _div_bitmap) \ +static struct clk_priv _name##_data = { \ + .shift = _shift, \ + .div_bitmap = _div_bitmap, \ + \ + .freq_table[0] = { \ + .index = 0, \ + .frequency = CPUFREQ_TABLE_END, \ + }, \ +} -FRQMR_CLK_DATA(pfc, 0); -FRQMR_CLK_DATA(s3fc, 4); -FRQMR_CLK_DATA(s2fc, 8); -FRQMR_CLK_DATA(mfc, 12); -FRQMR_CLK_DATA(bfc, 16); -FRQMR_CLK_DATA(sfc, 20); -FRQMR_CLK_DATA(ufc, 24); -FRQMR_CLK_DATA(ifc, 28); +FRQMR_CLK_DATA(pfc, 0, 0x0f80); +FRQMR_CLK_DATA(s3fc, 4, 0x0ff0); +FRQMR_CLK_DATA(s2fc, 8, 0x0030); +FRQMR_CLK_DATA(mfc, 12, 0x000c); +FRQMR_CLK_DATA(bfc, 16, 0x0fe0); +FRQMR_CLK_DATA(sfc, 20, 0x000c); +FRQMR_CLK_DATA(ufc, 24, 0x000c); +FRQMR_CLK_DATA(ifc, 28, 0x000e); -static unsigned long frqmr_clk_recalc(struct clk *clk) +static unsigned long frqmr_recalc(struct clk *clk) { struct clk_priv *data = clk->priv; unsigned int idx; @@ -49,8 +64,76 @@ static unsigned long frqmr_clk_recalc(struct clk *clk) return clk->parent->rate * 36 / div2[idx]; } +static void frqmr_build_rate_table(struct clk *clk) +{ + struct clk_priv *data = clk->priv; + int i, entry; + + for (i = entry = 0; i < ARRAY_SIZE(div2); i++) { + if ((data->div_bitmap & (1 << i)) == 0) + continue; + + data->freq_table[entry].index = entry; + data->freq_table[entry].frequency = + clk->parent->rate * 36 / div2[i]; + + entry++; + } + + if (entry == 0) { + pr_warning("clkfwk: failed to build frequency table " + "for \"%s\" clk!\n", clk->name); + return; + } + + /* Termination entry */ + data->freq_table[entry].index = entry; + data->freq_table[entry].frequency = CPUFREQ_TABLE_END; +} + +static long frqmr_round_rate(struct clk *clk, unsigned long rate) +{ + struct clk_priv *data = clk->priv; + unsigned long rate_error, rate_error_prev = ~0UL; + unsigned long rate_best_fit = rate; + unsigned long highest, lowest; + int i; + + highest = lowest = 0; + + for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { + unsigned long freq = data->freq_table[i].frequency; + + if (freq == CPUFREQ_ENTRY_INVALID) + continue; + + if (freq > highest) + highest = freq; + if (freq < lowest) + lowest = freq; + + rate_error = abs(freq - rate); + if (rate_error < rate_error_prev) { + rate_best_fit = freq; + rate_error_prev = rate_error; + } + + if (rate_error == 0) + break; + } + + if (rate >= highest) + rate_best_fit = highest; + if (rate <= lowest) + rate_best_fit = lowest; + + return rate_best_fit; +} + static struct clk_ops frqmr_clk_ops = { - .recalc = frqmr_clk_recalc, + .recalc = frqmr_recalc, + .build_rate_table = frqmr_build_rate_table, + .round_rate = frqmr_round_rate, }; /* -- cgit v1.2.3-70-g09d2 From cedcf3366f2191885aff92d33d6078ef08203e52 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 May 2009 21:51:28 +0900 Subject: sh: clkfwk: Map tree hierarchy in debugfs. This adopts the OMAP clock framework debugfs bits and replaces the aging procfs bits. The procfs clocks entry was primarily a debugging aid, and used to be tied in to cpuinfo before the clock list grew too unweildly. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 1 + arch/sh/kernel/cpu/clock.c | 110 +++++++++++++++++++++++++++++++++----------- 2 files changed, 85 insertions(+), 26 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index da681de1500..c499d470b8c 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -38,6 +38,7 @@ struct clk { unsigned long arch_flags; void *priv; + struct dentry *dentry; }; struct clk_lookup { diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 56c6e11fa83..686477f8ae5 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include @@ -404,24 +404,6 @@ void clk_put(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_put); - -static int show_clocks(char *buf, char **start, off_t off, - int len, int *eof, void *data) -{ - struct clk *clk; - char *p = buf; - - list_for_each_entry_reverse(clk, &clock_list, node) { - unsigned long rate = clk_get_rate(clk); - - p += sprintf(p, "%-12s\t: %ld.%02ldMHz\t%s\n", clk->name, - rate / 1000000, (rate % 1000000) / 10000, - (clk->usecount > 0) ? "enabled" : "disabled"); - } - - return p - buf; -} - #ifdef CONFIG_PM static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) { @@ -516,14 +498,90 @@ int __init clk_init(void) return ret; } -static int __init clk_proc_init(void) +/* + * debugfs support to trace clock tree hierarchy and attributes + */ +static struct dentry *clk_debugfs_root; + +static int clk_debugfs_register_one(struct clk *c) { - struct proc_dir_entry *p; - p = create_proc_read_entry("clocks", S_IRUSR, NULL, - show_clocks, NULL); - if (unlikely(!p)) - return -EINVAL; + int err; + struct dentry *d, *child; + struct clk *pa = c->parent; + char s[255]; + char *p = s; + + p += sprintf(p, "%s", c->name); + if (c->id > 0) + sprintf(p, ":%d", c->id); + d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root); + if (!d) + return -ENOMEM; + c->dentry = d; + + d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount); + if (!d) { + err = -ENOMEM; + goto err_out; + } + d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate); + if (!d) { + err = -ENOMEM; + goto err_out; + } + d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags); + if (!d) { + err = -ENOMEM; + goto err_out; + } + return 0; + +err_out: + d = c->dentry; + list_for_each_entry(child, &d->d_subdirs, d_u.d_child) + debugfs_remove(child); + debugfs_remove(c->dentry); + return err; +} + +static int clk_debugfs_register(struct clk *c) +{ + int err; + struct clk *pa = c->parent; + + if (pa && !pa->dentry) { + err = clk_debugfs_register(pa); + if (err) + return err; + } + if (!c->dentry) { + err = clk_debugfs_register_one(c); + if (err) + return err; + } + return 0; +} + +static int __init clk_debugfs_init(void) +{ + struct clk *c; + struct dentry *d; + int err; + + d = debugfs_create_dir("clock", NULL); + if (!d) + return -ENOMEM; + clk_debugfs_root = d; + + list_for_each_entry(c, &clock_list, node) { + err = clk_debugfs_register(c); + if (err) + goto err_out; + } return 0; +err_out: + debugfs_remove(clk_debugfs_root); /* REVISIT: Cleanup correctly */ + return err; } -subsys_initcall(clk_proc_init); +late_initcall(clk_debugfs_init); -- cgit v1.2.3-70-g09d2 From 549b5e358d17a8c04953ed80896ce07d37722451 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 May 2009 17:38:46 +0900 Subject: sh: clkfwk: Add MSTP bits to SH7785 clock framework. This plugs in all of the MSTP functions in to the clock framework, and hands them off to the platform devices that want them. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 3 ++ arch/sh/kernel/cpu/clock.c | 4 +-- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 63 ++++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 18 ++++++---- 4 files changed, 80 insertions(+), 8 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index c499d470b8c..64c93cb3d68 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -36,6 +36,9 @@ struct clk { unsigned long rate; unsigned long flags; + void __iomem *enable_reg; + unsigned int enable_bit; + unsigned long arch_flags; void *priv; struct dentry *dentry; diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 686477f8ae5..012d23476a7 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -39,7 +39,7 @@ static DEFINE_MUTEX(clock_list_sem); /* Used for clocks that always have same value as the parent clock */ unsigned long followparent_recalc(struct clk *clk) { - return clk->parent->rate; + return clk->parent ? clk->parent->rate : 0; } int clk_reparent(struct clk *child, struct clk *parent) @@ -512,7 +512,7 @@ static int clk_debugfs_register_one(struct clk *c) char *p = s; p += sprintf(p, "%s", c->name); - if (c->id > 0) + if (c->id >= 0) sprintf(p, ":%d", c->id); d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root); if (!d) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index b7a32dd1b2d..cf042b53b3a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -228,12 +228,75 @@ static struct clk *clks[] = { &umem_clk, }; +static int mstpcr_clk_enable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit), + clk->enable_reg); + return 0; +} + +static void mstpcr_clk_disable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit), + clk->enable_reg); +} + +static struct clk_ops mstpcr_clk_ops = { + .enable = mstpcr_clk_enable, + .disable = mstpcr_clk_disable, + .recalc = followparent_recalc, +}; + +#define MSTPCR0 0xffc80030 +#define MSTPCR1 0xffc80034 + +#define CLK(_name, _id, _parent, _enable_reg, \ + _enable_bit, _flags) \ +{ \ + .name = _name, \ + .id = _id, \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_enable_reg, \ + .enable_bit = _enable_bit, \ + .flags = _flags, \ + .ops = &mstpcr_clk_ops, \ +} + +static struct clk mstpcr_clks[] = { + /* MSTPCR0 */ + CLK("scif_fck", 5, &peripheral_clk, MSTPCR0, 29, 0), + CLK("scif_fck", 4, &peripheral_clk, MSTPCR0, 28, 0), + CLK("scif_fck", 3, &peripheral_clk, MSTPCR0, 27, 0), + CLK("scif_fck", 2, &peripheral_clk, MSTPCR0, 26, 0), + CLK("scif_fck", 1, &peripheral_clk, MSTPCR0, 25, 0), + CLK("scif_fck", 0, &peripheral_clk, MSTPCR0, 24, 0), + CLK("ssi_fck", 1, &peripheral_clk, MSTPCR0, 21, 0), + CLK("ssi_fck", 0, &peripheral_clk, MSTPCR0, 20, 0), + CLK("hac_fck", 1, &peripheral_clk, MSTPCR0, 17, 0), + CLK("hac_fck", 0, &peripheral_clk, MSTPCR0, 16, 0), + CLK("mmcif_fck", -1, &peripheral_clk, MSTPCR0, 13, 0), + CLK("flctl_fck", -1, &peripheral_clk, MSTPCR0, 12, 0), + CLK("tmu345_fck", -1, &peripheral_clk, MSTPCR0, 9, 0), + CLK("tmu012_fck", -1, &peripheral_clk, MSTPCR0, 8, 0), + CLK("siof_fck", -1, &peripheral_clk, MSTPCR0, 3, 0), + CLK("hspi_fck", -1, &peripheral_clk, MSTPCR0, 2, 0), + + /* MSTPCR1 */ + CLK("hudi_fck", -1, NULL, MSTPCR1, 19, 0), + CLK("ubc_fck", -1, NULL, MSTPCR1, 17, 0), + CLK("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0), + CLK("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0), + CLK("gdta_fck", -1, NULL, MSTPCR1, 0, 0), +}; + int __init arch_clk_init(void) { int i, ret = 0; for (i = 0; i < ARRAY_SIZE(clks); i++) ret |= clk_register(clks[i]); + for (i = 0; i < ARRAY_SIZE(mstpcr_clks); i++) + ret |= clk_register(&mstpcr_clks[i]); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index d7e77bc77e2..af561402570 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -20,7 +20,7 @@ static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", + .clk = "tmu012_fck", .clockevent_rating = 200, }; @@ -51,7 +51,7 @@ static struct sh_timer_config tmu1_platform_data = { .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", + .clk = "tmu012_fck", .clocksource_rating = 200, }; @@ -82,7 +82,7 @@ static struct sh_timer_config tmu2_platform_data = { .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", + .clk = "tmu012_fck", }; static struct resource tmu2_resources[] = { @@ -112,7 +112,7 @@ static struct sh_timer_config tmu3_platform_data = { .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", + .clk = "tmu345_fck", }; static struct resource tmu3_resources[] = { @@ -142,7 +142,7 @@ static struct sh_timer_config tmu4_platform_data = { .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", + .clk = "tmu345_fck", }; static struct resource tmu4_resources[] = { @@ -172,7 +172,7 @@ static struct sh_timer_config tmu5_platform_data = { .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", + .clk = "tmu345_fck", }; static struct resource tmu5_resources[] = { @@ -204,31 +204,37 @@ static struct plat_sci_port sci_platform_data[] = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, + .clk = "scif_fck", }, { .mapbase = 0xffeb0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 44, 44, 44, 44 }, + .clk = "scif_fck", }, { .mapbase = 0xffec0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 60, 60, 60, 60 }, + .clk = "scif_fck", }, { .mapbase = 0xffed0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 61, 61, 61, 61 }, + .clk = "scif_fck", }, { .mapbase = 0xffee0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 62, 62, 62, 62 }, + .clk = "scif_fck", }, { .mapbase = 0xffef0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 63, 63, 63, 63 }, + .clk = "scif_fck", }, { .flags = 0, } -- cgit v1.2.3-70-g09d2 From c94a85746f7bdc13035acdf88c130d7b6fa41bde Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 25 May 2009 08:10:28 +0000 Subject: sh: add shared clock framework frequency table code Add SuperH-specific clock framework helper functions: - clk_rate_table_build() - build cpufreq table from divisors/multipliers - clk_rate_table_round() - use cpufreq table to find matching frequency Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 18 +++++++++++ arch/sh/kernel/cpu/clock.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 64c93cb3d68..60d5d2bc714 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -100,4 +100,22 @@ enum clk_sh_algo_id { IP_N1, }; +struct clk_div_mult_table { + unsigned int *divisors; + unsigned int nr_divisors; + unsigned int *multipliers; + unsigned int nr_multipliers; +}; + +struct cpufreq_frequency_table; +void clk_rate_table_build(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + int nr_freqs, + struct clk_div_mult_table *src_table, + unsigned long *bitmap); + +long clk_rate_table_round(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + unsigned long rate); + #endif /* __ASM_SH_CLOCK_H */ diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 012d23476a7..59764d6c5f4 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,80 @@ static LIST_HEAD(clock_list); static DEFINE_SPINLOCK(clock_lock); static DEFINE_MUTEX(clock_list_sem); +void clk_rate_table_build(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + int nr_freqs, + struct clk_div_mult_table *src_table, + unsigned long *bitmap) +{ + unsigned long mult, div; + unsigned long freq; + int i; + + for (i = 0; i < nr_freqs; i++) { + div = 1; + mult = 1; + + if (src_table->divisors && i < src_table->nr_divisors) + div = src_table->divisors[i]; + + if (src_table->multipliers && i < src_table->nr_multipliers) + mult = src_table->multipliers[i]; + + if (!div || !mult || (bitmap && !test_bit(i, bitmap))) + freq = CPUFREQ_ENTRY_INVALID; + else + freq = clk->parent->rate * mult / div; + + freq_table[i].index = i; + freq_table[i].frequency = freq; + } + + /* Termination entry */ + freq_table[i].index = i; + freq_table[i].frequency = CPUFREQ_TABLE_END; +} + +long clk_rate_table_round(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + unsigned long rate) +{ + unsigned long rate_error, rate_error_prev = ~0UL; + unsigned long rate_best_fit = rate; + unsigned long highest, lowest; + int i; + + highest = lowest = 0; + + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { + unsigned long freq = freq_table[i].frequency; + + if (freq == CPUFREQ_ENTRY_INVALID) + continue; + + if (freq > highest) + highest = freq; + if (freq < lowest) + lowest = freq; + + rate_error = abs(freq - rate); + if (rate_error < rate_error_prev) { + rate_best_fit = freq; + rate_error_prev = rate_error; + } + + if (rate_error == 0) + break; + } + + if (rate >= highest) + rate_best_fit = highest; + if (rate <= lowest) + rate_best_fit = lowest; + + return rate_best_fit; +} + /* Used for clocks that always have same value as the parent clock */ unsigned long followparent_recalc(struct clk *clk) { -- cgit v1.2.3-70-g09d2 From 61ce5393e4c8914c46ec99cbda76823515109709 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 25 May 2009 08:10:45 +0000 Subject: sh: remove clk_ops->build_rate_table() This patch removes the ->build_rate_table() callback, ->recalc() may instead be used for this purpose. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 1 - arch/sh/kernel/cpu/clock.c | 2 -- 2 files changed, 3 deletions(-) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 60d5d2bc714..aa9480d4aa0 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -16,7 +16,6 @@ struct clk_ops { int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); int (*set_parent)(struct clk *clk, struct clk *parent); long (*round_rate)(struct clk *clk, unsigned long rate); - void (*build_rate_table)(struct clk *clk); }; struct clk { diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 59764d6c5f4..aa0fd089358 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -138,8 +138,6 @@ void propagate_rate(struct clk *tclk) list_for_each_entry(clkp, &tclk->children, sibling) { if (clkp->ops && clkp->ops->recalc) clkp->rate = clkp->ops->recalc(clkp); - if (clkp->ops && clkp->ops->build_rate_table) - clkp->ops->build_rate_table(clkp); propagate_rate(clkp); } -- cgit v1.2.3-70-g09d2 From 098dee99d14e8324d3793df442d6078d0c134140 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 4 Jun 2009 05:31:41 +0000 Subject: sh: add enable()/disable()/set_rate() to div6 code This patch updates the div6 clock helper code to add support for enable(), disable() and set_rate() callbacks. Needed by the camera clock enabling board code on Migo-R. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 4 ++++ arch/sh/kernel/cpu/clock-cpg.c | 44 ++++++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/clock.c | 19 ++++++++++++++++++ 3 files changed, 67 insertions(+) (limited to 'arch/sh/kernel/cpu/clock.c') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 026b9daa558..9fe7d7f8af4 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -119,6 +119,10 @@ long clk_rate_table_round(struct clk *clk, struct cpufreq_frequency_table *freq_table, unsigned long rate); +int clk_rate_table_find(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + unsigned long rate); + #define SH_CLK_MSTP32(_name, _id, _parent, _enable_reg, \ _enable_bit, _flags) \ { \ diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index fedc8b84db4..275942e58e4 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -68,9 +68,53 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk) return clk->freq_table[idx].frequency; } +static int sh_clk_div6_set_rate(struct clk *clk, + unsigned long rate, int algo_id) +{ + unsigned long value; + int idx; + + idx = clk_rate_table_find(clk, clk->freq_table, rate); + if (idx < 0) + return idx; + + value = __raw_readl(clk->enable_reg); + value &= ~0x3f; + value |= idx; + __raw_writel(value, clk->enable_reg); + return 0; +} + +static int sh_clk_div6_enable(struct clk *clk) +{ + unsigned long value; + int ret; + + ret = sh_clk_div6_set_rate(clk, clk->rate, 0); + if (ret == 0) { + value = __raw_readl(clk->enable_reg); + value &= ~0x100; /* clear stop bit to enable clock */ + __raw_writel(value, clk->enable_reg); + } + return ret; +} + +static void sh_clk_div6_disable(struct clk *clk) +{ + unsigned long value; + + value = __raw_readl(clk->enable_reg); + value |= 0x100; /* stop clock */ + value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ + __raw_writel(value, clk->enable_reg); +} + static struct clk_ops sh_clk_div6_clk_ops = { .recalc = sh_clk_div6_recalc, .round_rate = sh_clk_div_round_rate, + .set_rate = sh_clk_div6_set_rate, + .enable = sh_clk_div6_enable, + .disable = sh_clk_div6_disable, }; int __init sh_clk_div6_register(struct clk *clks, int nr) diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index aa0fd089358..f3a46be2ae8 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -111,6 +111,25 @@ long clk_rate_table_round(struct clk *clk, return rate_best_fit; } +int clk_rate_table_find(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + unsigned long rate) +{ + int i; + + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { + unsigned long freq = freq_table[i].frequency; + + if (freq == CPUFREQ_ENTRY_INVALID) + continue; + + if (freq == rate) + return i; + } + + return -ENOENT; +} + /* Used for clocks that always have same value as the parent clock */ unsigned long followparent_recalc(struct clk *clk) { -- cgit v1.2.3-70-g09d2