From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AFFD22F31 for ; Thu, 13 Apr 2023 21:44:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3797CC433EF; Thu, 13 Apr 2023 21:44:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1681422293; bh=wyjwIC3Cy5WU+viRyzdkyHAzNFXM1r3VuLYgpEtI3OQ=; h=In-Reply-To:References:Subject:From:Cc:To:Date:From; b=ACV4dJc7m/PMzJd0ORQurNYPYOMbHI+ezUMpAoVoLD2TcxTUalLqPPpJtALsZLeJb BEtZnCJtUIXD5CjbK+1ClFdZLc9eYqceaGYzSoahVJ/K6U5Aqf5YdcIP6GD4IilsQy dOy90zE7iEAJsisMRAMzA8TlO0S4VUEDMAW+DQAGiLu6DsW4HfAofVliB7kfC66oXd bbj+fJFaUkhS5O0TxxeJAwkCGx8Ir3/wHoxVeBqkAidrJasFoYZXcdVIM9nFZylroG mG6SePWOiq8owicG2JA4Ofq34WhZ4YzrrwxsaPqUu34tWKggJKtoTrm1XL9ZdW3VFY +M7eEYKNKhrog== Message-ID: <636b8f855b6009ba068010e00c20e7f5.sboyd@kernel.org> Content-Type: text/plain; charset="utf-8" Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable In-Reply-To: <20221018-clk-range-checks-fixes-v3-0-9a1358472d52@cerno.tech> References: <20221018-clk-range-checks-fixes-v3-0-9a1358472d52@cerno.tech> Subject: Re: [PATCH v3 00/65] clk: Make determine_rate mandatory for muxes From: Stephen Boyd Cc: linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , linux-arm-kernel@lists.infradead.org, linux-actions@lists.infradead.org, patches@opensource.cirrus.com, linux-stm32@st-md-mailman.stormreply.com, linux-mediatek@lists.infradead.org, linux-renesas-soc@vger.kernel.org, linux-tegra@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-phy@lists.infradead.org, linux-rtc@vger.kernel.org, linux-sunxi@lists.linux.dev, alsa-devel@alsa-project.org, linux-mips@vger.kernel.org, Maxime Ripard , Liam Beguin To: Abel Vesa , Alessandro Zummo , Alexandre Belloni , Alexandre Torgue , Andreas =?utf-8?q?F=C3=A4rber?= , Baolin Wang , Charles Keepax , Chen-Yu Tsai , Chunyan Zhang , Claudiu Beznea , Daniel Vetter , David Airlie , David Lechner , Dinh Nguyen , Fabio Estevam , Geert Uytterhoeven , Jaroslav Kysela , Jernej Skrabec , Jonathan Hunter , Kishon Vijay Abraham I , Liam Girdwood , Linus Walleij , Luca Ceresoli , Manivannan Sadhasivam , Mark Brown
, Matthias Brugger , Max Filippov , Maxime Coquelin , Maxime Ripard , Michael Turquette , NXP Linux Team , Nicolas Ferre , Orson Zhai , Paul Cercueil , Pengutronix Kernel Team , Peter De Schrijver , Prashant Gaikwad , Richard Fitzgerald , Samuel Holland , Sascha Hauer , Sekhar Nori , Shawn Guo , Takashi Iwai , Thierry Reding , Ulf Hansson , Vinod Koul Date: Thu, 13 Apr 2023 14:44:51 -0700 User-Agent: alot/0.10 Quoting Maxime Ripard (2023-04-04 03:10:50) > Hi, >=20 > This is a follow-up to a previous series that was printing a warning > when a mux has a set_parent implementation but is missing > determine_rate(). >=20 > The rationale is that set_parent() is very likely to be useful when > changing the rate, but it's determine_rate() that takes the parenting > decision. If we're missing it, then the current parent is always going > to be used, and thus set_parent() will not be used. The only exception > being a direct call to clk_set_parent(), but those are fairly rare > compared to clk_set_rate(). >=20 > Stephen then asked to promote the warning to an error, and to fix up all > the muxes that are in that situation first. So here it is :) >=20 Thanks for resending. I was thinking that we apply this patch first and then set determine_rate clk_ops without setting the clk flag. The function name is up for debate. ---8<--- diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 27c30a533759..057dd3ca8920 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -594,45 +594,57 @@ clk_core_forward_rate_req(struct clk_core *core, req->max_rate =3D old_req->max_rate; } =20 -int clk_mux_determine_rate_flags(struct clk_hw *hw, - struct clk_rate_request *req, - unsigned long flags) +static int +clk_core_determine_rate_noreparent(struct clk_core *core, + struct clk_rate_request *req) { - struct clk_core *core =3D hw->core, *parent, *best_parent =3D NULL; - int i, num_parents, ret; + struct clk_core *parent; + int ret; unsigned long best =3D 0; =20 - /* if NO_REPARENT flag set, pass through to current parent */ - if (core->flags & CLK_SET_RATE_NO_REPARENT) { - parent =3D core->parent; - if (core->flags & CLK_SET_RATE_PARENT) { - struct clk_rate_request parent_req; - - if (!parent) { - req->rate =3D 0; - return 0; - } + parent =3D core->parent; + if (core->flags & CLK_SET_RATE_PARENT) { + struct clk_rate_request parent_req; =20 - clk_core_forward_rate_req(core, req, parent, &parent_req, req->rate); + if (!parent) { + req->rate =3D 0; + return 0; + } =20 - trace_clk_rate_request_start(&parent_req); + clk_core_forward_rate_req(core, req, parent, &parent_req, req->rate); =20 - ret =3D clk_core_round_rate_nolock(parent, &parent_req); - if (ret) - return ret; + trace_clk_rate_request_start(&parent_req); =20 - trace_clk_rate_request_done(&parent_req); + ret =3D clk_core_round_rate_nolock(parent, &parent_req); + if (ret) + return ret; =20 - best =3D parent_req.rate; - } else if (parent) { - best =3D clk_core_get_rate_nolock(parent); - } else { - best =3D clk_core_get_rate_nolock(core); - } + trace_clk_rate_request_done(&parent_req); =20 - goto out; + best =3D parent_req.rate; + } else if (parent) { + best =3D clk_core_get_rate_nolock(parent); + } else { + best =3D clk_core_get_rate_nolock(core); } =20 + req->rate =3D best; + + return 0; +} + +int clk_mux_determine_rate_flags(struct clk_hw *hw, + struct clk_rate_request *req, + unsigned long flags) +{ + struct clk_core *core =3D hw->core, *parent, *best_parent =3D NULL; + int i, num_parents, ret; + unsigned long best =3D 0; + + /* if NO_REPARENT flag set, pass through to current parent */ + if (core->flags & CLK_SET_RATE_NO_REPARENT) + return clk_core_determine_rate_noreparent(core, req); + /* find the parent that can provide the fastest rate <=3D rate */ num_parents =3D core->num_parents; for (i =3D 0; i < num_parents; i++) { @@ -670,9 +682,7 @@ int clk_mux_determine_rate_flags(struct clk_hw *hw, if (!best_parent) return -EINVAL; =20 -out: - if (best_parent) - req->best_parent_hw =3D best_parent->hw; + req->best_parent_hw =3D best_parent->hw; req->best_parent_rate =3D best; req->rate =3D best; =20 @@ -772,6 +782,24 @@ int __clk_mux_determine_rate_closest(struct clk_hw *hw, } EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest); =20 +/** + * clk_hw_determine_rate_noreparent - clk_ops::determine_rate implementati= on for a clk that doesn't reparent + * @hw: clk to determine rate on + * @req: rate request + * + * Helper for finding best parent rate to provide a given frequency. This = can + * be used directly as a determine_rate callback (e.g. for a mux), or from= a + * more complex clock that may combine a mux with other operations. + * + * Returns: 0 on success, -EERROR value on error + */ +int clk_hw_determine_rate_noreparent(struct clk_hw *hw, + struct clk_rate_request *req) +{ + return clk_core_determine_rate_noreparent(hw->core, req); +} +EXPORT_SYMBOL_GPL(clk_hw_determine_rate_noreparent); + /*** clk api ***/ =20 static void clk_core_rate_unprotect(struct clk_core *core) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 28ff6f1a6ada..958977231ff7 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -1333,6 +1333,8 @@ int __clk_mux_determine_rate_closest(struct clk_hw *h= w, int clk_mux_determine_rate_flags(struct clk_hw *hw, struct clk_rate_request *req, unsigned long flags); +int clk_hw_determine_rate_noreparent(struct clk_hw *hw, + struct clk_rate_request *req); void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent); void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate, unsigned long *max_rate); --=20 https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git