diff options
author | Magnus Damm <damm@igel.co.jp> | 2009-05-25 08:10:36 +0000 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-26 17:08:42 +0900 |
commit | df109e630f82de63ec82eebbfec2a57852517f28 (patch) | |
tree | 5b181c7bb7cfc2b3ab408f95d2f6f124ae1cd07b /arch/sh | |
parent | c94a85746f7bdc13035acdf88c130d7b6fa41bde (diff) |
sh: use shared frequency tables on sh7785
This patch converts the sh7785 clock code to make use
of clk_rate_table_build() and clk_rate_table_round().
The ->build_rate_table() callback is removed, the
table building is instead handled in ->recalc().
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/kernel/cpu/sh4a/clock-sh7785.c | 77 |
1 files changed, 12 insertions, 65 deletions
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 7021ab0bfb8..a4a9bcbec66 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -19,6 +19,12 @@ static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18, 24, 32, 36, 48 }; + +static struct clk_div_mult_table cpg_div = { + .divisors = div2, + .nr_divisors = ARRAY_SIZE(div2), +}; + struct clk_priv { unsigned int shift; @@ -52,82 +58,23 @@ FRQMR_CLK_DATA(ifc, 28, 0x000e); static unsigned long frqmr_recalc(struct clk *clk) { struct clk_priv *data = clk->priv; - unsigned int idx; - - idx = (__raw_readl(FRQMR1) >> data->shift) & 0x000f; - - return clk->parent->rate / 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; + unsigned int idx = (__raw_readl(FRQMR1) >> data->shift) & 0x000f; - data->freq_table[entry].index = entry; - data->freq_table[entry].frequency = - clk->parent->rate / 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; + clk_rate_table_build(clk, data->freq_table, ARRAY_SIZE(div2), + &cpg_div, &data->div_bitmap); + + return data->freq_table[idx].frequency; } 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; + return clk_rate_table_round(clk, data->freq_table, rate); } static struct clk_ops frqmr_clk_ops = { .recalc = frqmr_recalc, - .build_rate_table = frqmr_build_rate_table, .round_rate = frqmr_round_rate, }; |