diff options
Diffstat (limited to 'drivers/sh/clk/cpg.c')
-rw-r--r-- | drivers/sh/clk/cpg.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index f0d015dd0fef..9dea32907795 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c | |||
@@ -71,6 +71,22 @@ static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) | |||
71 | return clk_rate_table_round(clk, clk->freq_table, rate); | 71 | return clk_rate_table_round(clk, clk->freq_table, rate); |
72 | } | 72 | } |
73 | 73 | ||
74 | /* | ||
75 | * Div/mult table lookup helpers | ||
76 | */ | ||
77 | static inline struct clk_div_table *clk_to_div_table(struct clk *clk) | ||
78 | { | ||
79 | return clk->priv; | ||
80 | } | ||
81 | |||
82 | static inline struct clk_div_mult_table *clk_to_div_mult_table(struct clk *clk) | ||
83 | { | ||
84 | return clk_to_div_table(clk)->div_mult_table; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * div6 support | ||
89 | */ | ||
74 | static int sh_clk_div6_divisors[64] = { | 90 | static int sh_clk_div6_divisors[64] = { |
75 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, | 91 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, |
76 | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, | 92 | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, |
@@ -78,14 +94,18 @@ static int sh_clk_div6_divisors[64] = { | |||
78 | 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 | 94 | 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 |
79 | }; | 95 | }; |
80 | 96 | ||
81 | static struct clk_div_mult_table sh_clk_div6_table = { | 97 | static struct clk_div_mult_table div6_div_mult_table = { |
82 | .divisors = sh_clk_div6_divisors, | 98 | .divisors = sh_clk_div6_divisors, |
83 | .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), | 99 | .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), |
84 | }; | 100 | }; |
85 | 101 | ||
102 | static struct clk_div_table sh_clk_div6_table = { | ||
103 | .div_mult_table = &div6_div_mult_table, | ||
104 | }; | ||
105 | |||
86 | static unsigned long sh_clk_div6_recalc(struct clk *clk) | 106 | static unsigned long sh_clk_div6_recalc(struct clk *clk) |
87 | { | 107 | { |
88 | struct clk_div_mult_table *table = &sh_clk_div6_table; | 108 | struct clk_div_mult_table *table = clk_to_div_mult_table(clk); |
89 | unsigned int idx; | 109 | unsigned int idx; |
90 | 110 | ||
91 | clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, | 111 | clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, |
@@ -98,7 +118,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk) | |||
98 | 118 | ||
99 | static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) | 119 | static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) |
100 | { | 120 | { |
101 | struct clk_div_mult_table *table = &sh_clk_div6_table; | 121 | struct clk_div_mult_table *table = clk_to_div_mult_table(clk); |
102 | u32 value; | 122 | u32 value; |
103 | int ret, i; | 123 | int ret, i; |
104 | 124 | ||
@@ -223,7 +243,8 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, | |||
223 | { | 243 | { |
224 | struct clk *clkp; | 244 | struct clk *clkp; |
225 | void *freq_table; | 245 | void *freq_table; |
226 | int nr_divs = sh_clk_div6_table.nr_divisors; | 246 | struct clk_div_table *table = &sh_clk_div6_table; |
247 | int nr_divs = table->div_mult_table->nr_divisors; | ||
227 | int freq_table_size = sizeof(struct cpufreq_frequency_table); | 248 | int freq_table_size = sizeof(struct cpufreq_frequency_table); |
228 | int ret = 0; | 249 | int ret = 0; |
229 | int k; | 250 | int k; |
@@ -239,6 +260,7 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, | |||
239 | clkp = clks + k; | 260 | clkp = clks + k; |
240 | 261 | ||
241 | clkp->ops = ops; | 262 | clkp->ops = ops; |
263 | clkp->priv = table; | ||
242 | clkp->freq_table = freq_table + (k * freq_table_size); | 264 | clkp->freq_table = freq_table + (k * freq_table_size); |
243 | clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; | 265 | clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; |
244 | ret = clk_register(clkp); | 266 | ret = clk_register(clkp); |
@@ -262,10 +284,12 @@ int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) | |||
262 | &sh_clk_div6_reparent_clk_ops); | 284 | &sh_clk_div6_reparent_clk_ops); |
263 | } | 285 | } |
264 | 286 | ||
287 | /* | ||
288 | * div4 support | ||
289 | */ | ||
265 | static unsigned long sh_clk_div4_recalc(struct clk *clk) | 290 | static unsigned long sh_clk_div4_recalc(struct clk *clk) |
266 | { | 291 | { |
267 | struct clk_div4_table *d4t = clk->priv; | 292 | struct clk_div_mult_table *table = clk_to_div_mult_table(clk); |
268 | struct clk_div_mult_table *table = d4t->div_mult_table; | ||
269 | unsigned int idx; | 293 | unsigned int idx; |
270 | 294 | ||
271 | clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, | 295 | clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, |
@@ -278,8 +302,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk) | |||
278 | 302 | ||
279 | static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) | 303 | static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) |
280 | { | 304 | { |
281 | struct clk_div4_table *d4t = clk->priv; | 305 | struct clk_div_mult_table *table = clk_to_div_mult_table(clk); |
282 | struct clk_div_mult_table *table = d4t->div_mult_table; | ||
283 | u32 value; | 306 | u32 value; |
284 | int ret; | 307 | int ret; |
285 | 308 | ||
@@ -308,7 +331,7 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) | |||
308 | 331 | ||
309 | static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) | 332 | static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) |
310 | { | 333 | { |
311 | struct clk_div4_table *d4t = clk->priv; | 334 | struct clk_div_table *dt = clk_to_div_table(clk); |
312 | unsigned long value; | 335 | unsigned long value; |
313 | int idx = clk_rate_table_find(clk, clk->freq_table, rate); | 336 | int idx = clk_rate_table_find(clk, clk->freq_table, rate); |
314 | if (idx < 0) | 337 | if (idx < 0) |
@@ -319,8 +342,9 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) | |||
319 | value |= (idx << clk->enable_bit); | 342 | value |= (idx << clk->enable_bit); |
320 | sh_clk_write(value, clk); | 343 | sh_clk_write(value, clk); |
321 | 344 | ||
322 | if (d4t->kick) | 345 | /* XXX: Should use a post-change notifier */ |
323 | d4t->kick(clk); | 346 | if (dt->kick) |
347 | dt->kick(clk); | ||
324 | 348 | ||
325 | return 0; | 349 | return 0; |
326 | } | 350 | } |