diff options
author | Boris BREZILLON <b.brezillon@overkiz.com> | 2014-03-11 05:00:32 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-03-19 18:21:39 -0400 |
commit | 419f612932674d5f72b1995eda52ca15d87361ef (patch) | |
tree | 21b9bf077747370798922dbffaeb2662c4426d3e /drivers/clk | |
parent | 843bad8361bb0d7e5ed6254c84abd8d2ec61b6a4 (diff) |
clk: at91: replace prog clk round_rate with determine_rate
Implement the determine_rate callback to choose the best parent clk that
fulfills the requested rate.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/at91/clk-programmable.c | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index fd792b203eaf..eff701665f04 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c | |||
@@ -102,40 +102,40 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw, | |||
102 | return parent_rate >> prog->pres; | 102 | return parent_rate >> prog->pres; |
103 | } | 103 | } |
104 | 104 | ||
105 | static long clk_programmable_round_rate(struct clk_hw *hw, unsigned long rate, | 105 | static long clk_programmable_determine_rate(struct clk_hw *hw, |
106 | unsigned long *parent_rate) | 106 | unsigned long rate, |
107 | unsigned long *best_parent_rate, | ||
108 | struct clk **best_parent_clk) | ||
107 | { | 109 | { |
108 | unsigned long best_rate = *parent_rate; | 110 | struct clk *parent = NULL; |
109 | unsigned long best_diff; | 111 | long best_rate = -EINVAL; |
110 | unsigned long new_diff; | 112 | unsigned long parent_rate; |
111 | unsigned long cur_rate; | 113 | unsigned long tmp_rate; |
112 | int shift = shift; | 114 | int shift; |
113 | 115 | int i; | |
114 | if (rate > *parent_rate) | ||
115 | return *parent_rate; | ||
116 | else | ||
117 | best_diff = *parent_rate - rate; | ||
118 | |||
119 | if (!best_diff) | ||
120 | return best_rate; | ||
121 | 116 | ||
122 | for (shift = 1; shift < PROG_PRES_MASK; shift++) { | 117 | for (i = 0; i < __clk_get_num_parents(hw->clk); i++) { |
123 | cur_rate = *parent_rate >> shift; | 118 | parent = clk_get_parent_by_index(hw->clk, i); |
119 | if (!parent) | ||
120 | continue; | ||
124 | 121 | ||
125 | if (cur_rate > rate) | 122 | parent_rate = __clk_get_rate(parent); |
126 | new_diff = cur_rate - rate; | 123 | for (shift = 0; shift < PROG_PRES_MASK; shift++) { |
127 | else | 124 | tmp_rate = parent_rate >> shift; |
128 | new_diff = rate - cur_rate; | 125 | if (tmp_rate <= rate) |
126 | break; | ||
127 | } | ||
129 | 128 | ||
130 | if (!new_diff) | 129 | if (tmp_rate > rate) |
131 | return cur_rate; | 130 | continue; |
132 | 131 | ||
133 | if (new_diff < best_diff) { | 132 | if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) { |
134 | best_diff = new_diff; | 133 | best_rate = tmp_rate; |
135 | best_rate = cur_rate; | 134 | *best_parent_rate = parent_rate; |
135 | *best_parent_clk = parent; | ||
136 | } | 136 | } |
137 | 137 | ||
138 | if (rate > cur_rate) | 138 | if (!best_rate) |
139 | break; | 139 | break; |
140 | } | 140 | } |
141 | 141 | ||
@@ -228,7 +228,7 @@ static const struct clk_ops programmable_ops = { | |||
228 | .prepare = clk_programmable_prepare, | 228 | .prepare = clk_programmable_prepare, |
229 | .is_prepared = clk_programmable_is_ready, | 229 | .is_prepared = clk_programmable_is_ready, |
230 | .recalc_rate = clk_programmable_recalc_rate, | 230 | .recalc_rate = clk_programmable_recalc_rate, |
231 | .round_rate = clk_programmable_round_rate, | 231 | .determine_rate = clk_programmable_determine_rate, |
232 | .get_parent = clk_programmable_get_parent, | 232 | .get_parent = clk_programmable_get_parent, |
233 | .set_parent = clk_programmable_set_parent, | 233 | .set_parent = clk_programmable_set_parent, |
234 | .set_rate = clk_programmable_set_rate, | 234 | .set_rate = clk_programmable_set_rate, |