aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-06-04 01:31:41 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-06-11 02:12:58 -0400
commit098dee99d14e8324d3793df442d6078d0c134140 (patch)
treed2fedbcb58a917bc70a0244bc1da63ec8be97b23 /arch/sh
parentc01641b42a88c475fd4b72cff2b10e42262a80fe (diff)
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 <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/include/asm/clock.h4
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c44
-rw-r--r--arch/sh/kernel/cpu/clock.c19
3 files changed, 67 insertions, 0 deletions
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h
index 026b9daa5584..9fe7d7f8af40 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,
119 struct cpufreq_frequency_table *freq_table, 119 struct cpufreq_frequency_table *freq_table,
120 unsigned long rate); 120 unsigned long rate);
121 121
122int clk_rate_table_find(struct clk *clk,
123 struct cpufreq_frequency_table *freq_table,
124 unsigned long rate);
125
122#define SH_CLK_MSTP32(_name, _id, _parent, _enable_reg, \ 126#define SH_CLK_MSTP32(_name, _id, _parent, _enable_reg, \
123 _enable_bit, _flags) \ 127 _enable_bit, _flags) \
124{ \ 128{ \
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index fedc8b84db4c..275942e58e4f 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)
68 return clk->freq_table[idx].frequency; 68 return clk->freq_table[idx].frequency;
69} 69}
70 70
71static int sh_clk_div6_set_rate(struct clk *clk,
72 unsigned long rate, int algo_id)
73{
74 unsigned long value;
75 int idx;
76
77 idx = clk_rate_table_find(clk, clk->freq_table, rate);
78 if (idx < 0)
79 return idx;
80
81 value = __raw_readl(clk->enable_reg);
82 value &= ~0x3f;
83 value |= idx;
84 __raw_writel(value, clk->enable_reg);
85 return 0;
86}
87
88static int sh_clk_div6_enable(struct clk *clk)
89{
90 unsigned long value;
91 int ret;
92
93 ret = sh_clk_div6_set_rate(clk, clk->rate, 0);
94 if (ret == 0) {
95 value = __raw_readl(clk->enable_reg);
96 value &= ~0x100; /* clear stop bit to enable clock */
97 __raw_writel(value, clk->enable_reg);
98 }
99 return ret;
100}
101
102static void sh_clk_div6_disable(struct clk *clk)
103{
104 unsigned long value;
105
106 value = __raw_readl(clk->enable_reg);
107 value |= 0x100; /* stop clock */
108 value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
109 __raw_writel(value, clk->enable_reg);
110}
111
71static struct clk_ops sh_clk_div6_clk_ops = { 112static struct clk_ops sh_clk_div6_clk_ops = {
72 .recalc = sh_clk_div6_recalc, 113 .recalc = sh_clk_div6_recalc,
73 .round_rate = sh_clk_div_round_rate, 114 .round_rate = sh_clk_div_round_rate,
115 .set_rate = sh_clk_div6_set_rate,
116 .enable = sh_clk_div6_enable,
117 .disable = sh_clk_div6_disable,
74}; 118};
75 119
76int __init sh_clk_div6_register(struct clk *clks, int nr) 120int __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 aa0fd0893585..f3a46be2ae81 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,
111 return rate_best_fit; 111 return rate_best_fit;
112} 112}
113 113
114int clk_rate_table_find(struct clk *clk,
115 struct cpufreq_frequency_table *freq_table,
116 unsigned long rate)
117{
118 int i;
119
120 for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
121 unsigned long freq = freq_table[i].frequency;
122
123 if (freq == CPUFREQ_ENTRY_INVALID)
124 continue;
125
126 if (freq == rate)
127 return i;
128 }
129
130 return -ENOENT;
131}
132
114/* Used for clocks that always have same value as the parent clock */ 133/* Used for clocks that always have same value as the parent clock */
115unsigned long followparent_recalc(struct clk *clk) 134unsigned long followparent_recalc(struct clk *clk)
116{ 135{