aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Schulz <quentin.schulz@free-electrons.com>2017-08-10 02:34:04 -0400
committerStephen Boyd <sboyd@codeaurora.org>2017-09-01 18:46:53 -0400
commit8a8f4bf0c48055f0648b5449f4685b6cd0fc1c85 (patch)
tree925f18e24acecef715ed485e7a5f76d074ac13ad
parent0865805d82d4c822647ee35ab2629c48cc40706b (diff)
clk: at91: clk-generated: create function to find best_diff
The way to find the best_diff and do the appropriate process afterwards can be re-used. This patch prepares the driver for an upcoming patch that will allow clk_generated to determine the rate of the audio_pll. Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com> Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-rw-r--r--drivers/clk/at91/clk-generated.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index ef4b4e03de04..7260e498e059 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -99,15 +99,36 @@ clk_generated_recalc_rate(struct clk_hw *hw,
99 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); 99 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1);
100} 100}
101 101
102static void clk_generated_best_diff(struct clk_rate_request *req,
103 struct clk_hw *parent,
104 unsigned long parent_rate, u32 div,
105 int *best_diff, long *best_rate)
106{
107 unsigned long tmp_rate;
108 int tmp_diff;
109
110 if (!div)
111 tmp_rate = parent_rate;
112 else
113 tmp_rate = parent_rate / div;
114 tmp_diff = abs(req->rate - tmp_rate);
115
116 if (*best_diff < 0 || *best_diff > tmp_diff) {
117 *best_rate = tmp_rate;
118 *best_diff = tmp_diff;
119 req->best_parent_rate = parent_rate;
120 req->best_parent_hw = parent;
121 }
122}
123
102static int clk_generated_determine_rate(struct clk_hw *hw, 124static int clk_generated_determine_rate(struct clk_hw *hw,
103 struct clk_rate_request *req) 125 struct clk_rate_request *req)
104{ 126{
105 struct clk_generated *gck = to_clk_generated(hw); 127 struct clk_generated *gck = to_clk_generated(hw);
106 struct clk_hw *parent = NULL; 128 struct clk_hw *parent = NULL;
107 long best_rate = -EINVAL; 129 long best_rate = -EINVAL;
108 unsigned long tmp_rate, min_rate; 130 unsigned long min_rate;
109 int best_diff = -1; 131 int best_diff = -1;
110 int tmp_diff;
111 int i; 132 int i;
112 133
113 for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 134 for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
@@ -125,18 +146,10 @@ static int clk_generated_determine_rate(struct clk_hw *hw,
125 continue; 146 continue;
126 147
127 div = DIV_ROUND_CLOSEST(parent_rate, req->rate); 148 div = DIV_ROUND_CLOSEST(parent_rate, req->rate);
128 if (!div) 149
129 tmp_rate = parent_rate; 150 clk_generated_best_diff(req, parent, parent_rate, div,
130 else 151 &best_diff, &best_rate);
131 tmp_rate = parent_rate / div; 152
132 tmp_diff = abs(req->rate - tmp_rate);
133
134 if (best_diff < 0 || best_diff > tmp_diff) {
135 best_rate = tmp_rate;
136 best_diff = tmp_diff;
137 req->best_parent_rate = parent_rate;
138 req->best_parent_hw = parent;
139 }
140 153
141 if (!best_diff) 154 if (!best_diff)
142 break; 155 break;