From: Stephen Boyd <sboyd@xxxxxxxxxx> We'll need to turn the code in clk_mux_determine_rate_flags() to deal with CLK_SET_RATE_NO_REPARENT into a helper clock drivers will be able to use if they don't want to allow reparenting. Cc: Abel Vesa <abelvesa@xxxxxxxxxx> Cc: Alessandro Zummo <a.zummo@xxxxxxxxxxxx> Cc: Alexandre Belloni <alexandre.belloni@xxxxxxxxxxx> Cc: Alexandre Torgue <alexandre.torgue@xxxxxxxxxxx> Cc: "Andreas Färber" <afaerber@xxxxxxx> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@xxxxxxxxxxxxx> Cc: Baolin Wang <baolin.wang@xxxxxxxxxxxxxxxxx> Cc: Charles Keepax <ckeepax@xxxxxxxxxxxxxxxxxxxxx> Cc: Chen-Yu Tsai <wens@xxxxxxxx> Cc: Chen-Yu Tsai <wenst@xxxxxxxxxxxx> Cc: Chunyan Zhang <zhang.lyra@xxxxxxxxx> Cc: Claudiu Beznea <claudiu.beznea@xxxxxxxxxxxxx> Cc: Daniel Vetter <daniel@xxxxxxxx> Cc: David Airlie <airlied@xxxxxxxxx> Cc: David Lechner <david@xxxxxxxxxxxxxx> Cc: Dinh Nguyen <dinguyen@xxxxxxxxxx> Cc: Fabio Estevam <festevam@xxxxxxxxx> Cc: Geert Uytterhoeven <geert+renesas@xxxxxxxxx> Cc: Jaroslav Kysela <perex@xxxxxxxx> Cc: Jernej Skrabec <jernej.skrabec@xxxxxxxxx> Cc: Jonathan Hunter <jonathanh@xxxxxxxxxx> Cc: Kishon Vijay Abraham I <kishon@xxxxxxxxxx> Cc: Liam Girdwood <lgirdwood@xxxxxxxxx> Cc: Linus Walleij <linus.walleij@xxxxxxxxxx> Cc: Luca Ceresoli <luca.ceresoli@xxxxxxxxxxx> Cc: Manivannan Sadhasivam <mani@xxxxxxxxxx> Cc: Mark Brown <broonie@xxxxxxxxxx> Cc: Markus Schneider-Pargmann <msp@xxxxxxxxxxxx> Cc: Max Filippov <jcmvbkbc@xxxxxxxxx> Cc: Maxime Coquelin <mcoquelin.stm32@xxxxxxxxx> Cc: Mikko Perttunen <mperttunen@xxxxxxxxxx> Cc: Miles Chen <miles.chen@xxxxxxxxxxxx> Cc: Nicolas Ferre <nicolas.ferre@xxxxxxxxxxxxx> Cc: Orson Zhai <orsonzhai@xxxxxxxxx> Cc: Paul Cercueil <paul@xxxxxxxxxxxxxxx> Cc: Peng Fan <peng.fan@xxxxxxx> Cc: Peter De Schrijver <pdeschrijver@xxxxxxxxxx> Cc: Prashant Gaikwad <pgaikwad@xxxxxxxxxx> Cc: Richard Fitzgerald <rf@xxxxxxxxxxxxxxxxxxxxx> Cc: Samuel Holland <samuel@xxxxxxxxxxxx> Cc: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> Cc: Sekhar Nori <nsekhar@xxxxxx> Cc: Shawn Guo <shawnguo@xxxxxxxxxx> Cc: Takashi Iwai <tiwai@xxxxxxxx> Cc: Thierry Reding <thierry.reding@xxxxxxxxx> Cc: Ulf Hansson <ulf.hansson@xxxxxxxxxx> Cc: Vinod Koul <vkoul@xxxxxxxxxx> Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx Cc: linux-actions@xxxxxxxxxxxxxxxxxxx Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx Cc: linux-mips@xxxxxxxxxxxxxxx Cc: linux-phy@xxxxxxxxxxxxxxxxxxx Cc: linux-renesas-soc@xxxxxxxxxxxxxxx Cc: linux-rtc@xxxxxxxxxxxxxxx Cc: linux-stm32@xxxxxxxxxxxxxxxxxxxxxxxxxxxx Cc: linux-sunxi@xxxxxxxxxxxxxxx Cc: linux-tegra@xxxxxxxxxxxxxxx Cc: NXP Linux Team <linux-imx@xxxxxxx> Cc: patches@xxxxxxxxxxxxxxxxxxxxx Cc: Pengutronix Kernel Team <kernel@xxxxxxxxxxxxxx> Signed-off-by: Stephen Boyd <sboyd@xxxxxxxxxx> Signed-off-by: Maxime Ripard <maxime@xxxxxxxxxx> --- drivers/clk/clk.c | 75 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index e495dd7a1eae..f57f821a5e5a 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -594,6 +594,46 @@ clk_core_forward_rate_req(struct clk_core *core, req->max_rate = old_req->max_rate; } +static int +clk_core_determine_rate_no_reparent(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_core *core = hw->core; + struct clk_core *parent = core->parent; + unsigned long best; + int ret; + + if (core->flags & CLK_SET_RATE_PARENT) { + struct clk_rate_request parent_req; + + if (!parent) { + req->rate = 0; + return 0; + } + + clk_core_forward_rate_req(core, req, parent, &parent_req, + req->rate); + + trace_clk_rate_request_start(&parent_req); + + ret = clk_core_round_rate_nolock(parent, &parent_req); + if (ret) + return ret; + + trace_clk_rate_request_done(&parent_req); + + best = parent_req.rate; + } else if (parent) { + best = clk_core_get_rate_nolock(parent); + } else { + best = clk_core_get_rate_nolock(core); + } + + req->rate = best; + + return 0; +} + int clk_mux_determine_rate_flags(struct clk_hw *hw, struct clk_rate_request *req, unsigned long flags) @@ -603,35 +643,8 @@ int clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long best = 0; /* if NO_REPARENT flag set, pass through to current parent */ - if (core->flags & CLK_SET_RATE_NO_REPARENT) { - parent = core->parent; - if (core->flags & CLK_SET_RATE_PARENT) { - struct clk_rate_request parent_req; - - if (!parent) { - req->rate = 0; - return 0; - } - - clk_core_forward_rate_req(core, req, parent, &parent_req, req->rate); - - trace_clk_rate_request_start(&parent_req); - - ret = clk_core_round_rate_nolock(parent, &parent_req); - if (ret) - return ret; - - trace_clk_rate_request_done(&parent_req); - - best = parent_req.rate; - } else if (parent) { - best = clk_core_get_rate_nolock(parent); - } else { - best = clk_core_get_rate_nolock(core); - } - - goto out; - } + if (core->flags & CLK_SET_RATE_NO_REPARENT) + return clk_core_determine_rate_no_reparent(hw, req); /* find the parent that can provide the fastest rate <= rate */ num_parents = core->num_parents; @@ -670,9 +683,7 @@ int clk_mux_determine_rate_flags(struct clk_hw *hw, if (!best_parent) return -EINVAL; -out: - if (best_parent) - req->best_parent_hw = best_parent->hw; + req->best_parent_hw = best_parent->hw; req->best_parent_rate = best; req->rate = best; -- 2.40.0