Using clock rate protection, we can now enforce CLK_SET_RATE_GATE along the clock tree
Acked-by: Linus Walleij <[email protected]> Tested-by: Quentin Schulz <[email protected]> Signed-off-by: Jerome Brunet <[email protected]> --- drivers/clk/clk.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 4693d5e20327..f990ef127a83 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -552,6 +552,9 @@ static void clk_core_unprepare(struct clk_core *core) if (WARN_ON(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL)) return; + if (core->flags & CLK_SET_RATE_GATE) + clk_core_rate_unprotect(core); + if (--core->prepare_count > 0) return; @@ -622,6 +625,16 @@ static int clk_core_prepare(struct clk_core *core) core->prepare_count++; + /* + * CLK_SET_RATE_GATE is a special case of clock protection + * Instead of a consumer claiming exclusive rate control, it is + * actually the provider which prevents any consumer from making any + * operation which could result in a rate change or rate glitch while + * the clock is prepared. + */ + if (core->flags & CLK_SET_RATE_GATE) + clk_core_rate_protect(core); + return 0; } @@ -1703,9 +1716,6 @@ static int clk_core_set_rate_nolock(struct clk_core *core, if (clk_core_rate_is_protected(core)) return -EBUSY; - if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count) - return -EBUSY; - /* calculate new rates and get the topmost changed clock */ top = clk_calc_new_rates(core, req_rate); if (!top) -- 2.13.5

