diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-10-15 05:33:24 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-10-15 05:33:24 -0400 |
commit | 8e122db61c98debbc35e26dd29504958cbcf2cbb (patch) | |
tree | 4323f71c79fd3df0191c6489e84b50089797101f | |
parent | f586903d27e2503a3e7d427b3d665bbaf1b7f4d4 (diff) |
sh: clkfwk: Add a helper for rate rounding by divisor ranges.
This adds a new clk_rate_div_range_round() for implementing rate rounding
by divisor ranges. This can be used trivially by clocks that support
arbitrary ranged divisors without the need for rate table construction.
This should only be used by clocks that both have large divisor ranges in
addition to clocks that will never be arbitrarily scaled, as the lack of
a backing frequency table will prevent cpufreq from being able to do much
of anything with them.
Primarily intended for use as a ->recalc helper.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | drivers/sh/clk.c | 22 | ||||
-rw-r--r-- | include/linux/sh_clk.h | 3 |
2 files changed, 24 insertions, 1 deletions
diff --git a/drivers/sh/clk.c b/drivers/sh/clk.c index 3ac6fa0005b9..018be37ef339 100644 --- a/drivers/sh/clk.c +++ b/drivers/sh/clk.c | |||
@@ -76,7 +76,7 @@ struct clk_rate_round_data; | |||
76 | struct clk_rate_round_data { | 76 | struct clk_rate_round_data { |
77 | unsigned long rate; | 77 | unsigned long rate; |
78 | unsigned int min, max; | 78 | unsigned int min, max; |
79 | long (*func)(unsigned int pos, struct clk_rate_round_data *arg); | 79 | long (*func)(unsigned int, struct clk_rate_round_data *); |
80 | void *arg; | 80 | void *arg; |
81 | }; | 81 | }; |
82 | 82 | ||
@@ -148,6 +148,26 @@ long clk_rate_table_round(struct clk *clk, | |||
148 | return clk_rate_round_helper(&table_round); | 148 | return clk_rate_round_helper(&table_round); |
149 | } | 149 | } |
150 | 150 | ||
151 | static long clk_rate_div_range_iter(unsigned int pos, | ||
152 | struct clk_rate_round_data *rounder) | ||
153 | { | ||
154 | return clk_get_rate(rounder->arg) / pos; | ||
155 | } | ||
156 | |||
157 | long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, | ||
158 | unsigned int div_max, unsigned long rate) | ||
159 | { | ||
160 | struct clk_rate_round_data div_range_round = { | ||
161 | .min = div_min, | ||
162 | .max = div_max, | ||
163 | .func = clk_rate_div_range_iter, | ||
164 | .arg = clk_get_parent(clk), | ||
165 | .rate = rate, | ||
166 | }; | ||
167 | |||
168 | return clk_rate_round_helper(&div_range_round); | ||
169 | } | ||
170 | |||
151 | int clk_rate_table_find(struct clk *clk, | 171 | int clk_rate_table_find(struct clk *clk, |
152 | struct cpufreq_frequency_table *freq_table, | 172 | struct cpufreq_frequency_table *freq_table, |
153 | unsigned long rate) | 173 | unsigned long rate) |
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 49f6e9b6eda2..4dca992f3093 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h | |||
@@ -119,6 +119,9 @@ int clk_rate_table_find(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 | ||
122 | long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, | ||
123 | unsigned int div_max, unsigned long rate); | ||
124 | |||
122 | #define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ | 125 | #define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ |
123 | { \ | 126 | { \ |
124 | .parent = _parent, \ | 127 | .parent = _parent, \ |