@@ -164,81 +164,111 @@ static int rate_cmp_func(const void *_r1, const void *_r2)
164164 return 1 ;
165165}
166166
167- static int
168- scmi_clock_describe_rates_get (const struct scmi_protocol_handle * ph , u32 clk_id ,
169- struct scmi_clock_info * clk )
170- {
171- u64 * rate = NULL ;
172- int ret , cnt ;
173- bool rate_discrete = false;
174- u32 tot_rate_cnt = 0 , rates_flag ;
175- u16 num_returned , num_remaining ;
176- struct scmi_xfer * t ;
177- struct scmi_msg_clock_describe_rates * clk_desc ;
178- struct scmi_msg_resp_clock_describe_rates * rlist ;
167+ struct scmi_clk_ipriv {
168+ u32 clk_id ;
169+ struct scmi_clock_info * clk ;
170+ };
179171
180- ret = ph -> xops -> xfer_get_init (ph , CLOCK_DESCRIBE_RATES ,
181- sizeof (* clk_desc ), 0 , & t );
182- if (ret )
183- return ret ;
172+ static void iter_clk_describe_prepare_message (void * message ,
173+ const unsigned int desc_index ,
174+ const void * priv )
175+ {
176+ struct scmi_msg_clock_describe_rates * msg = message ;
177+ const struct scmi_clk_ipriv * p = priv ;
184178
185- clk_desc = t -> tx .buf ;
186- rlist = t -> rx .buf ;
179+ msg -> id = cpu_to_le32 (p -> clk_id );
180+ /* Set the number of rates to be skipped/already read */
181+ msg -> rate_index = cpu_to_le32 (desc_index );
182+ }
187183
188- do {
189- clk_desc -> id = cpu_to_le32 (clk_id );
190- /* Set the number of rates to be skipped/already read */
191- clk_desc -> rate_index = cpu_to_le32 (tot_rate_cnt );
184+ static int
185+ iter_clk_describe_update_state (struct scmi_iterator_state * st ,
186+ const void * response , void * priv )
187+ {
188+ u32 flags ;
189+ struct scmi_clk_ipriv * p = priv ;
190+ const struct scmi_msg_resp_clock_describe_rates * r = response ;
192191
193- ret = ph -> xops -> do_xfer (ph , t );
194- if (ret )
195- goto err ;
192+ flags = le32_to_cpu (r -> num_rates_flags );
193+ st -> num_remaining = NUM_REMAINING (flags );
194+ st -> num_returned = NUM_RETURNED (flags );
195+ p -> clk -> rate_discrete = RATE_DISCRETE (flags );
196196
197- rates_flag = le32_to_cpu (rlist -> num_rates_flags );
198- num_remaining = NUM_REMAINING (rates_flag );
199- rate_discrete = RATE_DISCRETE (rates_flag );
200- num_returned = NUM_RETURNED (rates_flag );
197+ return 0 ;
198+ }
201199
202- if (tot_rate_cnt + num_returned > SCMI_MAX_NUM_RATES ) {
203- dev_err (ph -> dev , "No. of rates > MAX_NUM_RATES" );
200+ static int
201+ iter_clk_describe_process_response (const struct scmi_protocol_handle * ph ,
202+ const void * response ,
203+ struct scmi_iterator_state * st , void * priv )
204+ {
205+ int ret = 0 ;
206+ struct scmi_clk_ipriv * p = priv ;
207+ const struct scmi_msg_resp_clock_describe_rates * r = response ;
208+
209+ if (!p -> clk -> rate_discrete ) {
210+ switch (st -> desc_index + st -> loop_idx ) {
211+ case 0 :
212+ p -> clk -> range .min_rate = RATE_TO_U64 (r -> rate [0 ]);
204213 break ;
205- }
206-
207- if (!rate_discrete ) {
208- clk -> range .min_rate = RATE_TO_U64 (rlist -> rate [0 ]);
209- clk -> range .max_rate = RATE_TO_U64 (rlist -> rate [1 ]);
210- clk -> range .step_size = RATE_TO_U64 (rlist -> rate [2 ]);
211- dev_dbg (ph -> dev , "Min %llu Max %llu Step %llu Hz\n" ,
212- clk -> range .min_rate , clk -> range .max_rate ,
213- clk -> range .step_size );
214+ case 1 :
215+ p -> clk -> range .max_rate = RATE_TO_U64 (r -> rate [1 ]);
216+ break ;
217+ case 2 :
218+ p -> clk -> range .step_size = RATE_TO_U64 (r -> rate [2 ]);
219+ break ;
220+ default :
221+ ret = - EINVAL ;
214222 break ;
215223 }
224+ } else {
225+ u64 * rate = & p -> clk -> list .rates [st -> desc_index + st -> loop_idx ];
216226
217- rate = & clk -> list .rates [tot_rate_cnt ];
218- for (cnt = 0 ; cnt < num_returned ; cnt ++ , rate ++ ) {
219- * rate = RATE_TO_U64 (rlist -> rate [cnt ]);
220- dev_dbg (ph -> dev , "Rate %llu Hz\n" , * rate );
221- }
227+ * rate = RATE_TO_U64 (r -> rate [st -> loop_idx ]);
228+ p -> clk -> list .num_rates ++ ;
229+ //XXX dev_dbg(ph->dev, "Rate %llu Hz\n", *rate);
230+ }
231+
232+ return ret ;
233+ }
222234
223- tot_rate_cnt += num_returned ;
235+ static int
236+ scmi_clock_describe_rates_get (const struct scmi_protocol_handle * ph , u32 clk_id ,
237+ struct scmi_clock_info * clk )
238+ {
239+ int ret ;
224240
225- ph -> xops -> reset_rx_to_maxsz (ph , t );
226- /*
227- * check for both returned and remaining to avoid infinite
228- * loop due to buggy firmware
229- */
230- } while (num_returned && num_remaining );
241+ void * iter ;
242+ struct scmi_msg_clock_describe_rates * msg ;
243+ struct scmi_iterator_ops ops = {
244+ .prepare_message = iter_clk_describe_prepare_message ,
245+ .update_state = iter_clk_describe_update_state ,
246+ .process_response = iter_clk_describe_process_response ,
247+ };
248+ struct scmi_clk_ipriv cpriv = {
249+ .clk_id = clk_id ,
250+ .clk = clk ,
251+ };
252+
253+ iter = ph -> hops -> iter_response_init (ph , & ops , SCMI_MAX_NUM_RATES ,
254+ CLOCK_DESCRIBE_RATES ,
255+ sizeof (* msg ), & cpriv );
256+ if (IS_ERR (iter ))
257+ return PTR_ERR (iter );
258+
259+ ret = ph -> hops -> iter_response_run (iter );
260+ if (ret )
261+ return ret ;
231262
232- if (rate_discrete && rate ) {
233- clk -> list .num_rates = tot_rate_cnt ;
234- sort (clk -> list .rates , tot_rate_cnt , sizeof (* rate ),
235- rate_cmp_func , NULL );
263+ if (!clk -> rate_discrete ) {
264+ dev_dbg (ph -> dev , "Min %llu Max %llu Step %llu Hz\n" ,
265+ clk -> range .min_rate , clk -> range .max_rate ,
266+ clk -> range .step_size );
267+ } else if (clk -> list .num_rates ) {
268+ sort (clk -> list .rates , clk -> list .num_rates ,
269+ sizeof (clk -> list .rates [0 ]), rate_cmp_func , NULL );
236270 }
237271
238- clk -> rate_discrete = rate_discrete ;
239-
240- err :
241- ph -> xops -> xfer_put (ph , t );
242272 return ret ;
243273}
244274
0 commit comments