[PATCH v2 04/11] clk: use round rate to bail out early in set_rate
Michael Turquette
mturquette at baylibre.com
Thu May 25 13:20:50 PDT 2017
Quoting Jerome Brunet (2017-05-21 14:59:51)
> The current implementation of clk_core_set_rate_nolock bails out early if
> the requested rate is exactly the same as the one set. It should bail out
> if the request would not result in rate a change. This important when rate
> is not exactly what is requested, which is fairly common with PLLs.
>
> Ex: provider able to give any rate with steps of 100Hz
> - 1st consumer request 48000Hz and gets it.
> - 2nd consumer request 48010Hz as well. If we were to perform the usual
> mechanism, we would get 48000Hz as well. The clock would not change so
> there is no point performing any checks to make sure the clock can
> change, we know it won't.
>
> This is important to prepare the addition of the clock protection mechanism
Why is this change necessary for the rate_protect feature? I don't see a
major problem with it, but not sure I want to change the expected
behavior unless it is required.
Thanks,
Mike
>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
> drivers/clk/clk.c | 23 +++++++++++++++++++++--
> 1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 100f72472e10..1a8c0d013238 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -1570,15 +1570,34 @@ static void clk_change_rate(struct clk_core *core)
> clk_change_rate(core->new_child);
> }
>
> +static unsigned long clk_core_req_round_rate_nolock(struct clk_core *core,
> + unsigned long req_rate)
> +{
> + int ret;
> + struct clk_rate_request req;
> +
> + if (!core)
> + return 0;
> +
> + clk_core_get_boundaries(core, &req.min_rate, &req.max_rate);
> + req.rate = req_rate;
> +
> + ret = clk_core_round_rate_nolock(core, &req);
> +
> + return ret ? 0 : req.rate;
> +}
> +
> static int clk_core_set_rate_nolock(struct clk_core *core,
> unsigned long req_rate)
> {
> struct clk_core *top, *fail_clk;
> - unsigned long rate = req_rate;
> + unsigned long rate;
>
> if (!core)
> return 0;
>
> + rate = clk_core_req_round_rate_nolock(core, req_rate);
> +
> /* bail early if nothing to do */
> if (rate == clk_core_get_rate_nolock(core))
> return 0;
> @@ -1587,7 +1606,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
> return -EBUSY;
>
> /* calculate new rates and get the topmost changed clock */
> - top = clk_calc_new_rates(core, rate);
> + top = clk_calc_new_rates(core, req_rate);
> if (!top)
> return -EINVAL;
>
> --
> 2.9.4
>
More information about the linux-amlogic
mailing list