@@ -140,42 +140,16 @@ static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw,
140140 AC100_CLKOUT_DIV_WIDTH );
141141}
142142
143- static long ac100_clkout_round_rate (struct clk_hw * hw , unsigned long rate ,
144- unsigned long prate )
145- {
146- unsigned long best_rate = 0 , tmp_rate , tmp_prate ;
147- int i ;
148-
149- if (prate == AC100_RTC_32K_RATE )
150- return divider_round_rate (hw , rate , & prate , NULL ,
151- AC100_CLKOUT_DIV_WIDTH ,
152- CLK_DIVIDER_POWER_OF_TWO );
153-
154- for (i = 0 ; ac100_clkout_prediv [i ].div ; i ++ ) {
155- tmp_prate = DIV_ROUND_UP (prate , ac100_clkout_prediv [i ].val );
156- tmp_rate = divider_round_rate (hw , rate , & tmp_prate , NULL ,
157- AC100_CLKOUT_DIV_WIDTH ,
158- CLK_DIVIDER_POWER_OF_TWO );
159-
160- if (tmp_rate > rate )
161- continue ;
162- if (rate - tmp_rate < best_rate - tmp_rate )
163- best_rate = tmp_rate ;
164- }
165-
166- return best_rate ;
167- }
168-
169143static int ac100_clkout_determine_rate (struct clk_hw * hw ,
170144 struct clk_rate_request * req )
171145{
172- struct clk_hw * best_parent ;
146+ int i , ret , num_parents = clk_hw_get_num_parents (hw );
147+ struct clk_hw * best_parent = NULL ;
173148 unsigned long best = 0 ;
174- int i , num_parents = clk_hw_get_num_parents (hw );
175149
176150 for (i = 0 ; i < num_parents ; i ++ ) {
177151 struct clk_hw * parent = clk_hw_get_parent_by_index (hw , i );
178- unsigned long tmp , prate ;
152+ unsigned long prate ;
179153
180154 /*
181155 * The clock has two parents, one is a fixed clock which is
@@ -199,21 +173,48 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,
199173
200174 prate = clk_hw_get_rate (parent );
201175
202- tmp = ac100_clkout_round_rate (hw , req -> rate , prate );
203-
204- if (tmp > req -> rate )
205- continue ;
206- if (req -> rate - tmp < req -> rate - best ) {
207- best = tmp ;
208- best_parent = parent ;
176+ if (prate == AC100_RTC_32K_RATE ) {
177+ struct clk_rate_request div_req = * req ;
178+
179+ div_req .best_parent_rate = prate ;
180+
181+ ret = divider_determine_rate (hw , & div_req , NULL ,
182+ AC100_CLKOUT_DIV_WIDTH ,
183+ CLK_DIVIDER_POWER_OF_TWO );
184+ if (ret != 0 || div_req .rate > req -> rate ) {
185+ continue ;
186+ } else if (req -> rate - div_req .rate < req -> rate - best ) {
187+ best = div_req .rate ;
188+ best_parent = parent ;
189+ }
190+ } else {
191+ int j ;
192+
193+ for (j = 0 ; ac100_clkout_prediv [j ].div ; j ++ ) {
194+ struct clk_rate_request div_req = * req ;
195+ unsigned long tmp_prate ;
196+
197+ tmp_prate = DIV_ROUND_UP (prate , ac100_clkout_prediv [j ].div );
198+ div_req .best_parent_rate = tmp_prate ;
199+
200+ ret = divider_determine_rate (hw , & div_req , NULL ,
201+ AC100_CLKOUT_DIV_WIDTH ,
202+ CLK_DIVIDER_POWER_OF_TWO );
203+ if (ret != 0 || div_req .rate > req -> rate ) {
204+ continue ;
205+ } else if (req -> rate - div_req .rate < req -> rate - best ) {
206+ best = div_req .rate ;
207+ best_parent = parent ;
208+ }
209+ }
209210 }
210211 }
211212
212213 if (!best )
213214 return - EINVAL ;
214215
215216 req -> best_parent_hw = best_parent ;
216- req -> best_parent_rate = best ;
217+ req -> best_parent_rate = clk_hw_get_rate ( best_parent ) ;
217218 req -> rate = best ;
218219
219220 return 0 ;
0 commit comments