linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes
@ 2023-05-05 11:25 Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 01/68] clk: Export clk_hw_forward_rate_request() Maxime Ripard
                   ` (67 more replies)
  0 siblings, 68 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Abel Vesa, Alessandro Zummo,
	Alexandre Belloni, Alexandre Torgue, Andreas Färber,
	AngeloGioacchino Del Regno, Baolin Wang, Charles Keepax,
	Chen-Yu Tsai, 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, Markus Schneider-Pargmann,
	Max Filippov, Maxime Coquelin, Mikko Perttunen, Miles Chen,
	Nicolas Ferre, Orson Zhai, Paul Cercueil, Peng Fan,
	Peter De Schrijver, Prashant Gaikwad, Richard Fitzgerald,
	Samuel Holland, Sascha Hauer, Sekhar Nori, Shawn Guo,
	Takashi Iwai, Thierry Reding, Ulf Hansson, Vinod Koul, dri-devel,
	linux-actions, linux-arm-kernel, linux-mips, linux-phy,
	linux-renesas-soc, linux-rtc, linux-stm32, linux-sunxi,
	linux-tegra, NXP Linux Team, patches, Pengutronix Kernel Team,
	Liam Beguin, Matthias Brugger, linux-mediatek, Miquel Raynal,
	Pawel Moll, alsa-devel

Hi,

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().

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().

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 :)

It was build-tested on x86, arm and arm64.

Affected drivers have been tracked down by the following coccinelle
script:

virtual report 

@ clk_ops @
identifier ops;
position p;
@@

 struct clk_ops ops@p = {
   ...
 };

@ has_set_parent @
identifier clk_ops.ops;
identifier set_parent_f;
@@

  struct clk_ops ops = {
	.set_parent = set_parent_f,
  };

@ has_determine_rate @
identifier clk_ops.ops;
identifier determine_rate_f;
@@

  struct clk_ops ops = {
	.determine_rate = determine_rate_f,
  };

@ script:python depends on report && has_set_parent && !has_determine_rate @
ops << clk_ops.ops;
set_parent_f << has_set_parent.set_parent_f;
p << clk_ops.p;
@@

coccilib.report.print_report(p[0], "ERROR: %s has set_parent (%s)" % (ops, set_parent_f))

Berlin is the only user still matching after this series has been
applied, but it's because it uses a composite clock which throws the
script off. The driver has been converted and shouldn't be a problem. 

Let me know what you think,
Maxime

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
Changes in v4:
- Switch from __clk_mux_determine_rate to a new helper
- Introduced unit tests for that new helper
- Fix kunit regression
- Reworded most of the commit logs
- Link to v3: https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v3-0-9a1358472d52@cerno.tech

Changes in v3:
- Rebased on top of next-20230404
- Link to v2: https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v2-0-f6736dec138e@cerno.tech

Changes in v2:
- Drop all the patches already applied
- Promote the clk registration warning to an error
- Make all muxes use determine_rate
- Link to v1: https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v1-0-f3ef80518140@cerno.tech

---
Maxime Ripard (66):
      clk: Export clk_hw_forward_rate_request()
      clk: test: Fix type sign of rounded rate variables
      clk: lan966x: Remove unused round_rate hook
      clk: nodrv: Add a determine_rate hook
      clk: test: Add a determine_rate hook
      clk: actions: composite: Add a determine_rate hook for pass clk
      clk: at91: main: Add a determine_rate hook
      clk: at91: sckc: Add a determine_rate hook
      clk: berlin: div: Add a determine_rate hook
      clk: cdce706: Add a determine_rate hook
      clk: k210: pll: Add a determine_rate hook
      clk: k210: aclk: Add a determine_rate hook
      clk: k210: mux: Add a determine_rate hook
      clk: lmk04832: clkout: Add a determine_rate hook
      clk: lochnagar: Add a determine_rate hook
      clk: qoriq: Add a determine_rate hook
      clk: si5341: Add a determine_rate hook
      clk: stm32f4: mux: Add a determine_rate hook
      clk: vc5: mux: Add a determine_rate hook
      clk: vc5: clkout: Add a determine_rate hook
      clk: wm831x: clkout: Add a determine_rate hook
      clk: davinci: da8xx-cfgchip: Add a determine_rate hook
      clk: davinci: da8xx-cfgchip: Add a determine_rate hook
      clk: imx: busy: Add a determine_rate hook
      clk: imx: fixup-mux: Add a determine_rate hook
      clk: imx: scu: Add a determine_rate hook
      clk: mediatek: cpumux: Add a determine_rate hook
      clk: pxa: Add a determine_rate hook
      clk: renesas: r9a06g032: Add a determine_rate hook
      clk: socfpga: gate: Add a determine_rate hook
      clk: stm32: core: Add a determine_rate hook
      clk: tegra: bpmp: Add a determine_rate hook
      clk: tegra: super: Add a determine_rate hook
      clk: tegra: periph: Add a determine_rate hook
      clk: ux500: prcmu: Add a determine_rate hook
      clk: ux500: sysctrl: Add a determine_rate hook
      clk: versatile: sp810: Add a determine_rate hook
      drm/tegra: sor: Add a determine_rate hook
      phy: cadence: sierra: Add a determine_rate hook
      phy: cadence: torrent: Add a determine_rate hook
      phy: ti: am654-serdes: Add a determine_rate hook
      phy: ti: j721e-wiz: Add a determine_rate hook
      rtc: sun6i: Add a determine_rate hook
      ASoC: tlv320aic32x4: Add a determine_rate hook
      clk: actions: composite: div: Switch to determine_rate
      clk: actions: composite: fact: Switch to determine_rate
      clk: at91: smd: Switch to determine_rate
      clk: axi-clkgen: Switch to determine_rate
      clk: cdce706: divider: Switch to determine_rate
      clk: cdce706: clkout: Switch to determine_rate
      clk: si5341: Switch to determine_rate
      clk: si5351: pll: Switch to determine_rate
      clk: si5351: msynth: Switch to determine_rate
      clk: si5351: clkout: Switch to determine_rate
      clk: da8xx: clk48: Switch to determine_rate
      clk: imx: scu: Switch to determine_rate
      clk: ingenic: cgu: Switch to determine_rate
      clk: ingenic: tcu: Switch to determine_rate
      clk: sprd: composite: Switch to determine_rate
      clk: st: flexgen: Switch to determine_rate
      clk: stm32: composite: Switch to determine_rate
      clk: tegra: periph: Switch to determine_rate
      clk: tegra: super: Switch to determine_rate
      ASoC: tlv320aic32x4: pll: Switch to determine_rate
      ASoC: tlv320aic32x4: div: Switch to determine_rate
      clk: Forbid to register a mux without determine_rate

Stephen Boyd (2):
      clk: Move no reparent case into a separate function
      clk: Introduce clk_hw_determine_rate_no_reparent()

 drivers/clk/actions/owl-composite.c       |  35 ++++--
 drivers/clk/at91/clk-main.c               |   1 +
 drivers/clk/at91/clk-smd.c                |  29 +++--
 drivers/clk/at91/sckc.c                   |   1 +
 drivers/clk/berlin/berlin2-div.c          |   1 +
 drivers/clk/clk-axi-clkgen.c              |  14 ++-
 drivers/clk/clk-cdce706.c                 |  30 ++---
 drivers/clk/clk-k210.c                    |   3 +
 drivers/clk/clk-lan966x.c                 |  17 ---
 drivers/clk/clk-lmk04832.c                |   1 +
 drivers/clk/clk-lochnagar.c               |   1 +
 drivers/clk/clk-qoriq.c                   |   1 +
 drivers/clk/clk-si5341.c                  |  19 ++--
 drivers/clk/clk-si5351.c                  |  67 ++++++-----
 drivers/clk/clk-stm32f4.c                 |   1 +
 drivers/clk/clk-versaclock5.c             |   2 +
 drivers/clk/clk-wm831x.c                  |   1 +
 drivers/clk/clk.c                         | 108 ++++++++++++------
 drivers/clk/clk_test.c                    | 180 +++++++++++++++++++++++++++++-
 drivers/clk/davinci/da8xx-cfgchip.c       |  12 +-
 drivers/clk/imx/clk-busy.c                |   1 +
 drivers/clk/imx/clk-fixup-mux.c           |   1 +
 drivers/clk/imx/clk-scu.c                 |  20 +++-
 drivers/clk/ingenic/cgu.c                 |  15 +--
 drivers/clk/ingenic/tcu.c                 |  19 ++--
 drivers/clk/mediatek/clk-cpumux.c         |   1 +
 drivers/clk/pxa/clk-pxa.c                 |   1 +
 drivers/clk/renesas/r9a06g032-clocks.c    |   1 +
 drivers/clk/socfpga/clk-gate.c            |   1 +
 drivers/clk/sprd/composite.c              |  16 ++-
 drivers/clk/st/clk-flexgen.c              |  15 +--
 drivers/clk/stm32/clk-stm32-core.c        |  33 ++++--
 drivers/clk/tegra/clk-bpmp.c              |   1 +
 drivers/clk/tegra/clk-periph.c            |  17 ++-
 drivers/clk/tegra/clk-super.c             |  16 ++-
 drivers/clk/ux500/clk-prcmu.c             |   1 +
 drivers/clk/ux500/clk-sysctrl.c           |   1 +
 drivers/clk/versatile/clk-sp810.c         |   1 +
 drivers/gpu/drm/tegra/sor.c               |   1 +
 drivers/phy/cadence/phy-cadence-sierra.c  |   1 +
 drivers/phy/cadence/phy-cadence-torrent.c |   1 +
 drivers/phy/ti/phy-am654-serdes.c         |   1 +
 drivers/phy/ti/phy-j721e-wiz.c            |   1 +
 drivers/rtc/rtc-sun6i.c                   |   1 +
 include/linux/clk-provider.h              |   2 +
 sound/soc/codecs/tlv320aic32x4-clk.c      |  33 +++---
 46 files changed, 527 insertions(+), 199 deletions(-)
---
base-commit: 145e5cddfe8b4bf607510b2dcf630d95f4db420f
change-id: 20221018-clk-range-checks-fixes-2039f3523240

Best regards,
-- 
Maxime Ripard <maxime@cerno.tech>


^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v4 01/68] clk: Export clk_hw_forward_rate_request()
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 02/68] clk: test: Fix type sign of rounded rate variables Maxime Ripard
                   ` (66 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

Commit 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the
parent") introduced the public clk_hw_forward_rate_request() function,
but didn't export the symbol. Make sure it's the case.

Fixes: 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 27c30a533759..e495dd7a1eae 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1549,6 +1549,7 @@ void clk_hw_forward_rate_request(const struct clk_hw *hw,
 				  parent->core, req,
 				  parent_rate);
 }
+EXPORT_SYMBOL_GPL(clk_hw_forward_rate_request);
 
 static bool clk_core_can_round(struct clk_core * const core)
 {

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 02/68] clk: test: Fix type sign of rounded rate variables
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 01/68] clk: Export clk_hw_forward_rate_request() Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 03/68] clk: Move no reparent case into a separate function Maxime Ripard
                   ` (65 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

clk_round_rate() may return a negative error code, but most of the
variables we defined to store its returned value are unsigned.

This obviously leads to issues on error.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk_test.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index f9a5c2964c65..2cb51153750d 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -266,7 +266,8 @@ static void clk_test_round_set_get_rate(struct kunit *test)
 	struct clk_dummy_context *ctx = test->priv;
 	struct clk_hw *hw = &ctx->hw;
 	struct clk *clk = clk_hw_get_clk(hw, NULL);
-	unsigned long rounded_rate, set_rate;
+	unsigned long set_rate;
+	long rounded_rate;
 
 	rounded_rate = clk_round_rate(clk, DUMMY_CLOCK_RATE_1);
 	KUNIT_ASSERT_GT(test, rounded_rate, 0);
@@ -851,7 +852,7 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_round_rate(struct kuni
 	struct clk_multiple_parent_ctx *ctx = test->priv;
 	struct clk_hw *hw = &ctx->hw;
 	struct clk *clk = clk_hw_get_clk(hw, NULL);
-	unsigned long rate;
+	long rate;
 	int ret;
 
 	ret = clk_set_rate_range(clk, DUMMY_CLOCK_RATE_1, DUMMY_CLOCK_RATE_2);
@@ -1090,7 +1091,7 @@ clk_test_single_parent_mux_set_range_round_rate_parent_only(struct kunit *test)
 	struct clk_hw *hw = &ctx->hw;
 	struct clk *clk = clk_hw_get_clk(hw, NULL);
 	struct clk *parent;
-	unsigned long rate;
+	long rate;
 	int ret;
 
 	parent = clk_get_parent(clk);
@@ -1120,7 +1121,7 @@ clk_test_single_parent_mux_set_range_round_rate_child_smaller(struct kunit *test
 	struct clk_hw *hw = &ctx->hw;
 	struct clk *clk = clk_hw_get_clk(hw, NULL);
 	struct clk *parent;
-	unsigned long rate;
+	long rate;
 	int ret;
 
 	parent = clk_get_parent(clk);
@@ -1158,7 +1159,7 @@ clk_test_single_parent_mux_set_range_round_rate_parent_smaller(struct kunit *tes
 	struct clk_hw *hw = &ctx->hw;
 	struct clk *clk = clk_hw_get_clk(hw, NULL);
 	struct clk *parent;
-	unsigned long rate;
+	long rate;
 	int ret;
 
 	parent = clk_get_parent(clk);

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 03/68] clk: Move no reparent case into a separate function
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 01/68] clk: Export clk_hw_forward_rate_request() Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 02/68] clk: test: Fix type sign of rounded rate variables Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
       [not found]   ` <CGME20230613111502eucas1p2644889c9de1abfe1a14a3b549772f247@eucas1p2.samsung.com>
  2023-05-05 11:25 ` [PATCH v4 04/68] clk: Introduce clk_hw_determine_rate_no_reparent() Maxime Ripard
                   ` (64 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Abel Vesa, Alessandro Zummo,
	Alexandre Belloni, Alexandre Torgue, Andreas Färber,
	AngeloGioacchino Del Regno, Baolin Wang, Charles Keepax,
	Chen-Yu Tsai, 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, Markus Schneider-Pargmann,
	Max Filippov, Maxime Coquelin, Mikko Perttunen, Miles Chen,
	Nicolas Ferre, Orson Zhai, Paul Cercueil, Peng Fan,
	Peter De Schrijver, Prashant Gaikwad, Richard Fitzgerald,
	Samuel Holland, Sascha Hauer, Sekhar Nori, Shawn Guo,
	Takashi Iwai, Thierry Reding, Ulf Hansson, Vinod Koul, dri-devel,
	linux-actions, linux-arm-kernel, linux-mips, linux-phy,
	linux-renesas-soc, linux-rtc, linux-stm32, linux-sunxi,
	linux-tegra, NXP Linux Team, patches, Pengutronix Kernel Team

From: Stephen Boyd <sboyd@kernel.org>

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@kernel.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: "Andreas Färber" <afaerber@suse.de>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
Cc: Chen-Yu Tsai <wens@csie.org>
Cc: Chen-Yu Tsai <wenst@chromium.org>
Cc: Chunyan Zhang <zhang.lyra@gmail.com>
Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: David Airlie <airlied@gmail.com>
Cc: David Lechner <david@lechnology.com>
Cc: Dinh Nguyen <dinguyen@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Luca Ceresoli <luca.ceresoli@bootlin.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Markus Schneider-Pargmann <msp@baylibre.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Mikko Perttunen <mperttunen@nvidia.com>
Cc: Miles Chen <miles.chen@mediatek.com>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Orson Zhai <orsonzhai@gmail.com>
Cc: Paul Cercueil <paul@crapouillou.net>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Richard Fitzgerald <rf@opensource.cirrus.com>
Cc: Samuel Holland <samuel@sholland.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-actions@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mips@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-renesas-soc@vger.kernel.org
Cc: linux-rtc@vger.kernel.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-sunxi@lists.linux.dev
Cc: linux-tegra@vger.kernel.org
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: patches@opensource.cirrus.com
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 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


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 04/68] clk: Introduce clk_hw_determine_rate_no_reparent()
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (2 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 03/68] clk: Move no reparent case into a separate function Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 17:15   ` kernel test robot
  2023-05-05 11:25 ` [PATCH v4 05/68] clk: lan966x: Remove unused round_rate hook Maxime Ripard
                   ` (63 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Abel Vesa, Alessandro Zummo,
	Alexandre Belloni, Alexandre Torgue, Andreas Färber,
	AngeloGioacchino Del Regno, Baolin Wang, Charles Keepax,
	Chen-Yu Tsai, 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, Markus Schneider-Pargmann,
	Max Filippov, Maxime Coquelin, Mikko Perttunen, Miles Chen,
	Nicolas Ferre, Orson Zhai, Paul Cercueil, Peng Fan,
	Peter De Schrijver, Prashant Gaikwad, Richard Fitzgerald,
	Samuel Holland, Sascha Hauer, Sekhar Nori, Shawn Guo,
	Takashi Iwai, Thierry Reding, Ulf Hansson, Vinod Koul, dri-devel,
	linux-actions, linux-arm-kernel, linux-mips, linux-phy,
	linux-renesas-soc, linux-rtc, linux-stm32, linux-sunxi,
	linux-tegra, NXP Linux Team, patches, Pengutronix Kernel Team

From: Stephen Boyd <sboyd@kernel.org>

Some clock drivers do not want to allow any reparenting on a given
clock, but usually do so by not providing any determine_rate
implementation.

Whenever we call clk_round_rate() or clk_set_rate(), this leads to
clk_core_can_round() returning false and thus the rest of the function
either forwarding the rate request to its current parent if
CLK_SET_RATE_PARENT is set, or just returning the current clock rate.

This behaviour happens implicitly, and as we move forward to making a
determine_rate implementation required for muxes, we need some way to
explicitly opt-in for that behaviour.

Fortunately, this is exactly what the clk_core_determine_rate_no_reparent()
function is doing, so we can simply make it available to drivers.

Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: "Andreas Färber" <afaerber@suse.de>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
Cc: Chen-Yu Tsai <wens@csie.org>
Cc: Chen-Yu Tsai <wenst@chromium.org>
Cc: Chunyan Zhang <zhang.lyra@gmail.com>
Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: David Airlie <airlied@gmail.com>
Cc: David Lechner <david@lechnology.com>
Cc: Dinh Nguyen <dinguyen@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Luca Ceresoli <luca.ceresoli@bootlin.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Markus Schneider-Pargmann <msp@baylibre.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Mikko Perttunen <mperttunen@nvidia.com>
Cc: Miles Chen <miles.chen@mediatek.com>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Orson Zhai <orsonzhai@gmail.com>
Cc: Paul Cercueil <paul@crapouillou.net>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Richard Fitzgerald <rf@opensource.cirrus.com>
Cc: Samuel Holland <samuel@sholland.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-actions@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mips@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-renesas-soc@vger.kernel.org
Cc: linux-rtc@vger.kernel.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-sunxi@lists.linux.dev
Cc: linux-tegra@vger.kernel.org
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: patches@opensource.cirrus.com
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk.c            |  18 +++++
 drivers/clk/clk_test.c       | 152 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/clk-provider.h |   2 +
 3 files changed, 172 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index f57f821a5e5a..5365595433c8 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -783,6 +783,24 @@ int __clk_mux_determine_rate_closest(struct clk_hw *hw,
 }
 EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
 
+/*
+ * clk_hw_determine_rate_no_reparent - clk_ops::determine_rate implementation for a clk that doesn't reparent
+ * @hw: mux type clk to determine rate on
+ * @req: rate request, also used to return preferred frequency
+ *
+ * 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_no_reparent(struct clk_hw *hw,
+				      struct clk_rate_request *req)
+{
+	return clk_core_determine_rate_no_reparent(hw, req);
+}
+
 /***        clk api        ***/
 
 static void clk_core_rate_unprotect(struct clk_core *core)
diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index 2cb51153750d..b3ed3b0e4c31 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -141,6 +141,12 @@ static const struct clk_ops clk_multiple_parents_mux_ops = {
 	.determine_rate = __clk_mux_determine_rate_closest,
 };
 
+static const struct clk_ops clk_multiple_parents_no_reparent_mux_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
+	.get_parent = clk_multiple_parents_mux_get_parent,
+	.set_parent = clk_multiple_parents_mux_set_parent,
+};
+
 static int clk_test_init_with_ops(struct kunit *test, const struct clk_ops *ops)
 {
 	struct clk_dummy_context *ctx;
@@ -2395,10 +2401,156 @@ static struct kunit_suite clk_mux_notifier_test_suite = {
 	.test_cases = clk_mux_notifier_test_cases,
 };
 
+static int
+clk_mux_no_reparent_test_init(struct kunit *test)
+{
+	struct clk_multiple_parent_ctx *ctx;
+	const char *parents[2] = { "parent-0", "parent-1"};
+	int ret;
+
+	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+	test->priv = ctx;
+
+	ctx->parents_ctx[0].hw.init = CLK_HW_INIT_NO_PARENT("parent-0",
+							    &clk_dummy_rate_ops,
+							    0);
+	ctx->parents_ctx[0].rate = DUMMY_CLOCK_RATE_1;
+	ret = clk_hw_register(NULL, &ctx->parents_ctx[0].hw);
+	if (ret)
+		return ret;
+
+	ctx->parents_ctx[1].hw.init = CLK_HW_INIT_NO_PARENT("parent-1",
+							    &clk_dummy_rate_ops,
+							    0);
+	ctx->parents_ctx[1].rate = DUMMY_CLOCK_RATE_2;
+	ret = clk_hw_register(NULL, &ctx->parents_ctx[1].hw);
+	if (ret)
+		return ret;
+
+	ctx->current_parent = 0;
+	ctx->hw.init = CLK_HW_INIT_PARENTS("test-mux", parents,
+					   &clk_multiple_parents_no_reparent_mux_ops,
+					   0);
+	ret = clk_hw_register(NULL, &ctx->hw);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void
+clk_mux_no_reparent_test_exit(struct kunit *test)
+{
+	struct clk_multiple_parent_ctx *ctx = test->priv;
+
+	clk_hw_unregister(&ctx->hw);
+	clk_hw_unregister(&ctx->parents_ctx[0].hw);
+	clk_hw_unregister(&ctx->parents_ctx[1].hw);
+}
+
+/*
+ * Test that if the we have a mux that cannot change parent and we call
+ * clk_round_rate() on it with a rate that should cause it to change
+ * parent, it won't.
+ */
+static void clk_mux_no_reparent_round_rate(struct kunit *test)
+{
+	struct clk_multiple_parent_ctx *ctx = test->priv;
+	struct clk_hw *hw = &ctx->hw;
+	struct clk *clk = clk_hw_get_clk(hw, NULL);
+	struct clk *other_parent, *parent;
+	unsigned long other_parent_rate;
+	unsigned long parent_rate;
+	long rounded_rate;
+
+	parent = clk_get_parent(clk);
+	KUNIT_ASSERT_PTR_NE(test, parent, NULL);
+
+	parent_rate = clk_get_rate(parent);
+	KUNIT_ASSERT_GT(test, parent_rate, 0);
+
+	other_parent = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, other_parent);
+	KUNIT_ASSERT_FALSE(test, clk_is_match(parent, other_parent));
+
+	other_parent_rate = clk_get_rate(other_parent);
+	KUNIT_ASSERT_GT(test, other_parent_rate, 0);
+	clk_put(other_parent);
+
+	rounded_rate = clk_round_rate(clk, other_parent_rate);
+	KUNIT_ASSERT_GT(test, rounded_rate, 0);
+	KUNIT_EXPECT_EQ(test, rounded_rate, parent_rate);
+
+	clk_put(clk);
+}
+
+/*
+ * Test that if the we have a mux that cannot change parent and we call
+ * clk_set_rate() on it with a rate that should cause it to change
+ * parent, it won't.
+ */
+static void clk_mux_no_reparent_set_rate(struct kunit *test)
+{
+	struct clk_multiple_parent_ctx *ctx = test->priv;
+	struct clk_hw *hw = &ctx->hw;
+	struct clk *clk = clk_hw_get_clk(hw, NULL);
+	struct clk *other_parent, *parent;
+	unsigned long other_parent_rate;
+	unsigned long parent_rate;
+	unsigned long rate;
+	int ret;
+
+	parent = clk_get_parent(clk);
+	KUNIT_ASSERT_PTR_NE(test, parent, NULL);
+
+	parent_rate = clk_get_rate(parent);
+	KUNIT_ASSERT_GT(test, parent_rate, 0);
+
+	other_parent = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, other_parent);
+	KUNIT_ASSERT_FALSE(test, clk_is_match(parent, other_parent));
+
+	other_parent_rate = clk_get_rate(other_parent);
+	KUNIT_ASSERT_GT(test, other_parent_rate, 0);
+	clk_put(other_parent);
+
+	ret = clk_set_rate(clk, other_parent_rate);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	rate = clk_get_rate(clk);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, rate, parent_rate);
+
+	clk_put(clk);
+}
+
+static struct kunit_case clk_mux_no_reparent_test_cases[] = {
+	KUNIT_CASE(clk_mux_no_reparent_round_rate),
+	KUNIT_CASE(clk_mux_no_reparent_set_rate),
+	{}
+};
+
+/*
+ * Test suite for a clock mux that isn't allowed to change parent, using
+ * the clk_hw_determine_rate_no_reparent() helper.
+ *
+ * These tests exercise that helper, and the proper selection of
+ * rates and parents.
+ */
+static struct kunit_suite clk_mux_no_reparent_test_suite = {
+	.name = "clk-mux-no-reparent",
+	.init = clk_mux_no_reparent_test_init,
+	.exit = clk_mux_no_reparent_test_exit,
+	.test_cases = clk_mux_no_reparent_test_cases,
+};
+
 kunit_test_suites(
 	&clk_leaf_mux_set_rate_parent_test_suite,
 	&clk_test_suite,
 	&clk_multiple_parents_mux_test_suite,
+	&clk_mux_no_reparent_test_suite,
 	&clk_mux_notifier_test_suite,
 	&clk_orphan_transparent_multiple_parent_mux_test_suite,
 	&clk_orphan_transparent_single_parent_test_suite,
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 28ff6f1a6ada..f8f220fb5dab 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 *hw,
 int clk_mux_determine_rate_flags(struct clk_hw *hw,
 				 struct clk_rate_request *req,
 				 unsigned long flags);
+int clk_hw_determine_rate_no_reparent(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);

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 05/68] clk: lan966x: Remove unused round_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (3 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 04/68] clk: Introduce clk_hw_determine_rate_no_reparent() Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 06/68] clk: nodrv: Add a determine_rate hook Maxime Ripard
                   ` (62 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The lan966x driver registers a gck clock with both a determine_rate and
a round_rate implementation. Both are equivalent, and are only called by
clk_core_determine_round_nolock() which favors determine_rate.

Thus, lan966x_gck_round_rate() is never called, so we can just remove
it.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-lan966x.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/clk/clk-lan966x.c b/drivers/clk/clk-lan966x.c
index 460e7216bfa1..870fd7df50c1 100644
--- a/drivers/clk/clk-lan966x.c
+++ b/drivers/clk/clk-lan966x.c
@@ -103,22 +103,6 @@ static int lan966x_gck_set_rate(struct clk_hw *hw,
 	return 0;
 }
 
-static long lan966x_gck_round_rate(struct clk_hw *hw, unsigned long rate,
-				   unsigned long *parent_rate)
-{
-	unsigned int div;
-
-	if (rate == 0 || *parent_rate == 0)
-		return -EINVAL;
-
-	if (rate >= *parent_rate)
-		return *parent_rate;
-
-	div = DIV_ROUND_CLOSEST(*parent_rate, rate);
-
-	return *parent_rate / div;
-}
-
 static unsigned long lan966x_gck_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
@@ -177,7 +161,6 @@ static const struct clk_ops lan966x_gck_ops = {
 	.enable         = lan966x_gck_enable,
 	.disable        = lan966x_gck_disable,
 	.set_rate       = lan966x_gck_set_rate,
-	.round_rate     = lan966x_gck_round_rate,
 	.recalc_rate    = lan966x_gck_recalc_rate,
 	.determine_rate = lan966x_gck_determine_rate,
 	.set_parent     = lan966x_gck_set_parent,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 06/68] clk: nodrv: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (4 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 05/68] clk: lan966x: Remove unused round_rate hook Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 07/68] clk: test: " Maxime Ripard
                   ` (61 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The nodrv clock implements a mux with a set_parent hook, but doesn't
provide a determine_rate implementation.

Even though it's a mock clock and the missing function is harmless,
we'll start to require a determine_rate implementation when set_parent
is set, so let's fill it.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 5365595433c8..e4a1d5f9694c 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -4331,11 +4331,18 @@ static int clk_nodrv_set_parent(struct clk_hw *hw, u8 index)
 	return -ENXIO;
 }
 
+static int clk_nodrv_determine_rate(struct clk_hw *hw,
+				    struct clk_rate_request *req)
+{
+	return -ENXIO;
+}
+
 static const struct clk_ops clk_nodrv_ops = {
 	.enable		= clk_nodrv_prepare_enable,
 	.disable	= clk_nodrv_disable_unprepare,
 	.prepare	= clk_nodrv_prepare_enable,
 	.unprepare	= clk_nodrv_disable_unprepare,
+	.determine_rate	= clk_nodrv_determine_rate,
 	.set_rate	= clk_nodrv_set_rate,
 	.set_parent	= clk_nodrv_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 07/68] clk: test: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (5 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 06/68] clk: nodrv: Add a determine_rate hook Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-06-09  1:41   ` Stephen Boyd
  2023-05-05 11:25 ` [PATCH v4 08/68] clk: actions: composite: Add a determine_rate hook for pass clk Maxime Ripard
                   ` (60 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The single parent clock in our kunit tests implements a mux with a
set_parent hook, but doesn't provide a determine_rate implementation.

This is not entirely unexpected, since its whole purpose it to have a
single parent. When determine_rate is missing, and since
CLK_SET_RATE_PARENT is set for all its instances, the default behaviour
of the framework will be to forward it to the current parent.

This is totally fine as far as the tests are concerned, but we'll start
to mandate a determine_rate implementation when set_parent is set, so
let's fill it with __clk_mux_determine_rate() which will have the same
behavior.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk_test.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index b3ed3b0e4c31..a154ec9d0111 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -104,6 +104,23 @@ static const struct clk_ops clk_dummy_minimize_rate_ops = {
 };
 
 static const struct clk_ops clk_dummy_single_parent_ops = {
+	/*
+	 * FIXME: Even though we should probably be able to use
+	 * __clk_mux_determine_rate() here, if we use it and call
+	 * clk_round_rate() or clk_set_rate() with a rate lower than
+	 * what all the parents can provide, it will return -EINVAL.
+	 *
+	 * This is due to the fact that it has the undocumented
+	 * behaviour to always pick up the closest rate higher than the
+	 * requested rate. If we get something lower, it thus considers
+	 * that it's not acceptable and will return an error.
+	 *
+	 * It's somewhat inconsistent and creates a weird threshold
+	 * between rates above the parent rate which would be rounded to
+	 * what the parent can provide, but rates below will simply
+	 * return an error.
+	 */
+	.determine_rate = __clk_mux_determine_rate_closest,
 	.set_parent = clk_dummy_single_set_parent,
 	.get_parent = clk_dummy_single_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 08/68] clk: actions: composite: Add a determine_rate hook for pass clk
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (6 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 07/68] clk: test: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 09/68] clk: at91: main: Add a determine_rate hook Maxime Ripard
                   ` (59 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Andreas Färber,
	Manivannan Sadhasivam, linux-actions, linux-arm-kernel

The Actions "Pass" clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: "Andreas Färber" <afaerber@suse.de>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: linux-actions@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/actions/owl-composite.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/actions/owl-composite.c b/drivers/clk/actions/owl-composite.c
index 101706e0c66f..e7784f9e5bf6 100644
--- a/drivers/clk/actions/owl-composite.c
+++ b/drivers/clk/actions/owl-composite.c
@@ -189,6 +189,7 @@ const struct clk_ops owl_comp_fix_fact_ops = {
 
 const struct clk_ops owl_comp_pass_ops = {
 	/* mux_ops */
+	.determine_rate	= clk_hw_determine_rate_no_reparent,
 	.get_parent	= owl_comp_get_parent,
 	.set_parent	= owl_comp_set_parent,
 

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 09/68] clk: at91: main: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (7 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 08/68] clk: actions: composite: Add a determine_rate hook for pass clk Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 10/68] clk: at91: sckc: " Maxime Ripard
                   ` (58 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Alexandre Belloni, Claudiu Beznea,
	Nicolas Ferre, linux-arm-kernel

The SAM9x5 main clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/at91/clk-main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 8601b27c1ae0..4966e0f9e92c 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -533,6 +533,7 @@ static const struct clk_ops sam9x5_main_ops = {
 	.prepare = clk_sam9x5_main_prepare,
 	.is_prepared = clk_sam9x5_main_is_prepared,
 	.recalc_rate = clk_sam9x5_main_recalc_rate,
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = clk_sam9x5_main_set_parent,
 	.get_parent = clk_sam9x5_main_get_parent,
 	.save_context = clk_sam9x5_main_save_context,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 10/68] clk: at91: sckc: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (8 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 09/68] clk: at91: main: Add a determine_rate hook Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 11/68] clk: berlin: div: " Maxime Ripard
                   ` (57 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Alexandre Belloni, Claudiu Beznea,
	Nicolas Ferre, linux-arm-kernel

The SAM9x5 slow clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/at91/sckc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index fdc9b669f8a7..a2d86c377827 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -310,6 +310,7 @@ static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
 }
 
 static const struct clk_ops sam9x5_slow_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = clk_sam9x5_slow_set_parent,
 	.get_parent = clk_sam9x5_slow_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 11/68] clk: berlin: div: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (9 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 10/68] clk: at91: sckc: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 12/68] clk: cdce706: " Maxime Ripard
                   ` (56 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The Berlin2 divider clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/berlin/berlin2-div.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/berlin/berlin2-div.c b/drivers/clk/berlin/berlin2-div.c
index eb14a5bc0507..0a248bfe2193 100644
--- a/drivers/clk/berlin/berlin2-div.c
+++ b/drivers/clk/berlin/berlin2-div.c
@@ -210,6 +210,7 @@ static unsigned long berlin2_div_recalc_rate(struct clk_hw *hw,
 }
 
 static const struct clk_ops berlin2_div_rate_ops = {
+	.determine_rate	= clk_hw_determine_rate_no_reparent,
 	.recalc_rate	= berlin2_div_recalc_rate,
 };
 

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 12/68] clk: cdce706: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (10 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 11/68] clk: berlin: div: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 21:00   ` kernel test robot
  2023-05-05 11:25 ` [PATCH v4 13/68] clk: k210: pll: " Maxime Ripard
                   ` (55 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard, Max Filippov

The cdce706 "clkin" clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-cdce706.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c
index d8bee8180a6b..139aa0954cc1 100644
--- a/drivers/clk/clk-cdce706.c
+++ b/drivers/clk/clk-cdce706.c
@@ -155,6 +155,7 @@ static u8 cdce706_clkin_get_parent(struct clk_hw *hw)
 }
 
 static const struct clk_ops cdce706_clkin_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = cdce706_clkin_set_parent,
 	.get_parent = cdce706_clkin_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 13/68] clk: k210: pll: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (11 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 12/68] clk: cdce706: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 14/68] clk: k210: aclk: " Maxime Ripard
                   ` (54 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The K210 PLL clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-k210.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-k210.c b/drivers/clk/clk-k210.c
index 4eed667eddaf..21d942065a3e 100644
--- a/drivers/clk/clk-k210.c
+++ b/drivers/clk/clk-k210.c
@@ -537,6 +537,7 @@ static const struct clk_ops k210_pll2_ops = {
 	.disable	= k210_pll_disable,
 	.is_enabled	= k210_pll_is_enabled,
 	.recalc_rate	= k210_pll_get_rate,
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent	= k210_pll2_set_parent,
 	.get_parent	= k210_pll2_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 14/68] clk: k210: aclk: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (12 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 13/68] clk: k210: pll: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 15/68] clk: k210: mux: " Maxime Ripard
                   ` (53 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The K210 ACLK clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-k210.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-k210.c b/drivers/clk/clk-k210.c
index 21d942065a3e..b5b8fb29a347 100644
--- a/drivers/clk/clk-k210.c
+++ b/drivers/clk/clk-k210.c
@@ -636,6 +636,7 @@ static unsigned long k210_aclk_get_rate(struct clk_hw *hw,
 }
 
 static const struct clk_ops k210_aclk_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent	= k210_aclk_set_parent,
 	.get_parent	= k210_aclk_get_parent,
 	.recalc_rate	= k210_aclk_get_rate,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 15/68] clk: k210: mux: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (13 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 14/68] clk: k210: aclk: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 16/68] clk: lmk04832: clkout: " Maxime Ripard
                   ` (52 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The K210 mux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-k210.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-k210.c b/drivers/clk/clk-k210.c
index b5b8fb29a347..870adac5cdee 100644
--- a/drivers/clk/clk-k210.c
+++ b/drivers/clk/clk-k210.c
@@ -776,6 +776,7 @@ static unsigned long k210_clk_get_rate(struct clk_hw *hw,
 static const struct clk_ops k210_clk_mux_ops = {
 	.enable		= k210_clk_enable,
 	.disable	= k210_clk_disable,
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent	= k210_clk_set_parent,
 	.get_parent	= k210_clk_get_parent,
 	.recalc_rate	= k210_clk_get_rate,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 16/68] clk: lmk04832: clkout: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (14 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 15/68] clk: k210: mux: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 17/68] clk: lochnagar: " Maxime Ripard
                   ` (51 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard, Liam Beguin

The LKM04832 "CLKOUT" clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the flag
CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
to __clk_mux_determine_rate(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems
unlikely.

Reviewed-by: Liam Beguin <liambeguin@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-lmk04832.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c
index afdfee3b365f..e22ac93e0c2f 100644
--- a/drivers/clk/clk-lmk04832.c
+++ b/drivers/clk/clk-lmk04832.c
@@ -1279,6 +1279,7 @@ static const struct clk_ops lmk04832_clkout_ops = {
 	.is_enabled = lmk04832_clkout_is_enabled,
 	.prepare = lmk04832_clkout_prepare,
 	.unprepare = lmk04832_clkout_unprepare,
+	.determine_rate = __clk_mux_determine_rate,
 	.set_parent = lmk04832_clkout_set_parent,
 	.get_parent = lmk04832_clkout_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 17/68] clk: lochnagar: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (15 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 16/68] clk: lmk04832: clkout: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 17:46   ` kernel test robot
  2023-05-05 18:47   ` kernel test robot
  2023-05-05 11:25 ` [PATCH v4 18/68] clk: qoriq: " Maxime Ripard
                   ` (50 subsequent siblings)
  67 siblings, 2 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Charles Keepax, Richard Fitzgerald, patches

The lochnagar clocks implement a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Since there's no upstream device tree using that driver, it's a bit hard
to tell if it uses the assigned-clock properties. The binding and its
example uses them though, so it's likely that the author intent was to
force the parent through the device tree and prevent any reparenting but
through an explicit call to clk_set_parent().

This case is equivalent to setting the determine_rate implementation to
clk_hw_determine_rate_no_reparent(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
Cc: Richard Fitzgerald <rf@opensource.cirrus.com>
Cc: patches@opensource.cirrus.com
Tested-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-lochnagar.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-lochnagar.c b/drivers/clk/clk-lochnagar.c
index 80944bf482e9..db468a62c8d7 100644
--- a/drivers/clk/clk-lochnagar.c
+++ b/drivers/clk/clk-lochnagar.c
@@ -209,6 +209,7 @@ static u8 lochnagar_clk_get_parent(struct clk_hw *hw)
 static const struct clk_ops lochnagar_clk_ops = {
 	.prepare = lochnagar_clk_prepare,
 	.unprepare = lochnagar_clk_unprepare,
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = lochnagar_clk_set_parent,
 	.get_parent = lochnagar_clk_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 18/68] clk: qoriq: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (16 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 17/68] clk: lochnagar: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 19/68] clk: si5341: " Maxime Ripard
                   ` (49 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The Qoriq mux clocks implement a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-qoriq.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 5eddb9f0d6bd..e3386fd98c5e 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -878,6 +878,7 @@ static u8 mux_get_parent(struct clk_hw *hw)
 }
 
 static const struct clk_ops cmux_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = mux_get_parent,
 	.set_parent = mux_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 19/68] clk: si5341: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (17 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 18/68] clk: qoriq: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 20/68] clk: stm32f4: mux: " Maxime Ripard
                   ` (48 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The SI5341 clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-si5341.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
index 0e528d7ba656..4b65def64109 100644
--- a/drivers/clk/clk-si5341.c
+++ b/drivers/clk/clk-si5341.c
@@ -551,6 +551,7 @@ static int si5341_clk_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops si5341_clk_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = si5341_clk_set_parent,
 	.get_parent = si5341_clk_get_parent,
 	.recalc_rate = si5341_clk_recalc_rate,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 20/68] clk: stm32f4: mux: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (18 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 19/68] clk: si5341: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 21/68] clk: vc5: " Maxime Ripard
                   ` (47 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Alexandre Torgue, Maxime Coquelin,
	linux-arm-kernel, linux-stm32

The STM32F4 mux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

However, the upstream device trees seem to use assigned-clock-parents on
that clock to force the parent at boot time, so it's likely that the
author intent was to force the parent through the device tree and
prevent any reparenting but through an explicit call to
clk_set_parent().

This case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-stm32f4.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 473dfe632cc5..07c13ebe327d 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -1045,6 +1045,7 @@ static int cclk_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops cclk_mux_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = cclk_mux_get_parent,
 	.set_parent = cclk_mux_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 21/68] clk: vc5: mux: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (19 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 20/68] clk: stm32f4: mux: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 22/68] clk: vc5: clkout: " Maxime Ripard
                   ` (46 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard, Luca Ceresoli

The Versaclock5 mux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-versaclock5.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index fa71a57875ce..97ffd4ef0e5f 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -281,6 +281,7 @@ static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops vc5_mux_ops = {
+	.determine_rate	= clk_hw_determine_rate_no_reparent,
 	.set_parent	= vc5_mux_set_parent,
 	.get_parent	= vc5_mux_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 22/68] clk: vc5: clkout: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (20 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 21/68] clk: vc5: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 23/68] clk: wm831x: " Maxime Ripard
                   ` (45 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard, Luca Ceresoli

The Versaclock5 "clkout" clock implements a mux with a set_parent hook,
but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-versaclock5.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index 97ffd4ef0e5f..3d6f4b01e6c0 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -726,6 +726,7 @@ static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
 static const struct clk_ops vc5_clk_out_ops = {
 	.prepare	= vc5_clk_out_prepare,
 	.unprepare	= vc5_clk_out_unprepare,
+	.determine_rate	= clk_hw_determine_rate_no_reparent,
 	.set_parent	= vc5_clk_out_set_parent,
 	.get_parent	= vc5_clk_out_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 23/68] clk: wm831x: clkout: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (21 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 22/68] clk: vc5: clkout: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 18:06   ` kernel test robot
  2023-05-05 11:25 ` [PATCH v4 24/68] clk: davinci: da8xx-cfgchip: " Maxime Ripard
                   ` (44 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, patches, Charles Keepax

The WM381x "clkout" clock implements a mux with a set_parent hook,
but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: patches@opensource.cirrus.com
Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-wm831x.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index ae6dd38ec053..34e9d4d541e2 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -329,6 +329,7 @@ static const struct clk_ops wm831x_clkout_ops = {
 	.is_prepared = wm831x_clkout_is_prepared,
 	.prepare = wm831x_clkout_prepare,
 	.unprepare = wm831x_clkout_unprepare,
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = wm831x_clkout_get_parent,
 	.set_parent = wm831x_clkout_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 24/68] clk: davinci: da8xx-cfgchip: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (22 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 23/68] clk: wm831x: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 25/68] " Maxime Ripard
                   ` (43 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, David Lechner, Sekhar Nori

The Davinci DA8xxx cfgchip mux clock implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

However, the upstream device trees seem to use assigned-clock-parents on
that clock to force the parent at boot time, so it's likely that the
author intent was to force the parent through the device tree and
prevent any reparenting but through an explicit call to
clk_set_parent().

This case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

Cc: David Lechner <david@lechnology.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Acked-by: David Lechner <david@lechnology.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/davinci/da8xx-cfgchip.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
index 4103d605e804..11fcf6f63336 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -229,6 +229,7 @@ static u8 da8xx_cfgchip_mux_clk_get_parent(struct clk_hw *hw)
 }
 
 static const struct clk_ops da8xx_cfgchip_mux_clk_ops = {
+	.determine_rate	= clk_hw_determine_rate_no_reparent,
 	.set_parent	= da8xx_cfgchip_mux_clk_set_parent,
 	.get_parent	= da8xx_cfgchip_mux_clk_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 25/68] clk: davinci: da8xx-cfgchip: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (23 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 24/68] clk: davinci: da8xx-cfgchip: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 26/68] clk: imx: busy: " Maxime Ripard
                   ` (42 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, David Lechner, Sekhar Nori

The Davinci DA8xxx cfgchip "clk48" clock implements a mux with a
set_parent hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: David Lechner <david@lechnology.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Acked-by: David Lechner <david@lechnology.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/davinci/da8xx-cfgchip.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
index 11fcf6f63336..1bbcc8e43bc5 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -565,6 +565,7 @@ static u8 da8xx_usb1_clk48_get_parent(struct clk_hw *hw)
 }
 
 static const struct clk_ops da8xx_usb1_clk48_ops = {
+	.determine_rate	= clk_hw_determine_rate_no_reparent,
 	.set_parent	= da8xx_usb1_clk48_set_parent,
 	.get_parent	= da8xx_usb1_clk48_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 26/68] clk: imx: busy: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (24 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 25/68] " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 27/68] clk: imx: fixup-mux: " Maxime Ripard
                   ` (41 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Abel Vesa, Fabio Estevam, Peng Fan,
	Sascha Hauer, Shawn Guo, linux-arm-kernel, NXP Linux Team,
	Pengutronix Kernel Team

The iMX busy clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/imx/clk-busy.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c
index 6f17311647f3..f163df952ccc 100644
--- a/drivers/clk/imx/clk-busy.c
+++ b/drivers/clk/imx/clk-busy.c
@@ -148,6 +148,7 @@ static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops clk_busy_mux_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = clk_busy_mux_get_parent,
 	.set_parent = clk_busy_mux_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 27/68] clk: imx: fixup-mux: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (25 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 26/68] clk: imx: busy: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 28/68] clk: imx: scu: " Maxime Ripard
                   ` (40 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Abel Vesa, Fabio Estevam, Peng Fan,
	Sascha Hauer, Shawn Guo, linux-arm-kernel, NXP Linux Team,
	Pengutronix Kernel Team

The iMX fixup mux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

However, the upstream device trees seem to use assigned-clock-parents on
that clock to force the parent at boot time, so it's likely that the
author intent was to force the parent through the device tree and
prevent any reparenting but through an explicit call to
clk_set_parent().

This case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/imx/clk-fixup-mux.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c
index c82401570c84..b48701864ef0 100644
--- a/drivers/clk/imx/clk-fixup-mux.c
+++ b/drivers/clk/imx/clk-fixup-mux.c
@@ -60,6 +60,7 @@ static int clk_fixup_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops clk_fixup_mux_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = clk_fixup_mux_get_parent,
 	.set_parent = clk_fixup_mux_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 28/68] clk: imx: scu: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (26 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 27/68] clk: imx: fixup-mux: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-06  0:37   ` kernel test robot
  2023-05-05 11:25 ` [PATCH v4 29/68] clk: mediatek: cpumux: " Maxime Ripard
                   ` (39 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Abel Vesa, Fabio Estevam, Peng Fan,
	Sascha Hauer, Shawn Guo, linux-arm-kernel, NXP Linux Team,
	Pengutronix Kernel Team

The iMX SCU mux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/imx/clk-scu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index 1e6870f3671f..417f893f8895 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -785,6 +785,7 @@ static int clk_gpr_mux_scu_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops clk_gpr_mux_scu_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = clk_gpr_mux_scu_get_parent,
 	.set_parent = clk_gpr_mux_scu_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 29/68] clk: mediatek: cpumux: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (27 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 28/68] clk: imx: scu: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-08  2:36   ` Chen-Yu Tsai
  2023-05-05 11:25 ` [PATCH v4 30/68] clk: pxa: " Maxime Ripard
                   ` (38 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, AngeloGioacchino Del Regno,
	Matthias Brugger, linux-arm-kernel, linux-mediatek

The Mediatek cpumux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mediatek@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/mediatek/clk-cpumux.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index da05f06192c0..a03826db4dcb 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -53,6 +53,7 @@ static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops clk_cpumux_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = clk_cpumux_get_parent,
 	.set_parent = clk_cpumux_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 30/68] clk: pxa: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (28 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 29/68] clk: mediatek: cpumux: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 31/68] clk: renesas: r9a06g032: " Maxime Ripard
                   ` (37 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The PXA "CKEN" clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/pxa/clk-pxa.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/pxa/clk-pxa.c b/drivers/clk/pxa/clk-pxa.c
index 374098ebbf2b..ebee2afd05de 100644
--- a/drivers/clk/pxa/clk-pxa.c
+++ b/drivers/clk/pxa/clk-pxa.c
@@ -82,6 +82,7 @@ static u8 cken_get_parent(struct clk_hw *hw)
 }
 
 static const struct clk_ops cken_mux_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = cken_get_parent,
 	.set_parent = dummy_clk_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 31/68] clk: renesas: r9a06g032: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (29 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 30/68] clk: pxa: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 32/68] clk: socfpga: gate: " Maxime Ripard
                   ` (36 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Geert Uytterhoeven, linux-renesas-soc,
	Miquel Raynal

The Renesas r9a06g032 bitselect clock implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: linux-renesas-soc@vger.kernel.org
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/renesas/r9a06g032-clocks.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
index 40828616f723..55db63c7041a 100644
--- a/drivers/clk/renesas/r9a06g032-clocks.c
+++ b/drivers/clk/renesas/r9a06g032-clocks.c
@@ -1121,6 +1121,7 @@ static int r9a06g032_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops clk_bitselect_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = r9a06g032_clk_mux_get_parent,
 	.set_parent = r9a06g032_clk_mux_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 32/68] clk: socfpga: gate: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (30 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 31/68] clk: renesas: r9a06g032: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 33/68] clk: stm32: core: " Maxime Ripard
                   ` (35 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard, Dinh Nguyen

The SoCFGPA gate clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Dinh Nguyen <dinguyen@kernel.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/socfpga/clk-gate.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
index 32ccda960f28..8dd601bd8538 100644
--- a/drivers/clk/socfpga/clk-gate.c
+++ b/drivers/clk/socfpga/clk-gate.c
@@ -110,6 +110,7 @@ static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
 
 static struct clk_ops gateclk_ops = {
 	.recalc_rate = socfpga_clk_recalc_rate,
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = socfpga_clk_get_parent,
 	.set_parent = socfpga_clk_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 33/68] clk: stm32: core: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (31 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 32/68] clk: socfpga: gate: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 34/68] clk: tegra: bpmp: " Maxime Ripard
                   ` (34 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Alexandre Torgue, Maxime Coquelin,
	linux-arm-kernel, linux-stm32

The STM32 mux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the flag
CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
to __clk_mux_determine_rate(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems
unlikely.

Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/stm32/clk-stm32-core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c
index 45a279e73779..3247539683c9 100644
--- a/drivers/clk/stm32/clk-stm32-core.c
+++ b/drivers/clk/stm32/clk-stm32-core.c
@@ -275,6 +275,7 @@ static int clk_stm32_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 const struct clk_ops clk_stm32_mux_ops = {
+	.determine_rate	= __clk_mux_determine_rate,
 	.get_parent	= clk_stm32_mux_get_parent,
 	.set_parent	= clk_stm32_mux_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 34/68] clk: tegra: bpmp: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (32 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 33/68] clk: stm32: core: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 35/68] clk: tegra: super: " Maxime Ripard
                   ` (33 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Jonathan Hunter, Peter De Schrijver,
	Prashant Gaikwad, Thierry Reding, linux-tegra

The Tegra BPMP mux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

However, the upstream device trees seem to use assigned-clock-parents on
that clock to force the parent at boot time, so it's likely that the
author intent was to force the parent through the device tree and
prevent any reparenting but through an explicit call to
clk_set_parent().

This case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/tegra/clk-bpmp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c
index 0ecdffaa6b16..a9f3fb448de6 100644
--- a/drivers/clk/tegra/clk-bpmp.c
+++ b/drivers/clk/tegra/clk-bpmp.c
@@ -286,6 +286,7 @@ static const struct clk_ops tegra_bpmp_clk_mux_ops = {
 	.unprepare = tegra_bpmp_clk_unprepare,
 	.is_prepared = tegra_bpmp_clk_is_prepared,
 	.recalc_rate = tegra_bpmp_clk_recalc_rate,
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = tegra_bpmp_clk_set_parent,
 	.get_parent = tegra_bpmp_clk_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 35/68] clk: tegra: super: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (33 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 34/68] clk: tegra: bpmp: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 36/68] clk: tegra: periph: " Maxime Ripard
                   ` (32 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Jonathan Hunter, Peter De Schrijver,
	Prashant Gaikwad, Thierry Reding, linux-tegra

The Tegra super mux clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

However, the upstream device trees seem to use assigned-clock-parents on
that clock to force the parent at boot time, so it's likely that the
author intent was to force the parent through the device tree and
prevent any reparenting but through an explicit call to
clk_set_parent().

This case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/tegra/clk-super.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index a98a420398fa..3f3a7a203c5f 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -136,6 +136,7 @@ static void clk_super_mux_restore_context(struct clk_hw *hw)
 }
 
 static const struct clk_ops tegra_clk_super_mux_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = clk_super_get_parent,
 	.set_parent = clk_super_set_parent,
 	.restore_context = clk_super_mux_restore_context,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 36/68] clk: tegra: periph: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (34 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 35/68] clk: tegra: super: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 37/68] clk: ux500: prcmu: " Maxime Ripard
                   ` (31 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Jonathan Hunter, Peter De Schrijver,
	Prashant Gaikwad, Thierry Reding, linux-tegra

The Tegra periph nodiv clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

However, the upstream device trees seem to use assigned-clock-parents on
that clock to force the parent at boot time, so it's likely that the
author intent was to force the parent through the device tree and
prevent any reparenting but through an explicit call to
clk_set_parent().

This case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/tegra/clk-periph.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index 79ca3aa072b7..ea443366e972 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -140,6 +140,7 @@ const struct clk_ops tegra_clk_periph_ops = {
 };
 
 static const struct clk_ops tegra_clk_periph_nodiv_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = clk_periph_get_parent,
 	.set_parent = clk_periph_set_parent,
 	.is_enabled = clk_periph_is_enabled,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 37/68] clk: ux500: prcmu: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (35 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 36/68] clk: tegra: periph: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 38/68] clk: ux500: sysctrl: " Maxime Ripard
                   ` (30 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Ulf Hansson, linux-arm-kernel, Linus Walleij

The UX500 PRCMU "clkout" clock implements a mux with a set_parent hook,
but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The PRCMU binding also allows to specify the default clock parent
through a device tree cell. This will be enforced at prepare time by the
driver.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

The result is that the driver relies on prepare to set the default
parent, and thus the set_parent hook is effectively unused by design.

We can make that decision explicit by setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent() that will keep the
same behaviour. Indeed, if no determine_rate implementation is provided,
clk_round_rate() (through clk_core_round_rate_nolock()) will call itself
on the parent if CLK_SET_RATE_PARENT is set, and will not change the
clock rate otherwise.

Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/ux500/clk-prcmu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
index 4deb37f19a7c..5cbf24c94606 100644
--- a/drivers/clk/ux500/clk-prcmu.c
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -344,6 +344,7 @@ static const struct clk_ops clk_prcmu_clkout_ops = {
 	.prepare = clk_prcmu_clkout_prepare,
 	.unprepare = clk_prcmu_clkout_unprepare,
 	.recalc_rate = clk_prcmu_clkout_recalc_rate,
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = clk_prcmu_clkout_get_parent,
 	.set_parent = clk_prcmu_clkout_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 38/68] clk: ux500: sysctrl: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (36 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 37/68] clk: ux500: prcmu: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 39/68] clk: versatile: sp810: " Maxime Ripard
                   ` (29 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Ulf Hansson, linux-arm-kernel, Linus Walleij

The UX500 sysctrl "set_parent" clocks implement a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/ux500/clk-sysctrl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c
index 702f2f8b43fa..ba3258c88d28 100644
--- a/drivers/clk/ux500/clk-sysctrl.c
+++ b/drivers/clk/ux500/clk-sysctrl.c
@@ -110,6 +110,7 @@ static const struct clk_ops clk_sysctrl_gate_fixed_rate_ops = {
 };
 
 static const struct clk_ops clk_sysctrl_set_parent_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = clk_sysctrl_set_parent,
 	.get_parent = clk_sysctrl_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 39/68] clk: versatile: sp810: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (37 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 38/68] clk: ux500: sysctrl: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:30   ` Linus Walleij
  2023-05-05 11:25 ` [PATCH v4 40/68] drm/tegra: sor: " Maxime Ripard
                   ` (28 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Linus Walleij, Pawel Moll, linux-arm-kernel

The Versatile sp810 "timerclken" clock implements a mux with a
set_parent hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

This mismatch is probably due to the fact that the driver introduction
predates the determine_rate introduction, and it was never revised since
then.

The default, implicit, behaviour that has been in use so far has thus
been to simply keep using the current parent in all cases. This is also
the behaviour of the new clk_hw_determine_rate_no_reparent() helper, so
we can simply use it to make our expectation explicit.

Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/versatile/clk-sp810.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c
index caf0cd2fb5b6..45adac1b4630 100644
--- a/drivers/clk/versatile/clk-sp810.c
+++ b/drivers/clk/versatile/clk-sp810.c
@@ -63,6 +63,7 @@ static int clk_sp810_timerclken_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops clk_sp810_timerclken_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.get_parent = clk_sp810_timerclken_get_parent,
 	.set_parent = clk_sp810_timerclken_set_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 40/68] drm/tegra: sor: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (38 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 39/68] clk: versatile: sp810: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 41/68] phy: cadence: sierra: " Maxime Ripard
                   ` (27 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Daniel Vetter, David Airlie,
	Jonathan Hunter, Mikko Perttunen, Thierry Reding, dri-devel,
	linux-tegra

The Tegra sor pad clock implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: David Airlie <airlied@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Mikko Perttunen <mperttunen@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/gpu/drm/tegra/sor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index fbb63d755496..abd6e3b92293 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -586,6 +586,7 @@ static u8 tegra_clk_sor_pad_get_parent(struct clk_hw *hw)
 }
 
 static const struct clk_ops tegra_clk_sor_pad_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = tegra_clk_sor_pad_set_parent,
 	.get_parent = tegra_clk_sor_pad_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 41/68] phy: cadence: sierra: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (39 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 40/68] drm/tegra: sor: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 42/68] phy: cadence: torrent: " Maxime Ripard
                   ` (26 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Kishon Vijay Abraham I, Vinod Koul, linux-phy

The Cadence Sierra PLL clock implements a mux with a set_parent hook,
but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the flag
CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
to __clk_mux_determine_rate(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems
unlikely.

Cc: Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: linux-phy@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/phy/cadence/phy-cadence-sierra.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 13fcd3a65fe9..7df9c79a772a 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -720,6 +720,7 @@ static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops cdns_sierra_pll_mux_ops = {
+	.determine_rate = __clk_mux_determine_rate,
 	.set_parent = cdns_sierra_pll_mux_set_parent,
 	.get_parent = cdns_sierra_pll_mux_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 42/68] phy: cadence: torrent: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (40 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 41/68] phy: cadence: sierra: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 43/68] phy: ti: am654-serdes: " Maxime Ripard
                   ` (25 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Kishon Vijay Abraham I, Vinod Koul, linux-phy

The Cadence Torrent refclk clock implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the flag
CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
to __clk_mux_determine_rate(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems
unlikely.

Cc: Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: linux-phy@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 3831f596d50c..62e59d1bb9c3 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1861,6 +1861,7 @@ static const struct clk_ops cdns_torrent_refclk_driver_ops = {
 	.enable = cdns_torrent_refclk_driver_enable,
 	.disable = cdns_torrent_refclk_driver_disable,
 	.is_enabled = cdns_torrent_refclk_driver_is_enabled,
+	.determine_rate = __clk_mux_determine_rate,
 	.set_parent = cdns_torrent_refclk_driver_set_parent,
 	.get_parent = cdns_torrent_refclk_driver_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 43/68] phy: ti: am654-serdes: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (41 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 42/68] phy: cadence: torrent: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 44/68] phy: ti: j721e-wiz: " Maxime Ripard
                   ` (24 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Kishon Vijay Abraham I, Vinod Koul, linux-phy

The TI AM654 SerDes clock implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the flag
CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
to __clk_mux_determine_rate(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems
unlikely.

Cc: Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: linux-phy@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/phy/ti/phy-am654-serdes.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c
index 4ed2d951d3df..3f1d43e8b7ad 100644
--- a/drivers/phy/ti/phy-am654-serdes.c
+++ b/drivers/phy/ti/phy-am654-serdes.c
@@ -634,6 +634,7 @@ static int serdes_am654_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops serdes_am654_clk_mux_ops = {
+	.determine_rate = __clk_mux_determine_rate,
 	.set_parent = serdes_am654_clk_mux_set_parent,
 	.get_parent = serdes_am654_clk_mux_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 44/68] phy: ti: j721e-wiz: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (42 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 43/68] phy: ti: am654-serdes: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 45/68] rtc: sun6i: " Maxime Ripard
                   ` (23 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Kishon Vijay Abraham I, Vinod Koul, linux-phy

The TI J721e Wiz clock implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the flag
CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
to __clk_mux_determine_rate(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems
unlikely.

Cc: Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: linux-phy@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/phy/ti/phy-j721e-wiz.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index d91923799df2..fc3cd98c60ff 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -801,6 +801,7 @@ static int wiz_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 }
 
 static const struct clk_ops wiz_clk_mux_ops = {
+	.determine_rate = __clk_mux_determine_rate,
 	.set_parent = wiz_clk_mux_set_parent,
 	.get_parent = wiz_clk_mux_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 45/68] rtc: sun6i: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (43 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 44/68] phy: ti: j721e-wiz: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 18:46   ` Jernej Škrabec
  2023-05-05 11:25 ` [PATCH v4 46/68] ASoC: tlv320aic32x4: " Maxime Ripard
                   ` (22 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Alessandro Zummo, Alexandre Belloni,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, linux-arm-kernel,
	linux-rtc, linux-sunxi

The Allwinner sun6i RTC clock implements a mux with a set_parent hook,
but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Chen-Yu Tsai <wens@csie.org>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Samuel Holland <samuel@sholland.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-rtc@vger.kernel.org
Cc: linux-sunxi@lists.linux.dev
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/rtc/rtc-sun6i.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index dc76537f1b62..71548dd59a3a 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -214,6 +214,7 @@ static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index)
 
 static const struct clk_ops sun6i_rtc_osc_ops = {
 	.recalc_rate	= sun6i_rtc_osc_recalc_rate,
+	.determine_rate	= clk_hw_determine_rate_no_reparent,
 
 	.get_parent	= sun6i_rtc_osc_get_parent,
 	.set_parent	= sun6i_rtc_osc_set_parent,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 46/68] ASoC: tlv320aic32x4: Add a determine_rate hook
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (44 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 45/68] rtc: sun6i: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 47/68] clk: actions: composite: div: Switch to determine_rate Maxime Ripard
                   ` (21 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Jaroslav Kysela, Liam Girdwood,
	Mark Brown, Takashi Iwai, alsa-devel

The tlv320aic32x4 clkin clock implements a mux with a set_parent hook,
but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidates to
trigger that parent change are either the assigned-clock-parents device
tree property or a call to clk_set_rate(), with determine_rate()
figuring out which parent is the best suited for a given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

Similarly, it doesn't look like the device tree using that clock driver
uses any of the assigned-clock properties on that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the determine_rate
implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
determine_rate implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: alsa-devel@alsa-project.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 sound/soc/codecs/tlv320aic32x4-clk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/codecs/tlv320aic32x4-clk.c b/sound/soc/codecs/tlv320aic32x4-clk.c
index 2f78e6820c75..80cbc6bc6847 100644
--- a/sound/soc/codecs/tlv320aic32x4-clk.c
+++ b/sound/soc/codecs/tlv320aic32x4-clk.c
@@ -292,6 +292,7 @@ static u8 clk_aic32x4_codec_clkin_get_parent(struct clk_hw *hw)
 }
 
 static const struct clk_ops aic32x4_codec_clkin_ops = {
+	.determine_rate = clk_hw_determine_rate_no_reparent,
 	.set_parent = clk_aic32x4_codec_clkin_set_parent,
 	.get_parent = clk_aic32x4_codec_clkin_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 47/68] clk: actions: composite: div: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (45 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 46/68] ASoC: tlv320aic32x4: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 48/68] clk: actions: composite: fact: " Maxime Ripard
                   ` (20 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Andreas Färber,
	Manivannan Sadhasivam, linux-actions, linux-arm-kernel

The Actions composite divider clocks implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: "Andreas Färber" <afaerber@suse.de>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: linux-actions@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/actions/owl-composite.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/actions/owl-composite.c b/drivers/clk/actions/owl-composite.c
index e7784f9e5bf6..2f1e282134b2 100644
--- a/drivers/clk/actions/owl-composite.c
+++ b/drivers/clk/actions/owl-composite.c
@@ -53,13 +53,19 @@ static int owl_comp_is_enabled(struct clk_hw *hw)
 	return owl_gate_clk_is_enabled(common, &comp->gate_hw);
 }
 
-static long owl_comp_div_round_rate(struct clk_hw *hw, unsigned long rate,
-				unsigned long *parent_rate)
+static int owl_comp_div_determine_rate(struct clk_hw *hw,
+				       struct clk_rate_request *req)
 {
 	struct owl_composite *comp = hw_to_owl_comp(hw);
+	long rate;
 
-	return owl_divider_helper_round_rate(&comp->common, &comp->rate.div_hw,
-					rate, parent_rate);
+	rate = owl_divider_helper_round_rate(&comp->common, &comp->rate.div_hw,
+					     req->rate, &req->best_parent_rate);
+	if (rate < 0)
+		return rate;
+
+	req->rate = rate;
+	return 0;
 }
 
 static unsigned long owl_comp_div_recalc_rate(struct clk_hw *hw,
@@ -152,7 +158,7 @@ const struct clk_ops owl_comp_div_ops = {
 	.is_enabled	= owl_comp_is_enabled,
 
 	/* div_ops */
-	.round_rate	= owl_comp_div_round_rate,
+	.determine_rate	= owl_comp_div_determine_rate,
 	.recalc_rate	= owl_comp_div_recalc_rate,
 	.set_rate	= owl_comp_div_set_rate,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 48/68] clk: actions: composite: fact: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (46 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 47/68] clk: actions: composite: div: Switch to determine_rate Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 49/68] clk: at91: smd: " Maxime Ripard
                   ` (19 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Andreas Färber,
	Manivannan Sadhasivam, linux-actions, linux-arm-kernel

The Actions composite factor clocks implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: "Andreas Färber" <afaerber@suse.de>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: linux-actions@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/actions/owl-composite.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/actions/owl-composite.c b/drivers/clk/actions/owl-composite.c
index 2f1e282134b2..48f177f6ce9c 100644
--- a/drivers/clk/actions/owl-composite.c
+++ b/drivers/clk/actions/owl-composite.c
@@ -86,14 +86,20 @@ static int owl_comp_div_set_rate(struct clk_hw *hw, unsigned long rate,
 					rate, parent_rate);
 }
 
-static long owl_comp_fact_round_rate(struct clk_hw *hw, unsigned long rate,
-			unsigned long *parent_rate)
+static int owl_comp_fact_determine_rate(struct clk_hw *hw,
+					struct clk_rate_request *req)
 {
 	struct owl_composite *comp = hw_to_owl_comp(hw);
+	long rate;
 
-	return owl_factor_helper_round_rate(&comp->common,
-					&comp->rate.factor_hw,
-					rate, parent_rate);
+	rate = owl_factor_helper_round_rate(&comp->common,
+					    &comp->rate.factor_hw,
+					    req->rate, &req->best_parent_rate);
+	if (rate < 0)
+		return rate;
+
+	req->rate = rate;
+	return 0;
 }
 
 static unsigned long owl_comp_fact_recalc_rate(struct clk_hw *hw,
@@ -175,7 +181,7 @@ const struct clk_ops owl_comp_fact_ops = {
 	.is_enabled	= owl_comp_is_enabled,
 
 	/* fact_ops */
-	.round_rate	= owl_comp_fact_round_rate,
+	.determine_rate	= owl_comp_fact_determine_rate,
 	.recalc_rate	= owl_comp_fact_recalc_rate,
 	.set_rate	= owl_comp_fact_set_rate,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 49/68] clk: at91: smd: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (47 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 48/68] clk: actions: composite: fact: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 50/68] clk: axi-clkgen: " Maxime Ripard
                   ` (18 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Alexandre Belloni, Claudiu Beznea,
	Nicolas Ferre, linux-arm-kernel

The Atmel SAM9x5 SMD clocks implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/at91/clk-smd.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
index 160378438f1b..09c649c8598e 100644
--- a/drivers/clk/at91/clk-smd.c
+++ b/drivers/clk/at91/clk-smd.c
@@ -36,26 +36,31 @@ static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw,
 	return parent_rate / (smddiv + 1);
 }
 
-static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate,
-					  unsigned long *parent_rate)
+static int at91sam9x5_clk_smd_determine_rate(struct clk_hw *hw,
+					     struct clk_rate_request *req)
 {
 	unsigned long div;
 	unsigned long bestrate;
 	unsigned long tmp;
 
-	if (rate >= *parent_rate)
-		return *parent_rate;
+	if (req->rate >= req->best_parent_rate) {
+		req->rate = req->best_parent_rate;
+		return 0;
+	}
 
-	div = *parent_rate / rate;
-	if (div > SMD_MAX_DIV)
-		return *parent_rate / (SMD_MAX_DIV + 1);
+	div = req->best_parent_rate / req->rate;
+	if (div > SMD_MAX_DIV) {
+		req->rate = req->best_parent_rate / (SMD_MAX_DIV + 1);
+		return 0;
+	}
 
-	bestrate = *parent_rate / div;
-	tmp = *parent_rate / (div + 1);
-	if (bestrate - rate > rate - tmp)
+	bestrate = req->best_parent_rate / div;
+	tmp = req->best_parent_rate / (div + 1);
+	if (bestrate - req->rate > req->rate - tmp)
 		bestrate = tmp;
 
-	return bestrate;
+	req->rate = bestrate;
+	return 0;
 }
 
 static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index)
@@ -98,7 +103,7 @@ static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate,
 
 static const struct clk_ops at91sam9x5_smd_ops = {
 	.recalc_rate = at91sam9x5_clk_smd_recalc_rate,
-	.round_rate = at91sam9x5_clk_smd_round_rate,
+	.determine_rate = at91sam9x5_clk_smd_determine_rate,
 	.get_parent = at91sam9x5_clk_smd_get_parent,
 	.set_parent = at91sam9x5_clk_smd_set_parent,
 	.set_rate = at91sam9x5_clk_smd_set_rate,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 50/68] clk: axi-clkgen: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (48 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 49/68] clk: at91: smd: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 51/68] clk: cdce706: divider: " Maxime Ripard
                   ` (17 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The AXI clkgen clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-axi-clkgen.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
index a04a3d38c76e..bf4d8ddc93ae 100644
--- a/drivers/clk/clk-axi-clkgen.c
+++ b/drivers/clk/clk-axi-clkgen.c
@@ -384,23 +384,25 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
 	return 0;
 }
 
-static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
-	unsigned long *parent_rate)
+static int axi_clkgen_determine_rate(struct clk_hw *hw,
+				     struct clk_rate_request *req)
 {
 	struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(hw);
 	const struct axi_clkgen_limits *limits = &axi_clkgen->limits;
 	unsigned int d, m, dout;
 	unsigned long long tmp;
 
-	axi_clkgen_calc_params(limits, *parent_rate, rate, &d, &m, &dout);
+	axi_clkgen_calc_params(limits, req->best_parent_rate, req->rate,
+			       &d, &m, &dout);
 
 	if (d == 0 || dout == 0 || m == 0)
 		return -EINVAL;
 
-	tmp = (unsigned long long)*parent_rate * m;
+	tmp = (unsigned long long)req->best_parent_rate * m;
 	tmp = DIV_ROUND_CLOSEST_ULL(tmp, dout * d);
 
-	return min_t(unsigned long long, tmp, LONG_MAX);
+	req->rate = min_t(unsigned long long, tmp, LONG_MAX);
+	return 0;
 }
 
 static unsigned int axi_clkgen_get_div(struct axi_clkgen *axi_clkgen,
@@ -495,7 +497,7 @@ static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw)
 
 static const struct clk_ops axi_clkgen_ops = {
 	.recalc_rate = axi_clkgen_recalc_rate,
-	.round_rate = axi_clkgen_round_rate,
+	.determine_rate = axi_clkgen_determine_rate,
 	.set_rate = axi_clkgen_set_rate,
 	.enable = axi_clkgen_enable,
 	.disable = axi_clkgen_disable,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 51/68] clk: cdce706: divider: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (49 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 50/68] clk: axi-clkgen: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 52/68] clk: cdce706: clkout: " Maxime Ripard
                   ` (16 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard, Max Filippov

The cdce706 divider clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-cdce706.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c
index 139aa0954cc1..1c112bb51be6 100644
--- a/drivers/clk/clk-cdce706.c
+++ b/drivers/clk/clk-cdce706.c
@@ -288,18 +288,19 @@ static unsigned long cdce706_divider_recalc_rate(struct clk_hw *hw,
 	return 0;
 }
 
-static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,
-				       unsigned long *parent_rate)
+static int cdce706_divider_determine_rate(struct clk_hw *hw,
+					  struct clk_rate_request *req)
 {
 	struct cdce706_hw_data *hwd = to_hw_data(hw);
 	struct cdce706_dev_data *cdce = hwd->dev_data;
+	unsigned long rate = req->rate;
 	unsigned long mul, div;
 
 	dev_dbg(&hwd->dev_data->client->dev,
 		"%s, rate: %lu, parent_rate: %lu\n",
-		__func__, rate, *parent_rate);
+		__func__, rate, req->best_parent_rate);
 
-	rational_best_approximation(rate, *parent_rate,
+	rational_best_approximation(rate, req->best_parent_rate,
 				    1, CDCE706_DIVIDER_DIVIDER_MAX,
 				    &mul, &div);
 	if (!mul)
@@ -344,8 +345,8 @@ static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,
 
 		dev_dbg(&hwd->dev_data->client->dev,
 			"%s, altering parent rate: %lu -> %lu\n",
-			__func__, *parent_rate, rate * div);
-		*parent_rate = rate * div;
+			__func__, req->best_parent_rate, rate * div);
+		req->best_parent_rate = rate * div;
 	}
 	hwd->div = div;
 
@@ -353,7 +354,8 @@ static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,
 		"%s, divider: %d, div: %lu\n",
 		__func__, hwd->idx, div);
 
-	return *parent_rate / div;
+	req->rate = req->best_parent_rate / div;
+	return 0;
 }
 
 static int cdce706_divider_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -375,7 +377,7 @@ static const struct clk_ops cdce706_divider_ops = {
 	.set_parent = cdce706_divider_set_parent,
 	.get_parent = cdce706_divider_get_parent,
 	.recalc_rate = cdce706_divider_recalc_rate,
-	.round_rate = cdce706_divider_round_rate,
+	.determine_rate = cdce706_divider_determine_rate,
 	.set_rate = cdce706_divider_set_rate,
 };
 

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 52/68] clk: cdce706: clkout: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (50 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 51/68] clk: cdce706: divider: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 53/68] clk: si5341: " Maxime Ripard
                   ` (15 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard, Max Filippov

The cdce706 clkout clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-cdce706.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c
index 1c112bb51be6..34f57d36b7ff 100644
--- a/drivers/clk/clk-cdce706.c
+++ b/drivers/clk/clk-cdce706.c
@@ -423,11 +423,12 @@ static unsigned long cdce706_clkout_recalc_rate(struct clk_hw *hw,
 	return parent_rate;
 }
 
-static long cdce706_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
-				      unsigned long *parent_rate)
+static int cdce706_clkout_determine_rate(struct clk_hw *hw,
+					 struct clk_rate_request *req)
 {
-	*parent_rate = rate;
-	return rate;
+	req->best_parent_rate = req->rate;
+
+	return 0;
 }
 
 static int cdce706_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -442,7 +443,7 @@ static const struct clk_ops cdce706_clkout_ops = {
 	.set_parent = cdce706_clkout_set_parent,
 	.get_parent = cdce706_clkout_get_parent,
 	.recalc_rate = cdce706_clkout_recalc_rate,
-	.round_rate = cdce706_clkout_round_rate,
+	.determine_rate = cdce706_clkout_determine_rate,
 	.set_rate = cdce706_clkout_set_rate,
 };
 

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 53/68] clk: si5341: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (51 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 52/68] clk: cdce706: clkout: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 54/68] clk: si5351: pll: " Maxime Ripard
                   ` (14 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The SI5341 output clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-si5341.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
index 4b65def64109..68160510f448 100644
--- a/drivers/clk/clk-si5341.c
+++ b/drivers/clk/clk-si5341.c
@@ -828,19 +828,20 @@ static unsigned long si5341_output_clk_recalc_rate(struct clk_hw *hw,
 	return parent_rate / r_divider;
 }
 
-static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate,
-		unsigned long *parent_rate)
+static int si5341_output_clk_determine_rate(struct clk_hw *hw,
+					    struct clk_rate_request *req)
 {
+	unsigned long rate = req->rate;
 	unsigned long r;
 
 	if (!rate)
 		return 0;
 
-	r = *parent_rate >> 1;
+	r = req->best_parent_rate >> 1;
 
 	/* If rate is an even divisor, no changes to parent required */
 	if (r && !(r % rate))
-		return (long)rate;
+		return 0;
 
 	if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
 		if (rate > 200000000) {
@@ -850,14 +851,15 @@ static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 			/* Take a parent frequency near 400 MHz */
 			r = (400000000u / rate) & ~1;
 		}
-		*parent_rate = r * rate;
+		req->best_parent_rate = r * rate;
 	} else {
 		/* We cannot change our parent's rate, report what we can do */
 		r /= rate;
-		rate = *parent_rate / (r << 1);
+		rate = req->best_parent_rate / (r << 1);
 	}
 
-	return rate;
+	req->rate = rate;
+	return 0;
 }
 
 static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -930,7 +932,7 @@ static const struct clk_ops si5341_output_clk_ops = {
 	.prepare = si5341_output_clk_prepare,
 	.unprepare = si5341_output_clk_unprepare,
 	.recalc_rate = si5341_output_clk_recalc_rate,
-	.round_rate = si5341_output_clk_round_rate,
+	.determine_rate = si5341_output_clk_determine_rate,
 	.set_rate = si5341_output_clk_set_rate,
 	.set_parent = si5341_output_set_parent,
 	.get_parent = si5341_output_get_parent,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 54/68] clk: si5351: pll: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (52 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 53/68] clk: si5341: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 55/68] clk: si5351: msynth: " Maxime Ripard
                   ` (13 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The SI5351 PLL clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-si5351.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 4fcf7056717e..5992832774ad 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -442,11 +442,12 @@ static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
 	return (unsigned long)rate;
 }
 
-static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				  unsigned long *parent_rate)
+static int si5351_pll_determine_rate(struct clk_hw *hw,
+				     struct clk_rate_request *req)
 {
 	struct si5351_hw_data *hwdata =
 		container_of(hw, struct si5351_hw_data, hw);
+	unsigned long rate = req->rate;
 	unsigned long rfrac, denom, a, b, c;
 	unsigned long long lltmp;
 
@@ -456,18 +457,18 @@ static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 		rate = SI5351_PLL_VCO_MAX;
 
 	/* determine integer part of feedback equation */
-	a = rate / *parent_rate;
+	a = rate / req->best_parent_rate;
 
 	if (a < SI5351_PLL_A_MIN)
-		rate = *parent_rate * SI5351_PLL_A_MIN;
+		rate = req->best_parent_rate * SI5351_PLL_A_MIN;
 	if (a > SI5351_PLL_A_MAX)
-		rate = *parent_rate * SI5351_PLL_A_MAX;
+		rate = req->best_parent_rate * SI5351_PLL_A_MAX;
 
 	/* find best approximation for b/c = fVCO mod fIN */
 	denom = 1000 * 1000;
-	lltmp = rate % (*parent_rate);
+	lltmp = rate % (req->best_parent_rate);
 	lltmp *= denom;
-	do_div(lltmp, *parent_rate);
+	do_div(lltmp, req->best_parent_rate);
 	rfrac = (unsigned long)lltmp;
 
 	b = 0;
@@ -484,19 +485,20 @@ static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	hwdata->params.p1 -= 512;
 
 	/* recalculate rate by fIN * (a + b/c) */
-	lltmp  = *parent_rate;
+	lltmp  = req->best_parent_rate;
 	lltmp *= b;
 	do_div(lltmp, c);
 
 	rate  = (unsigned long)lltmp;
-	rate += *parent_rate * a;
+	rate += req->best_parent_rate * a;
 
 	dev_dbg(&hwdata->drvdata->client->dev,
 		"%s - %s: a = %lu, b = %lu, c = %lu, parent_rate = %lu, rate = %lu\n",
 		__func__, clk_hw_get_name(hw), a, b, c,
-		*parent_rate, rate);
+		req->best_parent_rate, rate);
 
-	return rate;
+	req->rate = rate;
+	return 0;
 }
 
 static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -533,7 +535,7 @@ static const struct clk_ops si5351_pll_ops = {
 	.set_parent = si5351_pll_set_parent,
 	.get_parent = si5351_pll_get_parent,
 	.recalc_rate = si5351_pll_recalc_rate,
-	.round_rate = si5351_pll_round_rate,
+	.determine_rate = si5351_pll_determine_rate,
 	.set_rate = si5351_pll_set_rate,
 };
 

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 55/68] clk: si5351: msynth: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (53 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 54/68] clk: si5351: pll: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 56/68] clk: si5351: clkout: " Maxime Ripard
                   ` (12 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The SI5351 msynth clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-si5351.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 5992832774ad..07bd67d681f9 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -642,11 +642,12 @@ static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
 	return (unsigned long)rate;
 }
 
-static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
-				     unsigned long *parent_rate)
+static int si5351_msynth_determine_rate(struct clk_hw *hw,
+					struct clk_rate_request *req)
 {
 	struct si5351_hw_data *hwdata =
 		container_of(hw, struct si5351_hw_data, hw);
+	unsigned long rate = req->rate;
 	unsigned long long lltmp;
 	unsigned long a, b, c;
 	int divby4;
@@ -681,10 +682,10 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
 		b = 0;
 		c = 1;
 
-		*parent_rate = a * rate;
+		req->best_parent_rate = a * rate;
 	} else if (hwdata->num >= 6) {
 		/* determine the closest integer divider */
-		a = DIV_ROUND_CLOSEST(*parent_rate, rate);
+		a = DIV_ROUND_CLOSEST(req->best_parent_rate, rate);
 		if (a < SI5351_MULTISYNTH_A_MIN)
 			a = SI5351_MULTISYNTH_A_MIN;
 		if (a > SI5351_MULTISYNTH67_A_MAX)
@@ -702,7 +703,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
 		}
 
 		/* determine integer part of divider equation */
-		a = *parent_rate / rate;
+		a = req->best_parent_rate / rate;
 		if (a < SI5351_MULTISYNTH_A_MIN)
 			a = SI5351_MULTISYNTH_A_MIN;
 		if (a > SI5351_MULTISYNTH_A_MAX)
@@ -710,7 +711,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
 
 		/* find best approximation for b/c = fVCO mod fOUT */
 		denom = 1000 * 1000;
-		lltmp = (*parent_rate) % rate;
+		lltmp = req->best_parent_rate % rate;
 		lltmp *= denom;
 		do_div(lltmp, rate);
 		rfrac = (unsigned long)lltmp;
@@ -724,7 +725,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
 	}
 
 	/* recalculate rate by fOUT = fIN / (a + b/c) */
-	lltmp  = *parent_rate;
+	lltmp  = req->best_parent_rate;
 	lltmp *= c;
 	do_div(lltmp, a * c + b);
 	rate  = (unsigned long)lltmp;
@@ -749,9 +750,11 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
 	dev_dbg(&hwdata->drvdata->client->dev,
 		"%s - %s: a = %lu, b = %lu, c = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n",
 		__func__, clk_hw_get_name(hw), a, b, c, divby4,
-		*parent_rate, rate);
+		req->best_parent_rate, rate);
 
-	return rate;
+	req->rate = rate;
+
+	return 0;
 }
 
 static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -791,7 +794,7 @@ static const struct clk_ops si5351_msynth_ops = {
 	.set_parent = si5351_msynth_set_parent,
 	.get_parent = si5351_msynth_get_parent,
 	.recalc_rate = si5351_msynth_recalc_rate,
-	.round_rate = si5351_msynth_round_rate,
+	.determine_rate = si5351_msynth_determine_rate,
 	.set_rate = si5351_msynth_set_rate,
 };
 

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 56/68] clk: si5351: clkout: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (54 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 55/68] clk: si5351: msynth: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:25 ` [PATCH v4 57/68] clk: da8xx: clk48: " Maxime Ripard
                   ` (11 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The SI5351 clkout clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk-si5351.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 07bd67d681f9..76487f568a6e 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -1037,11 +1037,12 @@ static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
 	return parent_rate >> rdiv;
 }
 
-static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
-				     unsigned long *parent_rate)
+static int si5351_clkout_determine_rate(struct clk_hw *hw,
+					struct clk_rate_request *req)
 {
 	struct si5351_hw_data *hwdata =
 		container_of(hw, struct si5351_hw_data, hw);
+	unsigned long rate = req->rate;
 	unsigned char rdiv;
 
 	/* clkout6/7 can only handle output freqencies < 150MHz */
@@ -1063,13 +1064,13 @@ static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
 			rdiv += 1;
 			rate *= 2;
 		}
-		*parent_rate = rate;
+		req->best_parent_rate = rate;
 	} else {
 		unsigned long new_rate, new_err, err;
 
 		/* round to closed rdiv */
 		rdiv = SI5351_OUTPUT_CLK_DIV_1;
-		new_rate = *parent_rate;
+		new_rate = req->best_parent_rate;
 		err = abs(new_rate - rate);
 		do {
 			new_rate >>= 1;
@@ -1080,14 +1081,15 @@ static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
 			err = new_err;
 		} while (1);
 	}
-	rate = *parent_rate >> rdiv;
+	rate = req->best_parent_rate >> rdiv;
 
 	dev_dbg(&hwdata->drvdata->client->dev,
 		"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
 		__func__, clk_hw_get_name(hw), (1 << rdiv),
-		*parent_rate, rate);
+		req->best_parent_rate, rate);
 
-	return rate;
+	req->rate = rate;
+	return 0;
 }
 
 static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1147,7 +1149,7 @@ static const struct clk_ops si5351_clkout_ops = {
 	.set_parent = si5351_clkout_set_parent,
 	.get_parent = si5351_clkout_get_parent,
 	.recalc_rate = si5351_clkout_recalc_rate,
-	.round_rate = si5351_clkout_round_rate,
+	.determine_rate = si5351_clkout_determine_rate,
 	.set_rate = si5351_clkout_set_rate,
 };
 

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 57/68] clk: da8xx: clk48: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (55 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 56/68] clk: si5351: clkout: " Maxime Ripard
@ 2023-05-05 11:25 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 58/68] clk: imx: scu: " Maxime Ripard
                   ` (10 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:25 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, David Lechner, Sekhar Nori

The TI DA8xx USB0 clk48 clocks implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: David Lechner <david@lechnology.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Acked-by: David Lechner <david@lechnology.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/davinci/da8xx-cfgchip.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
index 1bbcc8e43bc5..e5b2cdfe88ce 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -462,10 +462,12 @@ static unsigned long da8xx_usb0_clk48_recalc_rate(struct clk_hw *hw,
 	return 48000000;
 }
 
-static long da8xx_usb0_clk48_round_rate(struct clk_hw *hw, unsigned long rate,
-					unsigned long *parent_rate)
+static int da8xx_usb0_clk48_determine_rate(struct clk_hw *hw,
+					   struct clk_rate_request *req)
 {
-	return 48000000;
+	req->rate = 48000000;
+
+	return 0;
 }
 
 static int da8xx_usb0_clk48_set_parent(struct clk_hw *hw, u8 index)
@@ -494,7 +496,7 @@ static const struct clk_ops da8xx_usb0_clk48_ops = {
 	.disable	= da8xx_usb0_clk48_disable,
 	.is_enabled	= da8xx_usb0_clk48_is_enabled,
 	.recalc_rate	= da8xx_usb0_clk48_recalc_rate,
-	.round_rate	= da8xx_usb0_clk48_round_rate,
+	.determine_rate	= da8xx_usb0_clk48_determine_rate,
 	.set_parent	= da8xx_usb0_clk48_set_parent,
 	.get_parent	= da8xx_usb0_clk48_get_parent,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 58/68] clk: imx: scu: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (56 preceding siblings ...)
  2023-05-05 11:25 ` [PATCH v4 57/68] clk: da8xx: clk48: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 59/68] clk: ingenic: cgu: " Maxime Ripard
                   ` (9 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Abel Vesa, Fabio Estevam, Peng Fan,
	Sascha Hauer, Shawn Guo, linux-arm-kernel, NXP Linux Team,
	Pengutronix Kernel Team

The iMX SCU clocks implements a mux with a set_parent hook, but doesn't
provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. The round_rate()
implementation being shared with other clocks, it's not removed.

And if it was an oversight, the clock behaviour can be adjusted later
on.

Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/imx/clk-scu.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index 417f893f8895..725b7b3edb63 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -250,6 +250,23 @@ static unsigned long clk_scu_recalc_rate(struct clk_hw *hw,
 	return le32_to_cpu(msg.data.resp.rate);
 }
 
+/*
+ * clk_scu_determine_rate - Returns the closest rate for a SCU clock
+ * @hw: clock to round rate for
+ * @req: clock rate request
+ *
+ * Returns 0 on success, a negative error on failure
+ */
+static int clk_scu_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	/*
+	 * Assume we support all the requested rate and let the SCU firmware
+	 * to handle the left work
+	 */
+	return 0;
+}
+
 /*
  * clk_scu_round_rate - Round clock rate for a SCU clock
  * @hw: clock to round rate for
@@ -425,7 +442,7 @@ static void clk_scu_unprepare(struct clk_hw *hw)
 
 static const struct clk_ops clk_scu_ops = {
 	.recalc_rate = clk_scu_recalc_rate,
-	.round_rate = clk_scu_round_rate,
+	.determine_rate = clk_scu_determine_rate,
 	.set_rate = clk_scu_set_rate,
 	.get_parent = clk_scu_get_parent,
 	.set_parent = clk_scu_set_parent,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 59/68] clk: ingenic: cgu: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (57 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 58/68] clk: imx: scu: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 60/68] clk: ingenic: tcu: " Maxime Ripard
                   ` (8 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Paul Cercueil, linux-mips

The Ingenic CGU clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Paul Cercueil <paul@crapouillou.net>
Cc: linux-mips@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/ingenic/cgu.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 1f7ba30f5a1b..0c9c8344ad11 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -491,22 +491,23 @@ ingenic_clk_calc_div(struct clk_hw *hw,
 	return div;
 }
 
-static long
-ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
-		       unsigned long *parent_rate)
+static int ingenic_clk_determine_rate(struct clk_hw *hw,
+				      struct clk_rate_request *req)
 {
 	struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
 	const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
 	unsigned int div = 1;
 
 	if (clk_info->type & CGU_CLK_DIV)
-		div = ingenic_clk_calc_div(hw, clk_info, *parent_rate, req_rate);
+		div = ingenic_clk_calc_div(hw, clk_info, req->best_parent_rate,
+					   req->rate);
 	else if (clk_info->type & CGU_CLK_FIXDIV)
 		div = clk_info->fixdiv.div;
 	else if (clk_hw_can_set_rate_parent(hw))
-		*parent_rate = req_rate;
+		req->best_parent_rate = req->rate;
 
-	return DIV_ROUND_UP(*parent_rate, div);
+	req->rate = DIV_ROUND_UP(req->best_parent_rate, div);
+	return 0;
 }
 
 static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu,
@@ -626,7 +627,7 @@ static const struct clk_ops ingenic_clk_ops = {
 	.set_parent = ingenic_clk_set_parent,
 
 	.recalc_rate = ingenic_clk_recalc_rate,
-	.round_rate = ingenic_clk_round_rate,
+	.determine_rate = ingenic_clk_determine_rate,
 	.set_rate = ingenic_clk_set_rate,
 
 	.enable = ingenic_clk_enable,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 60/68] clk: ingenic: tcu: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (58 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 59/68] clk: ingenic: cgu: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 61/68] clk: sprd: composite: " Maxime Ripard
                   ` (7 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Paul Cercueil, linux-mips

The Ingenic TCU clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Paul Cercueil <paul@crapouillou.net>
Cc: linux-mips@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/ingenic/tcu.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c
index d5544cbc5c48..7d04ef40b7cf 100644
--- a/drivers/clk/ingenic/tcu.c
+++ b/drivers/clk/ingenic/tcu.c
@@ -178,18 +178,21 @@ static u8 ingenic_tcu_get_prescale(unsigned long rate, unsigned long req_rate)
 	return 5; /* /1024 divider */
 }
 
-static long ingenic_tcu_round_rate(struct clk_hw *hw, unsigned long req_rate,
-		unsigned long *parent_rate)
+static int ingenic_tcu_determine_rate(struct clk_hw *hw,
+				      struct clk_rate_request *req)
 {
-	unsigned long rate = *parent_rate;
+	unsigned long rate = req->best_parent_rate;
 	u8 prescale;
 
-	if (req_rate > rate)
-		return rate;
+	if (req->rate > rate) {
+		req->rate = rate;
+		return 0;
+	}
 
-	prescale = ingenic_tcu_get_prescale(rate, req_rate);
+	prescale = ingenic_tcu_get_prescale(rate, req->rate);
 
-	return rate >> (prescale * 2);
+	req->rate = rate >> (prescale * 2);
+	return 0;
 }
 
 static int ingenic_tcu_set_rate(struct clk_hw *hw, unsigned long req_rate,
@@ -219,7 +222,7 @@ static const struct clk_ops ingenic_tcu_clk_ops = {
 	.set_parent	= ingenic_tcu_set_parent,
 
 	.recalc_rate	= ingenic_tcu_recalc_rate,
-	.round_rate	= ingenic_tcu_round_rate,
+	.determine_rate	= ingenic_tcu_determine_rate,
 	.set_rate	= ingenic_tcu_set_rate,
 
 	.enable		= ingenic_tcu_enable,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 61/68] clk: sprd: composite: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (59 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 60/68] clk: ingenic: tcu: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-06-13 17:11   ` Harshit Mogalapalli
  2023-05-05 11:26 ` [PATCH v4 62/68] clk: st: flexgen: " Maxime Ripard
                   ` (6 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Baolin Wang, Chunyan Zhang, Orson Zhai

The Spreadtrum composite clocks implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Chunyan Zhang <zhang.lyra@gmail.com>
Cc: Orson Zhai <orsonzhai@gmail.com>
Acked-by: Chunyan Zhang <zhang.lyra@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/sprd/composite.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
index ebb644820b1e..d3a852720c07 100644
--- a/drivers/clk/sprd/composite.c
+++ b/drivers/clk/sprd/composite.c
@@ -9,13 +9,19 @@
 
 #include "composite.h"
 
-static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
-				unsigned long *parent_rate)
+static int sprd_comp_determine_rate(struct clk_hw *hw,
+				    struct clk_rate_request *req)
 {
 	struct sprd_comp *cc = hw_to_sprd_comp(hw);
+	unsigned long rate;
 
-	return sprd_div_helper_round_rate(&cc->common, &cc->div,
-					 rate, parent_rate);
+	rate = sprd_div_helper_round_rate(&cc->common, &cc->div,
+					  req->rate, &req->best_parent_rate);
+	if (rate < 0)
+		return rate;
+
+	req->rate = rate;
+	return 0;
 }
 
 static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
@@ -53,7 +59,7 @@ const struct clk_ops sprd_comp_ops = {
 	.get_parent	= sprd_comp_get_parent,
 	.set_parent	= sprd_comp_set_parent,
 
-	.round_rate	= sprd_comp_round_rate,
+	.determine_rate	= sprd_comp_determine_rate,
 	.recalc_rate	= sprd_comp_recalc_rate,
 	.set_rate	= sprd_comp_set_rate,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 62/68] clk: st: flexgen: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (60 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 61/68] clk: sprd: composite: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 63/68] clk: stm32: composite: " Maxime Ripard
                   ` (5 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Maxime Ripard

The ST Flexgen clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/st/clk-flexgen.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
index 7ae4f656191e..5292208c4dd8 100644
--- a/drivers/clk/st/clk-flexgen.c
+++ b/drivers/clk/st/clk-flexgen.c
@@ -119,20 +119,21 @@ clk_best_div(unsigned long parent_rate, unsigned long rate)
 	return parent_rate / rate + ((rate > (2*(parent_rate % rate))) ? 0 : 1);
 }
 
-static long flexgen_round_rate(struct clk_hw *hw, unsigned long rate,
-				   unsigned long *prate)
+static int flexgen_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
 {
 	unsigned long div;
 
 	/* Round div according to exact prate and wished rate */
-	div = clk_best_div(*prate, rate);
+	div = clk_best_div(req->best_parent_rate, req->rate);
 
 	if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
-		*prate = rate * div;
-		return rate;
+		req->best_parent_rate = req->rate * div;
+		return 0;
 	}
 
-	return *prate / div;
+	req->rate = req->best_parent_rate / div;
+	return 0;
 }
 
 static unsigned long flexgen_recalc_rate(struct clk_hw *hw,
@@ -197,7 +198,7 @@ static const struct clk_ops flexgen_ops = {
 	.is_enabled = flexgen_is_enabled,
 	.get_parent = flexgen_get_parent,
 	.set_parent = flexgen_set_parent,
-	.round_rate = flexgen_round_rate,
+	.determine_rate = flexgen_determine_rate,
 	.recalc_rate = flexgen_recalc_rate,
 	.set_rate = flexgen_set_rate,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 63/68] clk: stm32: composite: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (61 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 62/68] clk: st: flexgen: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 64/68] clk: tegra: periph: " Maxime Ripard
                   ` (4 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Alexandre Torgue, Maxime Coquelin,
	linux-arm-kernel, linux-stm32

The STM32 composite clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/stm32/clk-stm32-core.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c
index 3247539683c9..d5aa09e9fce4 100644
--- a/drivers/clk/stm32/clk-stm32-core.c
+++ b/drivers/clk/stm32/clk-stm32-core.c
@@ -426,15 +426,15 @@ static unsigned long clk_stm32_composite_recalc_rate(struct clk_hw *hw,
 				      composite->div_id, parent_rate);
 }
 
-static long clk_stm32_composite_round_rate(struct clk_hw *hw, unsigned long rate,
-					   unsigned long *prate)
+static int clk_stm32_composite_determine_rate(struct clk_hw *hw,
+					      struct clk_rate_request *req)
 {
 	struct clk_stm32_composite *composite = to_clk_stm32_composite(hw);
-
 	const struct stm32_div_cfg *divider;
+	unsigned long rate;
 
 	if (composite->div_id == NO_STM32_DIV)
-		return rate;
+		return 0;
 
 	divider = &composite->clock_data->dividers[composite->div_id];
 
@@ -445,14 +445,24 @@ static long clk_stm32_composite_round_rate(struct clk_hw *hw, unsigned long rate
 		val =  readl(composite->base + divider->offset) >> divider->shift;
 		val &= clk_div_mask(divider->width);
 
-		return divider_ro_round_rate(hw, rate, prate, divider->table,
-				divider->width, divider->flags,
-				val);
+		rate = divider_ro_round_rate(hw, req->rate, &req->best_parent_rate,
+					     divider->table, divider->width, divider->flags,
+					     val);
+		if (rate < 0)
+			return rate;
+
+		req->rate = rate;
+		return 0;
 	}
 
-	return divider_round_rate_parent(hw, clk_hw_get_parent(hw),
-					 rate, prate, divider->table,
-					 divider->width, divider->flags);
+	rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw),
+					 req->rate, &req->best_parent_rate,
+					 divider->table, divider->width, divider->flags);
+	if (rate < 0)
+		return rate;
+
+	req->rate = rate;
+	return 0;
 }
 
 static u8 clk_stm32_composite_get_parent(struct clk_hw *hw)
@@ -602,7 +612,7 @@ static void clk_stm32_composite_disable_unused(struct clk_hw *hw)
 const struct clk_ops clk_stm32_composite_ops = {
 	.set_rate	= clk_stm32_composite_set_rate,
 	.recalc_rate	= clk_stm32_composite_recalc_rate,
-	.round_rate	= clk_stm32_composite_round_rate,
+	.determine_rate	= clk_stm32_composite_determine_rate,
 	.get_parent	= clk_stm32_composite_get_parent,
 	.set_parent	= clk_stm32_composite_set_parent,
 	.enable		= clk_stm32_composite_gate_enable,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 64/68] clk: tegra: periph: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (62 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 63/68] clk: stm32: composite: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 65/68] clk: tegra: super: " Maxime Ripard
                   ` (3 subsequent siblings)
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Jonathan Hunter, Peter De Schrijver,
	Prashant Gaikwad, Thierry Reding, linux-tegra

The Tegra periph clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/tegra/clk-periph.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index ea443366e972..0626650a7011 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -45,16 +45,22 @@ static unsigned long clk_periph_recalc_rate(struct clk_hw *hw,
 	return div_ops->recalc_rate(div_hw, parent_rate);
 }
 
-static long clk_periph_round_rate(struct clk_hw *hw, unsigned long rate,
-				  unsigned long *prate)
+static int clk_periph_determine_rate(struct clk_hw *hw,
+				     struct clk_rate_request *req)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 	const struct clk_ops *div_ops = periph->div_ops;
 	struct clk_hw *div_hw = &periph->divider.hw;
+	unsigned long rate;
 
 	__clk_hw_set_clk(div_hw, hw);
 
-	return div_ops->round_rate(div_hw, rate, prate);
+	rate = div_ops->round_rate(div_hw, req->rate, &req->best_parent_rate);
+	if (rate < 0)
+		return rate;
+
+	req->rate = rate;
+	return 0;
 }
 
 static int clk_periph_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -130,7 +136,7 @@ const struct clk_ops tegra_clk_periph_ops = {
 	.get_parent = clk_periph_get_parent,
 	.set_parent = clk_periph_set_parent,
 	.recalc_rate = clk_periph_recalc_rate,
-	.round_rate = clk_periph_round_rate,
+	.determine_rate = clk_periph_determine_rate,
 	.set_rate = clk_periph_set_rate,
 	.is_enabled = clk_periph_is_enabled,
 	.enable = clk_periph_enable,
@@ -154,7 +160,7 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = {
 	.get_parent = clk_periph_get_parent,
 	.set_parent = clk_periph_set_parent,
 	.recalc_rate = clk_periph_recalc_rate,
-	.round_rate = clk_periph_round_rate,
+	.determine_rate = clk_periph_determine_rate,
 	.set_rate = clk_periph_set_rate,
 	.restore_context = clk_periph_restore_context,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (63 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 64/68] clk: tegra: periph: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-06-18 23:38   ` Dmitry Osipenko
  2023-05-05 11:26 ` [PATCH v4 66/68] ASoC: tlv320aic32x4: pll: " Maxime Ripard
                   ` (2 subsequent siblings)
  67 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Jonathan Hunter, Peter De Schrijver,
	Prashant Gaikwad, Thierry Reding, linux-tegra

The Tegra super clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/tegra/clk-super.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index 3f3a7a203c5f..7ec47942720c 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
 	.restore_context = clk_super_mux_restore_context,
 };
 
-static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
-				 unsigned long *parent_rate)
+static int clk_super_determine_rate(struct clk_hw *hw,
+				    struct clk_rate_request *req)
 {
 	struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
 	struct clk_hw *div_hw = &super->frac_div.hw;
+	unsigned long rate;
 
 	__clk_hw_set_clk(div_hw, hw);
 
-	return super->div_ops->round_rate(div_hw, rate, parent_rate);
+	rate = super->div_ops->round_rate(div_hw, req->rate,
+					  &req->best_parent_rate);
+	if (rate < 0)
+		return rate;
+
+	req->rate = rate;
+	return 0;
 }
 
 static unsigned long clk_super_recalc_rate(struct clk_hw *hw,
@@ -193,7 +200,7 @@ const struct clk_ops tegra_clk_super_ops = {
 	.get_parent = clk_super_get_parent,
 	.set_parent = clk_super_set_parent,
 	.set_rate = clk_super_set_rate,
-	.round_rate = clk_super_round_rate,
+	.determine_rate = clk_super_determine_rate,
 	.recalc_rate = clk_super_recalc_rate,
 	.restore_context = clk_super_restore_context,
 };

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 66/68] ASoC: tlv320aic32x4: pll: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (64 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 65/68] clk: tegra: super: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 67/68] ASoC: tlv320aic32x4: div: " Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 68/68] clk: Forbid to register a mux without determine_rate Maxime Ripard
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Jaroslav Kysela, Liam Girdwood,
	Mark Brown, Takashi Iwai, alsa-devel

The tlv320aic32x4 PLL clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: alsa-devel@alsa-project.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 sound/soc/codecs/tlv320aic32x4-clk.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/tlv320aic32x4-clk.c b/sound/soc/codecs/tlv320aic32x4-clk.c
index 80cbc6bc6847..e2de4617ab09 100644
--- a/sound/soc/codecs/tlv320aic32x4-clk.c
+++ b/sound/soc/codecs/tlv320aic32x4-clk.c
@@ -204,18 +204,23 @@ static unsigned long clk_aic32x4_pll_recalc_rate(struct clk_hw *hw,
 	return clk_aic32x4_pll_calc_rate(&settings, parent_rate);
 }
 
-static long clk_aic32x4_pll_round_rate(struct clk_hw *hw,
-			unsigned long rate,
-			unsigned long *parent_rate)
+static int clk_aic32x4_pll_determine_rate(struct clk_hw *hw,
+					  struct clk_rate_request *req)
 {
 	struct clk_aic32x4_pll_muldiv settings;
+	unsigned long rate;
 	int ret;
 
-	ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, *parent_rate);
+	ret = clk_aic32x4_pll_calc_muldiv(&settings, req->rate, req->best_parent_rate);
 	if (ret < 0)
-		return 0;
+		return -EINVAL;
 
-	return clk_aic32x4_pll_calc_rate(&settings, *parent_rate);
+	rate = clk_aic32x4_pll_calc_rate(&settings, req->best_parent_rate);
+	if (rate < 0)
+		return rate;
+
+	req->rate = rate;
+	return 0;
 }
 
 static int clk_aic32x4_pll_set_rate(struct clk_hw *hw,
@@ -266,7 +271,7 @@ static const struct clk_ops aic32x4_pll_ops = {
 	.unprepare = clk_aic32x4_pll_unprepare,
 	.is_prepared = clk_aic32x4_pll_is_prepared,
 	.recalc_rate = clk_aic32x4_pll_recalc_rate,
-	.round_rate = clk_aic32x4_pll_round_rate,
+	.determine_rate = clk_aic32x4_pll_determine_rate,
 	.set_rate = clk_aic32x4_pll_set_rate,
 	.set_parent = clk_aic32x4_pll_set_parent,
 	.get_parent = clk_aic32x4_pll_get_parent,

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 67/68] ASoC: tlv320aic32x4: div: Switch to determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (65 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 66/68] ASoC: tlv320aic32x4: pll: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  2023-05-05 11:26 ` [PATCH v4 68/68] clk: Forbid to register a mux without determine_rate Maxime Ripard
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Jaroslav Kysela, Liam Girdwood,
	Mark Brown, Takashi Iwai, alsa-devel

The tlv320aic32x4 divider clocks implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: alsa-devel@alsa-project.org
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 sound/soc/codecs/tlv320aic32x4-clk.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/tlv320aic32x4-clk.c b/sound/soc/codecs/tlv320aic32x4-clk.c
index e2de4617ab09..a7ec501b4c69 100644
--- a/sound/soc/codecs/tlv320aic32x4-clk.c
+++ b/sound/soc/codecs/tlv320aic32x4-clk.c
@@ -332,16 +332,17 @@ static int clk_aic32x4_div_set_rate(struct clk_hw *hw, unsigned long rate,
 				AIC32X4_DIV_MASK, divisor);
 }
 
-static long clk_aic32x4_div_round_rate(struct clk_hw *hw, unsigned long rate,
-				unsigned long *parent_rate)
+static int clk_aic32x4_div_determine_rate(struct clk_hw *hw,
+					  struct clk_rate_request *req)
 {
 	unsigned long divisor;
 
-	divisor = DIV_ROUND_UP(*parent_rate, rate);
+	divisor = DIV_ROUND_UP(req->best_parent_rate, req->rate);
 	if (divisor > 128)
 		return -EINVAL;
 
-	return DIV_ROUND_UP(*parent_rate, divisor);
+	req->rate = DIV_ROUND_UP(req->best_parent_rate, divisor);
+	return 0;
 }
 
 static unsigned long clk_aic32x4_div_recalc_rate(struct clk_hw *hw,
@@ -360,7 +361,7 @@ static const struct clk_ops aic32x4_div_ops = {
 	.prepare = clk_aic32x4_div_prepare,
 	.unprepare = clk_aic32x4_div_unprepare,
 	.set_rate = clk_aic32x4_div_set_rate,
-	.round_rate = clk_aic32x4_div_round_rate,
+	.determine_rate = clk_aic32x4_div_determine_rate,
 	.recalc_rate = clk_aic32x4_div_recalc_rate,
 };
 
@@ -388,7 +389,7 @@ static const struct clk_ops aic32x4_bdiv_ops = {
 	.set_parent = clk_aic32x4_bdiv_set_parent,
 	.get_parent = clk_aic32x4_bdiv_get_parent,
 	.set_rate = clk_aic32x4_div_set_rate,
-	.round_rate = clk_aic32x4_div_round_rate,
+	.determine_rate = clk_aic32x4_div_determine_rate,
 	.recalc_rate = clk_aic32x4_div_recalc_rate,
 };
 

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v4 68/68] clk: Forbid to register a mux without determine_rate
  2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
                   ` (66 preceding siblings ...)
  2023-05-05 11:26 ` [PATCH v4 67/68] ASoC: tlv320aic32x4: div: " Maxime Ripard
@ 2023-05-05 11:26 ` Maxime Ripard
  67 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-05-05 11:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Maxime Ripard, Abel Vesa, Alessandro Zummo,
	Alexandre Belloni, Alexandre Torgue, Andreas Färber,
	AngeloGioacchino Del Regno, Baolin Wang, Charles Keepax,
	Chen-Yu Tsai, 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, Markus Schneider-Pargmann,
	Max Filippov, Maxime Coquelin, Mikko Perttunen, Miles Chen,
	Nicolas Ferre, Orson Zhai, Paul Cercueil, Peng Fan,
	Peter De Schrijver, Prashant Gaikwad, Richard Fitzgerald,
	Samuel Holland, Sascha Hauer, Sekhar Nori, Shawn Guo,
	Takashi Iwai, Thierry Reding, Ulf Hansson, Vinod Koul, dri-devel,
	linux-actions, linux-arm-kernel, linux-mips, linux-phy,
	linux-renesas-soc, linux-rtc, linux-stm32, linux-sunxi,
	linux-tegra, NXP Linux Team, patches, Pengutronix Kernel Team

The determine_rate hook allows to select the proper parent and its rate
for a given clock configuration. On another hand, set_parent is there to
change the parent of a mux.

Some clocks provide a set_parent hook but don't implement
determine_rate. In such a case, set_parent is pretty much useless since
the clock framework will always assume the current parent is to be used,
and we will thus never change it.

This situation can be solved in two ways:
  - either we don't need to change the parent, and we thus shouldn't
    implement set_parent;
  - or we don't want to change the parent, in this case we should set
    CLK_SET_RATE_NO_REPARENT;
  - or we're missing a determine_rate implementation.

The latter is probably just an oversight from the driver's author, and
we should thus raise their awareness about the fact that the current
state of the driver is confusing.

All the drivers in-tree have been converted by now, so let's prevent any
clock with set_parent but without determine_rate to register so that it
can't sneak in again in the future.

Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: "Andreas Färber" <afaerber@suse.de>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
Cc: Chen-Yu Tsai <wens@csie.org>
Cc: Chen-Yu Tsai <wenst@chromium.org>
Cc: Chunyan Zhang <zhang.lyra@gmail.com>
Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: David Airlie <airlied@gmail.com>
Cc: David Lechner <david@lechnology.com>
Cc: Dinh Nguyen <dinguyen@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Luca Ceresoli <luca.ceresoli@bootlin.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Markus Schneider-Pargmann <msp@baylibre.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Mikko Perttunen <mperttunen@nvidia.com>
Cc: Miles Chen <miles.chen@mediatek.com>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Orson Zhai <orsonzhai@gmail.com>
Cc: Paul Cercueil <paul@crapouillou.net>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Richard Fitzgerald <rf@opensource.cirrus.com>
Cc: Samuel Holland <samuel@sholland.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-actions@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mips@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-renesas-soc@vger.kernel.org
Cc: linux-rtc@vger.kernel.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-sunxi@lists.linux.dev
Cc: linux-tegra@vger.kernel.org
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: patches@opensource.cirrus.com
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index e4a1d5f9694c..c8f9227c29c9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3775,6 +3775,13 @@ static int __clk_core_init(struct clk_core *core)
 		goto out;
 	}
 
+	if (core->ops->set_parent && !core->ops->determine_rate) {
+		pr_err("%s: %s must implement .set_parent & .determine_rate\n",
+			__func__, core->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
 	if (core->num_parents > 1 && !core->ops->get_parent) {
 		pr_err("%s: %s must implement .get_parent as it has multi parents\n",
 		       __func__, core->name);

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 39/68] clk: versatile: sp810: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 39/68] clk: versatile: sp810: " Maxime Ripard
@ 2023-05-05 11:30   ` Linus Walleij
  2023-05-05 19:04     ` Pawel Moll
  0 siblings, 1 reply; 98+ messages in thread
From: Linus Walleij @ 2023-05-05 11:30 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Michael Turquette, Stephen Boyd, linux-clk, Pawel Moll, linux-arm-kernel

On Fri, May 5, 2023 at 1:27 PM Maxime Ripard <maxime@cerno.tech> wrote:

> The Versatile sp810 "timerclken" clock implements a mux with a
> set_parent hook, but doesn't provide a determine_rate implementation.
>
> This is a bit odd, since set_parent() is there to, as its name implies,
> change the parent of a clock. However, the most likely candidates to
> trigger that parent change are either the assigned-clock-parents device
> tree property or a call to clk_set_rate(), with determine_rate()
> figuring out which parent is the best suited for a given rate.
>
> This mismatch is probably due to the fact that the driver introduction
> predates the determine_rate introduction, and it was never revised since
> then.
>
> The default, implicit, behaviour that has been in use so far has thus
> been to simply keep using the current parent in all cases. This is also
> the behaviour of the new clk_hw_determine_rate_no_reparent() helper, so
> we can simply use it to make our expectation explicit.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

Acked-by: Linus Walleij <linus.walleij@linaro.org>
I think Pawel's reply reads as an ACK as well?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 04/68] clk: Introduce clk_hw_determine_rate_no_reparent()
  2023-05-05 11:25 ` [PATCH v4 04/68] clk: Introduce clk_hw_determine_rate_no_reparent() Maxime Ripard
@ 2023-05-05 17:15   ` kernel test robot
  0 siblings, 0 replies; 98+ messages in thread
From: kernel test robot @ 2023-05-05 17:15 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: oe-kbuild-all, Alexandre Belloni, Peng Fan, Geert Uytterhoeven,
	Sekhar Nori, Alexandre Torgue, dri-devel, Jaroslav Kysela,
	Paul Cercueil, Max Filippov, Prashant Gaikwad, linux-phy,
	linux-clk, Abel Vesa, Kishon Vijay Abraham I, Samuel Holland,
	Chunyan Zhang, Takashi Iwai, Vinod Koul, Jernej Skrabec,
	Jonathan Hunter, Chen-Yu Tsai, NXP Linux Team, Orson Zhai,
	Ulf Hansson, linux-mips, Luca Ceresoli, linux-sunxi,
	Maxime Coquelin

Hi Maxime,

kernel test robot noticed the following build errors:

[auto build test ERROR on 145e5cddfe8b4bf607510b2dcf630d95f4db420f]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
base:   145e5cddfe8b4bf607510b2dcf630d95f4db420f
patch link:    https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v4-4-971d5077e7d2%40cerno.tech
patch subject: [PATCH v4 04/68] clk: Introduce clk_hw_determine_rate_no_reparent()
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20230506/202305060103.z9ddfq9A-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/3acd93f10087c4a2905407786d6dc7af83c2a58c
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
        git checkout 3acd93f10087c4a2905407786d6dc7af83c2a58c
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202305060103.z9ddfq9A-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk_test.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 17/68] clk: lochnagar: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 17/68] clk: lochnagar: " Maxime Ripard
@ 2023-05-05 17:46   ` kernel test robot
  2023-05-05 18:47   ` kernel test robot
  1 sibling, 0 replies; 98+ messages in thread
From: kernel test robot @ 2023-05-05 17:46 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: llvm, oe-kbuild-all, linux-clk, Maxime Ripard, Charles Keepax,
	Richard Fitzgerald, patches

Hi Maxime,

kernel test robot noticed the following build errors:

[auto build test ERROR on 145e5cddfe8b4bf607510b2dcf630d95f4db420f]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
base:   145e5cddfe8b4bf607510b2dcf630d95f4db420f
patch link:    https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v4-17-971d5077e7d2%40cerno.tech
patch subject: [PATCH v4 17/68] clk: lochnagar: Add a determine_rate hook
config: i386-randconfig-a012-20230501 (https://download.01.org/0day-ci/archive/20230506/202305060148.hPASUhEx-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/273bc4689da3909aebca0a3479e18194a748ee92
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
        git checkout 273bc4689da3909aebca0a3479e18194a748ee92
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202305060148.hPASUhEx-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-lochnagar.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 23/68] clk: wm831x: clkout: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 23/68] clk: wm831x: " Maxime Ripard
@ 2023-05-05 18:06   ` kernel test robot
  0 siblings, 0 replies; 98+ messages in thread
From: kernel test robot @ 2023-05-05 18:06 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: llvm, oe-kbuild-all, linux-clk, Maxime Ripard, patches, Charles Keepax

Hi Maxime,

kernel test robot noticed the following build errors:

[auto build test ERROR on 145e5cddfe8b4bf607510b2dcf630d95f4db420f]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
base:   145e5cddfe8b4bf607510b2dcf630d95f4db420f
patch link:    https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v4-23-971d5077e7d2%40cerno.tech
patch subject: [PATCH v4 23/68] clk: wm831x: clkout: Add a determine_rate hook
config: i386-randconfig-a011-20230501 (https://download.01.org/0day-ci/archive/20230506/202305060140.iMPUOCu9-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/3c4b2e3898c59b2dd85f6166f01357923713f8fe
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
        git checkout 3c4b2e3898c59b2dd85f6166f01357923713f8fe
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202305060140.iMPUOCu9-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-wm831x.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 45/68] rtc: sun6i: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 45/68] rtc: sun6i: " Maxime Ripard
@ 2023-05-05 18:46   ` Jernej Škrabec
  0 siblings, 0 replies; 98+ messages in thread
From: Jernej Škrabec @ 2023-05-05 18:46 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Maxime Ripard
  Cc: linux-clk, Maxime Ripard, Alessandro Zummo, Alexandre Belloni,
	Chen-Yu Tsai, Samuel Holland, linux-arm-kernel, linux-rtc,
	linux-sunxi

Dne petek, 05. maj 2023 ob 13:25:47 CEST je Maxime Ripard napisal(a):
> The Allwinner sun6i RTC clock implements a mux with a set_parent hook,
> but doesn't provide a determine_rate implementation.
> 
> This is a bit odd, since set_parent() is there to, as its name implies,
> change the parent of a clock. However, the most likely candidates to
> trigger that parent change are either the assigned-clock-parents device
> tree property or a call to clk_set_rate(), with determine_rate()
> figuring out which parent is the best suited for a given rate.
> 
> The other trigger would be a call to clk_set_parent(), but it's far less
> used, and it doesn't look like there's any obvious user for that clock.
> 
> Similarly, it doesn't look like the device tree using that clock driver
> uses any of the assigned-clock properties on that clock.
> 
> So, the set_parent hook is effectively unused, possibly because of an
> oversight. However, it could also be an explicit decision by the
> original author to avoid any reparenting but through an explicit call to
> clk_set_parent().
> 
> The latter case would be equivalent to setting the determine_rate
> implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
> determine_rate implementation is provided, clk_round_rate() (through
> clk_core_round_rate_nolock()) will call itself on the parent if
> CLK_SET_RATE_PARENT is set, and will not change the clock rate
> otherwise.
> 
> And if it was an oversight, then we are at least explicit about our
> behavior now and it can be further refined down the line.
> 
> Cc: Alessandro Zummo <a.zummo@towertech.it>
> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Cc: Chen-Yu Tsai <wens@csie.org>
> Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
> Cc: Samuel Holland <samuel@sholland.org>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-rtc@vger.kernel.org
> Cc: linux-sunxi@lists.linux.dev
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>

Best regards,
Jernej

> ---
>  drivers/rtc/rtc-sun6i.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
> index dc76537f1b62..71548dd59a3a 100644
> --- a/drivers/rtc/rtc-sun6i.c
> +++ b/drivers/rtc/rtc-sun6i.c
> @@ -214,6 +214,7 @@ static int sun6i_rtc_osc_set_parent(struct clk_hw *hw,
> u8 index)
> 
>  static const struct clk_ops sun6i_rtc_osc_ops = {
>  	.recalc_rate	= sun6i_rtc_osc_recalc_rate,
> +	.determine_rate	= clk_hw_determine_rate_no_reparent,
> 
>  	.get_parent	= sun6i_rtc_osc_get_parent,
>  	.set_parent	= sun6i_rtc_osc_set_parent,





^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 17/68] clk: lochnagar: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 17/68] clk: lochnagar: " Maxime Ripard
  2023-05-05 17:46   ` kernel test robot
@ 2023-05-05 18:47   ` kernel test robot
  1 sibling, 0 replies; 98+ messages in thread
From: kernel test robot @ 2023-05-05 18:47 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: oe-kbuild-all, linux-clk, Maxime Ripard, Charles Keepax,
	Richard Fitzgerald, patches

Hi Maxime,

kernel test robot noticed the following build errors:

[auto build test ERROR on 145e5cddfe8b4bf607510b2dcf630d95f4db420f]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
base:   145e5cddfe8b4bf607510b2dcf630d95f4db420f
patch link:    https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v4-17-971d5077e7d2%40cerno.tech
patch subject: [PATCH v4 17/68] clk: lochnagar: Add a determine_rate hook
config: arm-allmodconfig (https://download.01.org/0day-ci/archive/20230506/202305060216.rOqp4J6Z-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/273bc4689da3909aebca0a3479e18194a748ee92
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
        git checkout 273bc4689da3909aebca0a3479e18194a748ee92
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202305060216.rOqp4J6Z-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk_test.ko] undefined!
ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-cdce706.ko] undefined!
>> ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-lochnagar.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 39/68] clk: versatile: sp810: Add a determine_rate hook
  2023-05-05 11:30   ` Linus Walleij
@ 2023-05-05 19:04     ` Pawel Moll
  0 siblings, 0 replies; 98+ messages in thread
From: Pawel Moll @ 2023-05-05 19:04 UTC (permalink / raw)
  To: Linus Walleij, Maxime Ripard
  Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-kernel

On 05/05/2023 12:30, Linus Walleij wrote:
> On Fri, May 5, 2023 at 1:27 PM Maxime Ripard <maxime@cerno.tech> wrote:
> 
>> The Versatile sp810 "timerclken" clock implements a mux with a
>> set_parent hook, but doesn't provide a determine_rate implementation.
>>
>> This is a bit odd, since set_parent() is there to, as its name implies,
>> change the parent of a clock. However, the most likely candidates to
>> trigger that parent change are either the assigned-clock-parents device
>> tree property or a call to clk_set_rate(), with determine_rate()
>> figuring out which parent is the best suited for a given rate.
>>
>> This mismatch is probably due to the fact that the driver introduction
>> predates the determine_rate introduction, and it was never revised since
>> then.
>>
>> The default, implicit, behaviour that has been in use so far has thus
>> been to simply keep using the current parent in all cases. This is also
>> the behaviour of the new clk_hw_determine_rate_no_reparent() helper, so
>> we can simply use it to make our expectation explicit.
>>
>> Cc: Linus Walleij <linus.walleij@linaro.org>
>> Cc: Pawel Moll <pawel.moll@arm.com>
>> Cc: linux-arm-kernel@lists.infradead.org
>> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> 
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> I think Pawel's reply reads as an ACK as well?

Indeed, for what it's worth (not much ;-)

Acked-by: Pawel Moll <pawel.moll@arm.com>

Cheers!

Paweł

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 12/68] clk: cdce706: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 12/68] clk: cdce706: " Maxime Ripard
@ 2023-05-05 21:00   ` kernel test robot
  0 siblings, 0 replies; 98+ messages in thread
From: kernel test robot @ 2023-05-05 21:00 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: oe-kbuild-all, linux-clk, Maxime Ripard, Max Filippov

Hi Maxime,

kernel test robot noticed the following build errors:

[auto build test ERROR on 145e5cddfe8b4bf607510b2dcf630d95f4db420f]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
base:   145e5cddfe8b4bf607510b2dcf630d95f4db420f
patch link:    https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v4-12-971d5077e7d2%40cerno.tech
patch subject: [PATCH v4 12/68] clk: cdce706: Add a determine_rate hook
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20230506/202305060426.mOiZv7Hn-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/09a54ed3207dca37a9f0541411f1867aa38a750d
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
        git checkout 09a54ed3207dca37a9f0541411f1867aa38a750d
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202305060426.mOiZv7Hn-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk_test.ko] undefined!
>> ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-cdce706.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 28/68] clk: imx: scu: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 28/68] clk: imx: scu: " Maxime Ripard
@ 2023-05-06  0:37   ` kernel test robot
  0 siblings, 0 replies; 98+ messages in thread
From: kernel test robot @ 2023-05-06  0:37 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: oe-kbuild-all, linux-clk, Maxime Ripard, Abel Vesa,
	Fabio Estevam, Peng Fan, Sascha Hauer, Shawn Guo,
	linux-arm-kernel, NXP Linux Team, Pengutronix Kernel Team

Hi Maxime,

kernel test robot noticed the following build errors:

[auto build test ERROR on 145e5cddfe8b4bf607510b2dcf630d95f4db420f]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
base:   145e5cddfe8b4bf607510b2dcf630d95f4db420f
patch link:    https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v4-28-971d5077e7d2%40cerno.tech
patch subject: [PATCH v4 28/68] clk: imx: scu: Add a determine_rate hook
config: arm-allmodconfig (https://download.01.org/0day-ci/archive/20230506/202305060825.el8VAQuQ-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/0c9c183066c25a7519ff60578753e40bf622b982
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Maxime-Ripard/clk-Export-clk_hw_forward_rate_request/20230505-193724
        git checkout 0c9c183066c25a7519ff60578753e40bf622b982
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202305060825.el8VAQuQ-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/imx/clk-imx-scu.ko] undefined!
ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk_test.ko] undefined!
ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-cdce706.ko] undefined!
ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-lochnagar.ko] undefined!
ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-si5341.ko] undefined!
ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-versaclock5.ko] undefined!
ERROR: modpost: "clk_hw_determine_rate_no_reparent" [drivers/clk/clk-wm831x.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 29/68] clk: mediatek: cpumux: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 29/68] clk: mediatek: cpumux: " Maxime Ripard
@ 2023-05-08  2:36   ` Chen-Yu Tsai
  0 siblings, 0 replies; 98+ messages in thread
From: Chen-Yu Tsai @ 2023-05-08  2:36 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Michael Turquette, Stephen Boyd, linux-clk,
	AngeloGioacchino Del Regno, Matthias Brugger, linux-arm-kernel,
	linux-mediatek

On Fri, May 5, 2023 at 7:27 PM Maxime Ripard <maxime@cerno.tech> wrote:
>
> The Mediatek cpumux clock implements a mux with a set_parent hook, but
> doesn't provide a determine_rate implementation.
>
> This is a bit odd, since set_parent() is there to, as its name implies,
> change the parent of a clock. However, the most likely candidates to
> trigger that parent change are either the assigned-clock-parents device
> tree property or a call to clk_set_rate(), with determine_rate()
> figuring out which parent is the best suited for a given rate.
>
> The other trigger would be a call to clk_set_parent(), but it's far less
> used, and it doesn't look like there's any obvious user for that clock.
>
> Similarly, it doesn't look like the device tree using that clock driver
> uses any of the assigned-clock properties on that clock.
>
> So, the set_parent hook is effectively unused, possibly because of an
> oversight. However, it could also be an explicit decision by the
> original author to avoid any reparenting but through an explicit call to
> clk_set_parent().

The consumer, the cpufreq driver, assumes the original parent to be
the dedicated PLL that drives it. It gets a reference to the original
parent with clk_get_parent(). It also gets an intermediate (stable) clock
via DT. It does explicit clk_set_parent() calls to switch to/from the
stable clock, and does clk_set_rate() on the dedicated PLL in between.

So yeah, they only use set_parent hook.

> The latter case would be equivalent to setting the determine_rate
> implementation to clk_hw_determine_rate_no_reparent(). Indeed, if no
> determine_rate implementation is provided, clk_round_rate() (through
> clk_core_round_rate_nolock()) will call itself on the parent if
> CLK_SET_RATE_PARENT is set, and will not change the clock rate
> otherwise.
>
> And if it was an oversight, then we are at least explicit about our
> behavior now and it can be further refined down the line.
>
> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Cc: Matthias Brugger <matthias.bgg@gmail.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-mediatek@lists.infradead.org
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 07/68] clk: test: Add a determine_rate hook
  2023-05-05 11:25 ` [PATCH v4 07/68] clk: test: " Maxime Ripard
@ 2023-06-09  1:41   ` Stephen Boyd
  2023-06-13  8:21     ` Maxime Ripard
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Boyd @ 2023-06-09  1:41 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette; +Cc: linux-clk, Maxime Ripard

Quoting Maxime Ripard (2023-05-05 04:25:09)
> The single parent clock in our kunit tests implements a mux with a
> set_parent hook, but doesn't provide a determine_rate implementation.
> 
> This is not entirely unexpected, since its whole purpose it to have a
> single parent. When determine_rate is missing, and since
> CLK_SET_RATE_PARENT is set for all its instances, the default behaviour
> of the framework will be to forward it to the current parent.
> 
> This is totally fine as far as the tests are concerned, but we'll start
> to mandate a determine_rate implementation when set_parent is set, so
> let's fill it with __clk_mux_determine_rate() which will have the same
> behavior.
> 
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---
>  drivers/clk/clk_test.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
> index b3ed3b0e4c31..a154ec9d0111 100644
> --- a/drivers/clk/clk_test.c
> +++ b/drivers/clk/clk_test.c
> @@ -104,6 +104,23 @@ static const struct clk_ops clk_dummy_minimize_rate_ops = {
>  };
>  
>  static const struct clk_ops clk_dummy_single_parent_ops = {
> +       /*
> +        * FIXME: Even though we should probably be able to use

Are we ever going to fix this?

> +        * __clk_mux_determine_rate() here, if we use it and call
> +        * clk_round_rate() or clk_set_rate() with a rate lower than
> +        * what all the parents can provide, it will return -EINVAL.
> +        *
> +        * This is due to the fact that it has the undocumented
> +        * behaviour to always pick up the closest rate higher than the
> +        * requested rate. If we get something lower, it thus considers
> +        * that it's not acceptable and will return an error.
> +        *
> +        * It's somewhat inconsistent and creates a weird threshold
> +        * between rates above the parent rate which would be rounded to
> +        * what the parent can provide, but rates below will simply
> +        * return an error.
> +        */
> +       .determine_rate = __clk_mux_determine_rate_closest,
>         .set_parent = clk_dummy_single_set_parent,
>         .get_parent = clk_dummy_single_get_parent,

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 07/68] clk: test: Add a determine_rate hook
  2023-06-09  1:41   ` Stephen Boyd
@ 2023-06-13  8:21     ` Maxime Ripard
  2023-06-13 18:39       ` Stephen Boyd
  0 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-06-13  8:21 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: Michael Turquette, linux-clk

[-- Attachment #1: Type: text/plain, Size: 2826 bytes --]

Hi,

On Thu, Jun 08, 2023 at 06:41:56PM -0700, Stephen Boyd wrote:
> Quoting Maxime Ripard (2023-05-05 04:25:09)
> > The single parent clock in our kunit tests implements a mux with a
> > set_parent hook, but doesn't provide a determine_rate implementation.
> > 
> > This is not entirely unexpected, since its whole purpose it to have a
> > single parent. When determine_rate is missing, and since
> > CLK_SET_RATE_PARENT is set for all its instances, the default behaviour
> > of the framework will be to forward it to the current parent.
> > 
> > This is totally fine as far as the tests are concerned, but we'll start
> > to mandate a determine_rate implementation when set_parent is set, so
> > let's fill it with __clk_mux_determine_rate() which will have the same
> > behavior.
> > 
> > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> > ---
> >  drivers/clk/clk_test.c | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> > 
> > diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
> > index b3ed3b0e4c31..a154ec9d0111 100644
> > --- a/drivers/clk/clk_test.c
> > +++ b/drivers/clk/clk_test.c
> > @@ -104,6 +104,23 @@ static const struct clk_ops clk_dummy_minimize_rate_ops = {
> >  };
> >  
> >  static const struct clk_ops clk_dummy_single_parent_ops = {
> > +       /*
> > +        * FIXME: Even though we should probably be able to use
> 
> Are we ever going to fix this?

We probably should, but I'm not entirely sure how.

> > +        * __clk_mux_determine_rate() here, if we use it and call
> > +        * clk_round_rate() or clk_set_rate() with a rate lower than
> > +        * what all the parents can provide, it will return -EINVAL.
> > +        *
> > +        * This is due to the fact that it has the undocumented
> > +        * behaviour to always pick up the closest rate higher than the
> > +        * requested rate. If we get something lower, it thus considers
> > +        * that it's not acceptable and will return an error.
> > +        *
> > +        * It's somewhat inconsistent and creates a weird threshold
> > +        * between rates above the parent rate which would be rounded to
> > +        * what the parent can provide, but rates below will simply
> > +        * return an error.
> > +        */

I guess it's mostly a policy decision: __clk_mux_determine_rate() always
has been returning rates that are lower or equal to the target rate.

If no parent can provide one, then the obvious solution is to error out,
which creates the inconsistency mentioned above.

Another solution would be to pick up a parent by default (the current
one maybe?) but then we could return a rate higher than the target rate
which breaks what we've been doing so far.

I'm not sure if one is better than the other.
Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 03/68] clk: Move no reparent case into a separate function
       [not found]   ` <CGME20230613111502eucas1p2644889c9de1abfe1a14a3b549772f247@eucas1p2.samsung.com>
@ 2023-06-13 11:15     ` Marek Szyprowski
       [not found]       ` <CGME20230613121511eucas1p2595e0de21fadbafc1f6ffdc5636b9271@eucas1p2.samsung.com>
  0 siblings, 1 reply; 98+ messages in thread
From: Marek Szyprowski @ 2023-06-13 11:15 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: linux-clk, dri-devel, linux-actions, linux-arm-kernel,
	linux-mips, linux-phy, linux-renesas-soc, linux-rtc, linux-stm32,
	linux-sunxi, linux-tegra, NXP Linux Team,
	Pengutronix Kernel Team

On 05.05.2023 13:25, Maxime Ripard wrote:
> From: Stephen Boyd <sboyd@kernel.org>
>
> 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@kernel.org>
> Cc: Alessandro Zummo <a.zummo@towertech.it>
> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
> Cc: "Andreas Färber" <afaerber@suse.de>
> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
> Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
> Cc: Chen-Yu Tsai <wens@csie.org>
> Cc: Chen-Yu Tsai <wenst@chromium.org>
> Cc: Chunyan Zhang <zhang.lyra@gmail.com>
> Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: David Airlie <airlied@gmail.com>
> Cc: David Lechner <david@lechnology.com>
> Cc: Dinh Nguyen <dinguyen@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Jaroslav Kysela <perex@perex.cz>
> Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: Kishon Vijay Abraham I <kishon@kernel.org>
> Cc: Liam Girdwood <lgirdwood@gmail.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Luca Ceresoli <luca.ceresoli@bootlin.com>
> Cc: Manivannan Sadhasivam <mani@kernel.org>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Markus Schneider-Pargmann <msp@baylibre.com>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> Cc: Mikko Perttunen <mperttunen@nvidia.com>
> Cc: Miles Chen <miles.chen@mediatek.com>
> Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
> Cc: Orson Zhai <orsonzhai@gmail.com>
> Cc: Paul Cercueil <paul@crapouillou.net>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
> Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
> Cc: Richard Fitzgerald <rf@opensource.cirrus.com>
> Cc: Samuel Holland <samuel@sholland.org>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Sekhar Nori <nsekhar@ti.com>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Takashi Iwai <tiwai@suse.com>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Cc: Vinod Koul <vkoul@kernel.org>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-actions@lists.infradead.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-mips@vger.kernel.org
> Cc: linux-phy@lists.infradead.org
> Cc: linux-renesas-soc@vger.kernel.org
> Cc: linux-rtc@vger.kernel.org
> Cc: linux-stm32@st-md-mailman.stormreply.com
> Cc: linux-sunxi@lists.linux.dev
> Cc: linux-tegra@vger.kernel.org
> Cc: NXP Linux Team <linux-imx@nxp.com>
> Cc: patches@opensource.cirrus.com
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---

This patch landed in today's linux-next as commit 1b4e99fda73f ("clk: 
Move no reparent case into a separate function"). Unfortunately it 
causes serious regression of some of my test boards. Namely Exynos3250 
based boards are so slow after it, that my test scripts fail with a 
timeout waiting for them to finish booting. I will try to debug this 
later in the evening to check what has happened that some clocks got 
very low rate.


> 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;
>
Best regards

-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 03/68] clk: Move no reparent case into a separate function
       [not found]       ` <CGME20230613121511eucas1p2595e0de21fadbafc1f6ffdc5636b9271@eucas1p2.samsung.com>
@ 2023-06-13 12:15         ` Marek Szyprowski
  2023-06-13 12:29           ` Maxime Ripard
  0 siblings, 1 reply; 98+ messages in thread
From: Marek Szyprowski @ 2023-06-13 12:15 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: linux-clk, dri-devel, linux-actions, linux-arm-kernel,
	linux-mips, linux-phy, linux-renesas-soc, linux-rtc, linux-stm32,
	linux-sunxi, linux-tegra, NXP Linux Team,
	Pengutronix Kernel Team

On 13.06.2023 13:15, Marek Szyprowski wrote:
> On 05.05.2023 13:25, Maxime Ripard wrote:
>> From: Stephen Boyd <sboyd@kernel.org>
>>
>> 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@kernel.org>
>> Cc: Alessandro Zummo <a.zummo@towertech.it>
>> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
>> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
>> Cc: "Andreas Färber" <afaerber@suse.de>
>> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
>> Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
>> Cc: Chen-Yu Tsai <wens@csie.org>
>> Cc: Chen-Yu Tsai <wenst@chromium.org>
>> Cc: Chunyan Zhang <zhang.lyra@gmail.com>
>> Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
>> Cc: Daniel Vetter <daniel@ffwll.ch>
>> Cc: David Airlie <airlied@gmail.com>
>> Cc: David Lechner <david@lechnology.com>
>> Cc: Dinh Nguyen <dinguyen@kernel.org>
>> Cc: Fabio Estevam <festevam@gmail.com>
>> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
>> Cc: Jaroslav Kysela <perex@perex.cz>
>> Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
>> Cc: Jonathan Hunter <jonathanh@nvidia.com>
>> Cc: Kishon Vijay Abraham I <kishon@kernel.org>
>> Cc: Liam Girdwood <lgirdwood@gmail.com>
>> Cc: Linus Walleij <linus.walleij@linaro.org>
>> Cc: Luca Ceresoli <luca.ceresoli@bootlin.com>
>> Cc: Manivannan Sadhasivam <mani@kernel.org>
>> Cc: Mark Brown <broonie@kernel.org>
>> Cc: Markus Schneider-Pargmann <msp@baylibre.com>
>> Cc: Max Filippov <jcmvbkbc@gmail.com>
>> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> Cc: Mikko Perttunen <mperttunen@nvidia.com>
>> Cc: Miles Chen <miles.chen@mediatek.com>
>> Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
>> Cc: Orson Zhai <orsonzhai@gmail.com>
>> Cc: Paul Cercueil <paul@crapouillou.net>
>> Cc: Peng Fan <peng.fan@nxp.com>
>> Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
>> Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
>> Cc: Richard Fitzgerald <rf@opensource.cirrus.com>
>> Cc: Samuel Holland <samuel@sholland.org>
>> Cc: Sascha Hauer <s.hauer@pengutronix.de>
>> Cc: Sekhar Nori <nsekhar@ti.com>
>> Cc: Shawn Guo <shawnguo@kernel.org>
>> Cc: Takashi Iwai <tiwai@suse.com>
>> Cc: Thierry Reding <thierry.reding@gmail.com>
>> Cc: Ulf Hansson <ulf.hansson@linaro.org>
>> Cc: Vinod Koul <vkoul@kernel.org>
>> Cc: dri-devel@lists.freedesktop.org
>> Cc: linux-actions@lists.infradead.org
>> Cc: linux-arm-kernel@lists.infradead.org
>> Cc: linux-mips@vger.kernel.org
>> Cc: linux-phy@lists.infradead.org
>> Cc: linux-renesas-soc@vger.kernel.org
>> Cc: linux-rtc@vger.kernel.org
>> Cc: linux-stm32@st-md-mailman.stormreply.com
>> Cc: linux-sunxi@lists.linux.dev
>> Cc: linux-tegra@vger.kernel.org
>> Cc: NXP Linux Team <linux-imx@nxp.com>
>> Cc: patches@opensource.cirrus.com
>> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
>> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
>> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
>> ---
>
> This patch landed in today's linux-next as commit 1b4e99fda73f ("clk: 
> Move no reparent case into a separate function"). Unfortunately it 
> causes serious regression of some of my test boards. Namely Exynos3250 
> based boards are so slow after it, that my test scripts fail with a 
> timeout waiting for them to finish booting. I will try to debug this 
> later in the evening to check what has happened that some clocks got 
> very low rate.
>
I just got a few spare minutes, so I decided to take a look into this 
issue. The following change fixed my problem:

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index ffc9f03840b7..7ac9f7a8cb84 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -629,6 +629,7 @@ clk_core_determine_rate_no_reparent(struct clk_hw *hw,
                 best = clk_core_get_rate_nolock(core);
         }

+       req->best_parent_rate = best;
         req->rate = best;

         return 0;

best_parent_rate is still being used somewhere in the code and needs to 
be updated regardless of the CLK_SET_RATE_NO_REPARENT flag.

 > ...

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 03/68] clk: Move no reparent case into a separate function
  2023-06-13 12:15         ` Marek Szyprowski
@ 2023-06-13 12:29           ` Maxime Ripard
  0 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-06-13 12:29 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Michael Turquette, Stephen Boyd, linux-clk, dri-devel,
	linux-actions, linux-arm-kernel, linux-mips, linux-phy,
	linux-renesas-soc, linux-rtc, linux-stm32, linux-sunxi,
	linux-tegra, NXP Linux Team, Pengutronix Kernel Team

[-- Attachment #1: Type: text/plain, Size: 4646 bytes --]

Hi,

On Tue, Jun 13, 2023 at 02:15:10PM +0200, Marek Szyprowski wrote:
> On 13.06.2023 13:15, Marek Szyprowski wrote:
> > On 05.05.2023 13:25, Maxime Ripard wrote:
> >> From: Stephen Boyd <sboyd@kernel.org>
> >>
> >> 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@kernel.org>
> >> Cc: Alessandro Zummo <a.zummo@towertech.it>
> >> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> >> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
> >> Cc: "Andreas Färber" <afaerber@suse.de>
> >> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> >> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
> >> Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
> >> Cc: Chen-Yu Tsai <wens@csie.org>
> >> Cc: Chen-Yu Tsai <wenst@chromium.org>
> >> Cc: Chunyan Zhang <zhang.lyra@gmail.com>
> >> Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
> >> Cc: Daniel Vetter <daniel@ffwll.ch>
> >> Cc: David Airlie <airlied@gmail.com>
> >> Cc: David Lechner <david@lechnology.com>
> >> Cc: Dinh Nguyen <dinguyen@kernel.org>
> >> Cc: Fabio Estevam <festevam@gmail.com>
> >> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> >> Cc: Jaroslav Kysela <perex@perex.cz>
> >> Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
> >> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> >> Cc: Kishon Vijay Abraham I <kishon@kernel.org>
> >> Cc: Liam Girdwood <lgirdwood@gmail.com>
> >> Cc: Linus Walleij <linus.walleij@linaro.org>
> >> Cc: Luca Ceresoli <luca.ceresoli@bootlin.com>
> >> Cc: Manivannan Sadhasivam <mani@kernel.org>
> >> Cc: Mark Brown <broonie@kernel.org>
> >> Cc: Markus Schneider-Pargmann <msp@baylibre.com>
> >> Cc: Max Filippov <jcmvbkbc@gmail.com>
> >> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> >> Cc: Mikko Perttunen <mperttunen@nvidia.com>
> >> Cc: Miles Chen <miles.chen@mediatek.com>
> >> Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
> >> Cc: Orson Zhai <orsonzhai@gmail.com>
> >> Cc: Paul Cercueil <paul@crapouillou.net>
> >> Cc: Peng Fan <peng.fan@nxp.com>
> >> Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
> >> Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
> >> Cc: Richard Fitzgerald <rf@opensource.cirrus.com>
> >> Cc: Samuel Holland <samuel@sholland.org>
> >> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> >> Cc: Sekhar Nori <nsekhar@ti.com>
> >> Cc: Shawn Guo <shawnguo@kernel.org>
> >> Cc: Takashi Iwai <tiwai@suse.com>
> >> Cc: Thierry Reding <thierry.reding@gmail.com>
> >> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> >> Cc: Vinod Koul <vkoul@kernel.org>
> >> Cc: dri-devel@lists.freedesktop.org
> >> Cc: linux-actions@lists.infradead.org
> >> Cc: linux-arm-kernel@lists.infradead.org
> >> Cc: linux-mips@vger.kernel.org
> >> Cc: linux-phy@lists.infradead.org
> >> Cc: linux-renesas-soc@vger.kernel.org
> >> Cc: linux-rtc@vger.kernel.org
> >> Cc: linux-stm32@st-md-mailman.stormreply.com
> >> Cc: linux-sunxi@lists.linux.dev
> >> Cc: linux-tegra@vger.kernel.org
> >> Cc: NXP Linux Team <linux-imx@nxp.com>
> >> Cc: patches@opensource.cirrus.com
> >> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> >> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> >> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> >> ---
> >
> > This patch landed in today's linux-next as commit 1b4e99fda73f ("clk: 
> > Move no reparent case into a separate function"). Unfortunately it 
> > causes serious regression of some of my test boards. Namely Exynos3250 
> > based boards are so slow after it, that my test scripts fail with a 
> > timeout waiting for them to finish booting. I will try to debug this 
> > later in the evening to check what has happened that some clocks got 
> > very low rate.
> >
> I just got a few spare minutes, so I decided to take a look into this 
> issue. The following change fixed my problem:
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index ffc9f03840b7..7ac9f7a8cb84 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -629,6 +629,7 @@ clk_core_determine_rate_no_reparent(struct clk_hw *hw,
>                  best = clk_core_get_rate_nolock(core);
>          }
> 
> +       req->best_parent_rate = best;
>          req->rate = best;
> 
>          return 0;
> 
> best_parent_rate is still being used somewhere in the code and needs to 
> be updated regardless of the CLK_SET_RATE_NO_REPARENT flag.

Yeah, that makes sense, could you send a patch?

Thanks for figuring it out!
Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 61/68] clk: sprd: composite: Switch to determine_rate
  2023-05-05 11:26 ` [PATCH v4 61/68] clk: sprd: composite: " Maxime Ripard
@ 2023-06-13 17:11   ` Harshit Mogalapalli
  2023-06-13 19:21     ` Stephen Boyd
  0 siblings, 1 reply; 98+ messages in thread
From: Harshit Mogalapalli @ 2023-06-13 17:11 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: linux-clk, Baolin Wang, Chunyan Zhang, Orson Zhai, Dan Carpenter,
	Dan Carpenter, kernel-janitors, Harshit Mogalapalli

Hi Maxime,

On 05/05/23 4:56 pm, Maxime Ripard wrote:
> The Spreadtrum composite clocks implements a mux with a set_parent
> hook, but doesn't provide a determine_rate implementation.
> 
> This is a bit odd, since set_parent() is there to, as its name implies,
> change the parent of a clock. However, the most likely candidate to
> trigger that parent change is a call to clk_set_rate(), with
> determine_rate() figuring out which parent is the best suited for a
> given rate.
> 
> The other trigger would be a call to clk_set_parent(), but it's far less
> used, and it doesn't look like there's any obvious user for that clock.
> 
> So, the set_parent hook is effectively unused, possibly because of an
> oversight. However, it could also be an explicit decision by the
> original author to avoid any reparenting but through an explicit call to
> clk_set_parent().
> 
> The driver does implement round_rate() though, which means that we can
> change the rate of the clock, but we will never get to change the
> parent.
> 
> However, It's hard to tell whether it's been done on purpose or not.
> 
> Since we'll start mandating a determine_rate() implementation, let's
> convert the round_rate() implementation to a determine_rate(), which
> will also make the current behavior explicit. And if it was an
> oversight, the clock behaviour can be adjusted later on.
> 
> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
> Cc: Chunyan Zhang <zhang.lyra@gmail.com>
> Cc: Orson Zhai <orsonzhai@gmail.com>
> Acked-by: Chunyan Zhang <zhang.lyra@gmail.com>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---
>   drivers/clk/sprd/composite.c | 16 +++++++++++-----
>   1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
> index ebb644820b1e..d3a852720c07 100644
> --- a/drivers/clk/sprd/composite.c
> +++ b/drivers/clk/sprd/composite.c
> @@ -9,13 +9,19 @@
>   
>   #include "composite.h"
>   
> -static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
> -				unsigned long *parent_rate)
> +static int sprd_comp_determine_rate(struct clk_hw *hw,
> +				    struct clk_rate_request *req)
>   {
>   	struct sprd_comp *cc = hw_to_sprd_comp(hw);
> +	unsigned long rate;
>   
> -	return sprd_div_helper_round_rate(&cc->common, &cc->div,
> -					 rate, parent_rate);
> +	rate = sprd_div_helper_round_rate(&cc->common, &cc->div,
> +					  req->rate, &req->best_parent_rate);
> +	if (rate < 0)
> +		return rate;

As rate is unsigned long, it can never be less than zero, so the above 
if condition is never true. Smatch detected this.

Also if we just change the type of rate from unsigned long to long, will 
the return type of the function "sprd_comp_determine_rate" being int is 
correct?

Thanks,
Harshit

> +
> +	req->rate = rate;
> +	return 0;
>   }
>   
>   static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
> @@ -53,7 +59,7 @@ const struct clk_ops sprd_comp_ops = {
>   	.get_parent	= sprd_comp_get_parent,
>   	.set_parent	= sprd_comp_set_parent,
>   
> -	.round_rate	= sprd_comp_round_rate,
> +	.determine_rate	= sprd_comp_determine_rate,
>   	.recalc_rate	= sprd_comp_recalc_rate,
>   	.set_rate	= sprd_comp_set_rate,
>   };
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 07/68] clk: test: Add a determine_rate hook
  2023-06-13  8:21     ` Maxime Ripard
@ 2023-06-13 18:39       ` Stephen Boyd
  2023-06-19 13:20         ` Maxime Ripard
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Boyd @ 2023-06-13 18:39 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: Michael Turquette, linux-clk

Quoting Maxime Ripard (2023-06-13 01:21:59)
> On Thu, Jun 08, 2023 at 06:41:56PM -0700, Stephen Boyd wrote:
> > Quoting Maxime Ripard (2023-05-05 04:25:09)
> 
> > > +        * __clk_mux_determine_rate() here, if we use it and call
> > > +        * clk_round_rate() or clk_set_rate() with a rate lower than
> > > +        * what all the parents can provide, it will return -EINVAL.
> > > +        *
> > > +        * This is due to the fact that it has the undocumented
> > > +        * behaviour to always pick up the closest rate higher than the
> > > +        * requested rate. If we get something lower, it thus considers
> > > +        * that it's not acceptable and will return an error.
> > > +        *
> > > +        * It's somewhat inconsistent and creates a weird threshold
> > > +        * between rates above the parent rate which would be rounded to
> > > +        * what the parent can provide, but rates below will simply
> > > +        * return an error.
> > > +        */
> 
> I guess it's mostly a policy decision: __clk_mux_determine_rate() always
> has been returning rates that are lower or equal to the target rate.
> 
> If no parent can provide one, then the obvious solution is to error out,
> which creates the inconsistency mentioned above.
> 
> Another solution would be to pick up a parent by default (the current
> one maybe?) but then we could return a rate higher than the target rate
> which breaks what we've been doing so far.
> 
> I'm not sure if one is better than the other.

We should pick a rounding policy that we want for the test. The test
shouldn't be checking the rounding policy. It should be checking that
the code under test does what is expected when the rounding policy is
what we choose.

If __clk_mux_determine_rate() returns an error when the rate is lower
than the parent supports then we should test that as well and make sure
it does return an error in this case. We can directly call
__clk_mux_determine_rate() after registering the clks so that the
function is isolated.

We should also be testing what the clk API will do if a determine_rate()
clk_op returns an error. And what it will do if the clk has multiple
parents, etc. I'm mostly confused that it's marked as a FIXME when the
test should be doing wacky things to test various pieces of code.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 61/68] clk: sprd: composite: Switch to determine_rate
  2023-06-13 17:11   ` Harshit Mogalapalli
@ 2023-06-13 19:21     ` Stephen Boyd
  2023-06-13 19:45       ` Harshit Mogalapalli
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Boyd @ 2023-06-13 19:21 UTC (permalink / raw)
  To: Harshit Mogalapalli, Maxime Ripard, Michael Turquette
  Cc: linux-clk, Baolin Wang, Chunyan Zhang, Orson Zhai, Dan Carpenter,
	Dan Carpenter, kernel-janitors, Harshit Mogalapalli

Quoting Harshit Mogalapalli (2023-06-13 10:11:43)
> Hi Maxime,
> 
> On 05/05/23 4:56 pm, Maxime Ripard wrote:
> > The Spreadtrum composite clocks implements a mux with a set_parent
> > hook, but doesn't provide a determine_rate implementation.
> > 
> > This is a bit odd, since set_parent() is there to, as its name implies,
> > change the parent of a clock. However, the most likely candidate to
> > trigger that parent change is a call to clk_set_rate(), with
> > determine_rate() figuring out which parent is the best suited for a
> > given rate.
> > 
> > The other trigger would be a call to clk_set_parent(), but it's far less
> > used, and it doesn't look like there's any obvious user for that clock.
> > 
> > So, the set_parent hook is effectively unused, possibly because of an
> > oversight. However, it could also be an explicit decision by the
> > original author to avoid any reparenting but through an explicit call to
> > clk_set_parent().
> > 
> > The driver does implement round_rate() though, which means that we can
> > change the rate of the clock, but we will never get to change the
> > parent.
> > 
> > However, It's hard to tell whether it's been done on purpose or not.
> > 
> > Since we'll start mandating a determine_rate() implementation, let's
> > convert the round_rate() implementation to a determine_rate(), which
> > will also make the current behavior explicit. And if it was an
> > oversight, the clock behaviour can be adjusted later on.
> > 
> > Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
> > Cc: Chunyan Zhang <zhang.lyra@gmail.com>
> > Cc: Orson Zhai <orsonzhai@gmail.com>
> > Acked-by: Chunyan Zhang <zhang.lyra@gmail.com>
> > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> > ---
> >   drivers/clk/sprd/composite.c | 16 +++++++++++-----
> >   1 file changed, 11 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
> > index ebb644820b1e..d3a852720c07 100644
> > --- a/drivers/clk/sprd/composite.c
> > +++ b/drivers/clk/sprd/composite.c
> > @@ -9,13 +9,19 @@
> >   
> >   #include "composite.h"
> >   
> > -static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
> > -                             unsigned long *parent_rate)
> > +static int sprd_comp_determine_rate(struct clk_hw *hw,
> > +                                 struct clk_rate_request *req)
> >   {
> >       struct sprd_comp *cc = hw_to_sprd_comp(hw);
> > +     unsigned long rate;
> >   
> > -     return sprd_div_helper_round_rate(&cc->common, &cc->div,
> > -                                      rate, parent_rate);
> > +     rate = sprd_div_helper_round_rate(&cc->common, &cc->div,
> > +                                       req->rate, &req->best_parent_rate);
> > +     if (rate < 0)
> > +             return rate;
> 
> As rate is unsigned long, it can never be less than zero, so the above 
> if condition is never true. Smatch detected this.
> 
> Also if we just change the type of rate from unsigned long to long, will 
> the return type of the function "sprd_comp_determine_rate" being int is 
> correct?

The return type of the determine_rate clk_op is int. We can't change
that. Are you asking if long will be converted properly to an int when
it is signed?

I see that sprd_div_helper_round_rate() calls divider_round_rate() which
calls divider_round_rate_parent() which calls divider_determine_rate(),
so we might as well change everything here to call
divider_determine_rate() directly. That significantly cleans things up.

----8<----
diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
index d3a852720c07..ad6b6383e21f 100644
--- a/drivers/clk/sprd/composite.c
+++ b/drivers/clk/sprd/composite.c
@@ -13,15 +13,8 @@ static int sprd_comp_determine_rate(struct clk_hw *hw,
 				    struct clk_rate_request *req)
 {
 	struct sprd_comp *cc = hw_to_sprd_comp(hw);
-	unsigned long rate;
 
-	rate = sprd_div_helper_round_rate(&cc->common, &cc->div,
-					  req->rate, &req->best_parent_rate);
-	if (rate < 0)
-		return rate;
-
-	req->rate = rate;
-	return 0;
+	return divider_determine_rate(hw, req, NULL, cc->div.width, 0);
 }
 
 static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c
index 7621a1d1ab9c..c7261630cab4 100644
--- a/drivers/clk/sprd/div.c
+++ b/drivers/clk/sprd/div.c
@@ -9,23 +9,13 @@
 
 #include "div.h"
 
-long sprd_div_helper_round_rate(struct sprd_clk_common *common,
-				const struct sprd_div_internal *div,
-				unsigned long rate,
-				unsigned long *parent_rate)
-{
-	return divider_round_rate(&common->hw, rate, parent_rate,
-				  NULL, div->width, 0);
-}
-EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate);
-
 static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long *parent_rate)
 {
 	struct sprd_div *cd = hw_to_sprd_div(hw);
 
-	return sprd_div_helper_round_rate(&cd->common, &cd->div,
-					  rate, parent_rate);
+	return divider_round_rate(&cd->common.hw, rate, parent_rate, NULL,
+				  cd->div.width, 0);
 }
 
 unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
diff --git a/drivers/clk/sprd/div.h b/drivers/clk/sprd/div.h
index 6acfe6b179fc..f5d614b3dcf1 100644
--- a/drivers/clk/sprd/div.h
+++ b/drivers/clk/sprd/div.h
@@ -64,11 +64,6 @@ static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)
 	return container_of(common, struct sprd_div, common);
 }
 
-long sprd_div_helper_round_rate(struct sprd_clk_common *common,
-				const struct sprd_div_internal *div,
-				unsigned long rate,
-				unsigned long *parent_rate);
-
 unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
 					  const struct sprd_div_internal *div,
 					  unsigned long parent_rate);

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 61/68] clk: sprd: composite: Switch to determine_rate
  2023-06-13 19:21     ` Stephen Boyd
@ 2023-06-13 19:45       ` Harshit Mogalapalli
  0 siblings, 0 replies; 98+ messages in thread
From: Harshit Mogalapalli @ 2023-06-13 19:45 UTC (permalink / raw)
  To: Stephen Boyd, Maxime Ripard, Michael Turquette
  Cc: linux-clk, Baolin Wang, Chunyan Zhang, Orson Zhai, Dan Carpenter,
	Dan Carpenter, kernel-janitors

Hi Stephen,

On 14/06/23 12:51 am, Stephen Boyd wrote:
> Quoting Harshit Mogalapalli (2023-06-13 10:11:43)
>> Hi Maxime,
>>
>> On 05/05/23 4:56 pm, Maxime Ripard wrote:
>>> The Spreadtrum composite clocks implements a mux with a set_parent
>>> hook, but doesn't provide a determine_rate implementation.
>>>
>>> This is a bit odd, since set_parent() is there to, as its name implies,
>>> change the parent of a clock. However, the most likely candidate to
>>> trigger that parent change is a call to clk_set_rate(), with
>>> determine_rate() figuring out which parent is the best suited for a
>>> given rate.
>>>
>>> The other trigger would be a call to clk_set_parent(), but it's far less
>>> used, and it doesn't look like there's any obvious user for that clock.
>>>
>>> So, the set_parent hook is effectively unused, possibly because of an
>>> oversight. However, it could also be an explicit decision by the
>>> original author to avoid any reparenting but through an explicit call to
>>> clk_set_parent().
>>>
>>> The driver does implement round_rate() though, which means that we can
>>> change the rate of the clock, but we will never get to change the
>>> parent.
>>>
>>> However, It's hard to tell whether it's been done on purpose or not.
>>>
>>> Since we'll start mandating a determine_rate() implementation, let's
>>> convert the round_rate() implementation to a determine_rate(), which
>>> will also make the current behavior explicit. And if it was an
>>> oversight, the clock behaviour can be adjusted later on.
>>>
>>> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
>>> Cc: Chunyan Zhang <zhang.lyra@gmail.com>
>>> Cc: Orson Zhai <orsonzhai@gmail.com>
>>> Acked-by: Chunyan Zhang <zhang.lyra@gmail.com>
>>> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
>>> ---
>>>    drivers/clk/sprd/composite.c | 16 +++++++++++-----
>>>    1 file changed, 11 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
>>> index ebb644820b1e..d3a852720c07 100644
>>> --- a/drivers/clk/sprd/composite.c
>>> +++ b/drivers/clk/sprd/composite.c
>>> @@ -9,13 +9,19 @@
>>>    
>>>    #include "composite.h"
>>>    
>>> -static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
>>> -                             unsigned long *parent_rate)
>>> +static int sprd_comp_determine_rate(struct clk_hw *hw,
>>> +                                 struct clk_rate_request *req)
>>>    {
>>>        struct sprd_comp *cc = hw_to_sprd_comp(hw);
>>> +     unsigned long rate;
>>>    
>>> -     return sprd_div_helper_round_rate(&cc->common, &cc->div,
>>> -                                      rate, parent_rate);
>>> +     rate = sprd_div_helper_round_rate(&cc->common, &cc->div,
>>> +                                       req->rate, &req->best_parent_rate);
>>> +     if (rate < 0)
>>> +             return rate;
>>
>> As rate is unsigned long, it can never be less than zero, so the above
>> if condition is never true. Smatch detected this.
>>
>> Also if we just change the type of rate from unsigned long to long, will
>> the return type of the function "sprd_comp_determine_rate" being int is
>> correct?
> 
> The return type of the determine_rate clk_op is int. We can't change
> that. Are you asking if long will be converted properly to an int when
> it is signed?
> 

Yes, thanks for clarifying.

Thanks,
Harshit

> I see that sprd_div_helper_round_rate() calls divider_round_rate() which
> calls divider_round_rate_parent() which calls divider_determine_rate(),
> so we might as well change everything here to call
> divider_determine_rate() directly. That significantly cleans things up.
> 
> ----8<----
> diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
> index d3a852720c07..ad6b6383e21f 100644
> --- a/drivers/clk/sprd/composite.c
> +++ b/drivers/clk/sprd/composite.c
> @@ -13,15 +13,8 @@ static int sprd_comp_determine_rate(struct clk_hw *hw,
>   				    struct clk_rate_request *req)
>   {
>   	struct sprd_comp *cc = hw_to_sprd_comp(hw);
> -	unsigned long rate;
>   
> -	rate = sprd_div_helper_round_rate(&cc->common, &cc->div,
> -					  req->rate, &req->best_parent_rate);
> -	if (rate < 0)
> -		return rate;
> -
> -	req->rate = rate;
> -	return 0;
> +	return divider_determine_rate(hw, req, NULL, cc->div.width, 0);
>   }
>   
>   static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
> diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c
> index 7621a1d1ab9c..c7261630cab4 100644
> --- a/drivers/clk/sprd/div.c
> +++ b/drivers/clk/sprd/div.c
> @@ -9,23 +9,13 @@
>   
>   #include "div.h"
>   
> -long sprd_div_helper_round_rate(struct sprd_clk_common *common,
> -				const struct sprd_div_internal *div,
> -				unsigned long rate,
> -				unsigned long *parent_rate)
> -{
> -	return divider_round_rate(&common->hw, rate, parent_rate,
> -				  NULL, div->width, 0);
> -}
> -EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate);
> -
>   static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate,
>   				unsigned long *parent_rate)
>   {
>   	struct sprd_div *cd = hw_to_sprd_div(hw);
>   
> -	return sprd_div_helper_round_rate(&cd->common, &cd->div,
> -					  rate, parent_rate);
> +	return divider_round_rate(&cd->common.hw, rate, parent_rate, NULL,
> +				  cd->div.width, 0);
>   }
>   
>   unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
> diff --git a/drivers/clk/sprd/div.h b/drivers/clk/sprd/div.h
> index 6acfe6b179fc..f5d614b3dcf1 100644
> --- a/drivers/clk/sprd/div.h
> +++ b/drivers/clk/sprd/div.h
> @@ -64,11 +64,6 @@ static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)
>   	return container_of(common, struct sprd_div, common);
>   }
>   
> -long sprd_div_helper_round_rate(struct sprd_clk_common *common,
> -				const struct sprd_div_internal *div,
> -				unsigned long rate,
> -				unsigned long *parent_rate);
> -
>   unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
>   					  const struct sprd_div_internal *div,
>   					  unsigned long parent_rate);

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-05-05 11:26 ` [PATCH v4 65/68] clk: tegra: super: " Maxime Ripard
@ 2023-06-18 23:38   ` Dmitry Osipenko
  2023-06-19  7:26     ` Maxime Ripard
  0 siblings, 1 reply; 98+ messages in thread
From: Dmitry Osipenko @ 2023-06-18 23:38 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: linux-clk, Jonathan Hunter, Peter De Schrijver, Prashant Gaikwad,
	Thierry Reding, linux-tegra

05.05.2023 14:26, Maxime Ripard пишет:
> The Tegra super clocks implements a mux with a set_parent hook, but
> doesn't provide a determine_rate implementation.
> 
> This is a bit odd, since set_parent() is there to, as its name implies,
> change the parent of a clock. However, the most likely candidate to
> trigger that parent change is a call to clk_set_rate(), with
> determine_rate() figuring out which parent is the best suited for a
> given rate.
> 
> The other trigger would be a call to clk_set_parent(), but it's far less
> used, and it doesn't look like there's any obvious user for that clock.
> 
> So, the set_parent hook is effectively unused, possibly because of an
> oversight. However, it could also be an explicit decision by the
> original author to avoid any reparenting but through an explicit call to
> clk_set_parent().
> 
> The driver does implement round_rate() though, which means that we can
> change the rate of the clock, but we will never get to change the
> parent.
> 
> However, It's hard to tell whether it's been done on purpose or not.
> 
> Since we'll start mandating a determine_rate() implementation, let's
> convert the round_rate() implementation to a determine_rate(), which
> will also make the current behavior explicit. And if it was an
> oversight, the clock behaviour can be adjusted later on.
> 
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
> Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: linux-tegra@vger.kernel.org
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---
>  drivers/clk/tegra/clk-super.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
> index 3f3a7a203c5f..7ec47942720c 100644
> --- a/drivers/clk/tegra/clk-super.c
> +++ b/drivers/clk/tegra/clk-super.c
> @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
>  	.restore_context = clk_super_mux_restore_context,
>  };
>  
> -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
> -				 unsigned long *parent_rate)
> +static int clk_super_determine_rate(struct clk_hw *hw,
> +				    struct clk_rate_request *req)
>  {
>  	struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
>  	struct clk_hw *div_hw = &super->frac_div.hw;
> +	unsigned long rate;
>  
>  	__clk_hw_set_clk(div_hw, hw);
>  
> -	return super->div_ops->round_rate(div_hw, rate, parent_rate);
> +	rate = super->div_ops->round_rate(div_hw, req->rate,
> +					  &req->best_parent_rate);
> +	if (rate < 0)
> +		return rate;
> +
> +	req->rate = rate;
> +	return 0;
>  }
>  
>  static unsigned long clk_super_recalc_rate(struct clk_hw *hw,
> @@ -193,7 +200,7 @@ const struct clk_ops tegra_clk_super_ops = {
>  	.get_parent = clk_super_get_parent,
>  	.set_parent = clk_super_set_parent,
>  	.set_rate = clk_super_set_rate,
> -	.round_rate = clk_super_round_rate,
> +	.determine_rate = clk_super_determine_rate,
>  	.recalc_rate = clk_super_recalc_rate,
>  	.restore_context = clk_super_restore_context,
>  };
> 

Tegra30 doesn't boot anymore with this change. Best would be to keep the
old behaviour for both sclk and periph tegra clocks.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-06-18 23:38   ` Dmitry Osipenko
@ 2023-06-19  7:26     ` Maxime Ripard
  2023-06-20 19:09       ` Stephen Boyd
  0 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-06-19  7:26 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Michael Turquette, Stephen Boyd, linux-clk, Jonathan Hunter,
	Peter De Schrijver, Prashant Gaikwad, Thierry Reding,
	linux-tegra

[-- Attachment #1: Type: text/plain, Size: 4362 bytes --]

Hi Dmitry,

On Mon, Jun 19, 2023 at 02:38:59AM +0300, Dmitry Osipenko wrote:
> 05.05.2023 14:26, Maxime Ripard пишет:
> > The Tegra super clocks implements a mux with a set_parent hook, but
> > doesn't provide a determine_rate implementation.
> > 
> > This is a bit odd, since set_parent() is there to, as its name implies,
> > change the parent of a clock. However, the most likely candidate to
> > trigger that parent change is a call to clk_set_rate(), with
> > determine_rate() figuring out which parent is the best suited for a
> > given rate.
> > 
> > The other trigger would be a call to clk_set_parent(), but it's far less
> > used, and it doesn't look like there's any obvious user for that clock.
> > 
> > So, the set_parent hook is effectively unused, possibly because of an
> > oversight. However, it could also be an explicit decision by the
> > original author to avoid any reparenting but through an explicit call to
> > clk_set_parent().
> > 
> > The driver does implement round_rate() though, which means that we can
> > change the rate of the clock, but we will never get to change the
> > parent.
> > 
> > However, It's hard to tell whether it's been done on purpose or not.
> > 
> > Since we'll start mandating a determine_rate() implementation, let's
> > convert the round_rate() implementation to a determine_rate(), which
> > will also make the current behavior explicit. And if it was an
> > oversight, the clock behaviour can be adjusted later on.
> > 
> > Cc: Jonathan Hunter <jonathanh@nvidia.com>
> > Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
> > Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
> > Cc: Thierry Reding <thierry.reding@gmail.com>
> > Cc: linux-tegra@vger.kernel.org
> > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> > ---
> >  drivers/clk/tegra/clk-super.c | 15 +++++++++++----
> >  1 file changed, 11 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
> > index 3f3a7a203c5f..7ec47942720c 100644
> > --- a/drivers/clk/tegra/clk-super.c
> > +++ b/drivers/clk/tegra/clk-super.c
> > @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
> >  	.restore_context = clk_super_mux_restore_context,
> >  };
> >  
> > -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
> > -				 unsigned long *parent_rate)
> > +static int clk_super_determine_rate(struct clk_hw *hw,
> > +				    struct clk_rate_request *req)
> >  {
> >  	struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
> >  	struct clk_hw *div_hw = &super->frac_div.hw;
> > +	unsigned long rate;
> >  
> >  	__clk_hw_set_clk(div_hw, hw);
> >  
> > -	return super->div_ops->round_rate(div_hw, rate, parent_rate);
> > +	rate = super->div_ops->round_rate(div_hw, req->rate,
> > +					  &req->best_parent_rate);
> > +	if (rate < 0)
> > +		return rate;
> > +
> > +	req->rate = rate;
> > +	return 0;
> >  }
> >  
> >  static unsigned long clk_super_recalc_rate(struct clk_hw *hw,
> > @@ -193,7 +200,7 @@ const struct clk_ops tegra_clk_super_ops = {
> >  	.get_parent = clk_super_get_parent,
> >  	.set_parent = clk_super_set_parent,
> >  	.set_rate = clk_super_set_rate,
> > -	.round_rate = clk_super_round_rate,
> > +	.determine_rate = clk_super_determine_rate,
> >  	.recalc_rate = clk_super_recalc_rate,
> >  	.restore_context = clk_super_restore_context,
> >  };
> > 
> 
> Tegra30 doesn't boot anymore with this change. Best would be to keep the
> old behaviour for both sclk and periph tegra clocks.

I took a closer look at the patch and can't find anything different to
what the core is doing if there's a round_rate implementation:
https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L1459

Also, it's not clear to me how that driver is used. It looks like
div_ops is always supposed to be set, and super clocks are registered
with either tegra_clk_register_super_clk() or tegra_clk_register_super_mux()

tegra_clk_register_super_clk() sets the div_ops pointer to
tegra_clk_super_ops, but tegra30 doesn't seem to call it.

tegra_clk_register_super_mux() doesn't set the div_ops pointer, but is
used by tegra30, so I would assume that it's the broken one. But I'm
confused, since div_ops doesn't seem to be set anywhere?

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 07/68] clk: test: Add a determine_rate hook
  2023-06-13 18:39       ` Stephen Boyd
@ 2023-06-19 13:20         ` Maxime Ripard
  0 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-06-19 13:20 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: Michael Turquette, linux-clk

[-- Attachment #1: Type: text/plain, Size: 3095 bytes --]

Hi Stephen,

On Tue, Jun 13, 2023 at 11:39:58AM -0700, Stephen Boyd wrote:
> Quoting Maxime Ripard (2023-06-13 01:21:59)
> > On Thu, Jun 08, 2023 at 06:41:56PM -0700, Stephen Boyd wrote:
> > > Quoting Maxime Ripard (2023-05-05 04:25:09)
> > 
> > > > +        * __clk_mux_determine_rate() here, if we use it and call
> > > > +        * clk_round_rate() or clk_set_rate() with a rate lower than
> > > > +        * what all the parents can provide, it will return -EINVAL.
> > > > +        *
> > > > +        * This is due to the fact that it has the undocumented
> > > > +        * behaviour to always pick up the closest rate higher than the
> > > > +        * requested rate. If we get something lower, it thus considers
> > > > +        * that it's not acceptable and will return an error.
> > > > +        *
> > > > +        * It's somewhat inconsistent and creates a weird threshold
> > > > +        * between rates above the parent rate which would be rounded to
> > > > +        * what the parent can provide, but rates below will simply
> > > > +        * return an error.
> > > > +        */
> > 
> > I guess it's mostly a policy decision: __clk_mux_determine_rate() always
> > has been returning rates that are lower or equal to the target rate.
> > 
> > If no parent can provide one, then the obvious solution is to error out,
> > which creates the inconsistency mentioned above.
> > 
> > Another solution would be to pick up a parent by default (the current
> > one maybe?) but then we could return a rate higher than the target rate
> > which breaks what we've been doing so far.
> > 
> > I'm not sure if one is better than the other.
> 
> We should pick a rounding policy that we want for the test. The test
> shouldn't be checking the rounding policy. It should be checking that
> the code under test does what is expected when the rounding policy is
> what we choose.
> 
> If __clk_mux_determine_rate() returns an error when the rate is lower
> than the parent supports then we should test that as well and make sure
> it does return an error in this case. We can directly call
> __clk_mux_determine_rate() after registering the clks so that the
> function is isolated.

I guess my point is that, in general, we don't really expect an error in
clk_round_rate(). Most clocks will clamp the rates between the minimum
and maximum allowed and will select the closest parent or dividers to
match that rate. So we could end up with a rate fairly different from
the argument, but we'll get a rate.

For muxes using __clk_mux_determine_rate*() without CLK_SET_RATE_PARENT,
if the rate is too low (or if the range is loo low) and is right below
what one of the parent can provide, we end up with -EINVAL.

AFAIK, it's pretty much the only situation where that happens. A fixed
clock will always return its fixed rate for example, even if the rate is
very different from what we asked for. But for some reason, on some
muxes, with some rates, boom, EINVAL.

It's very unexpected and inconsistent to me. Hence the FIXME.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-06-19  7:26     ` Maxime Ripard
@ 2023-06-20 19:09       ` Stephen Boyd
  2023-06-21 15:35         ` Thierry Reding
  0 siblings, 1 reply; 98+ messages in thread
From: Stephen Boyd @ 2023-06-20 19:09 UTC (permalink / raw)
  To: Dmitry Osipenko, Maxime Ripard
  Cc: Michael Turquette, linux-clk, Jonathan Hunter,
	Peter De Schrijver, Prashant Gaikwad, Thierry Reding,
	linux-tegra

Quoting Maxime Ripard (2023-06-19 00:26:19)
> On Mon, Jun 19, 2023 at 02:38:59AM +0300, Dmitry Osipenko wrote:
> > 05.05.2023 14:26, Maxime Ripard пишет:
> > > 
> > > diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
> > > index 3f3a7a203c5f..7ec47942720c 100644
> > > --- a/drivers/clk/tegra/clk-super.c
> > > +++ b/drivers/clk/tegra/clk-super.c
> > > @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
> > >     .restore_context = clk_super_mux_restore_context,
> > >  };
> > >  
> > > -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
> > > -                            unsigned long *parent_rate)
> > > +static int clk_super_determine_rate(struct clk_hw *hw,
> > > +                               struct clk_rate_request *req)
> > >  {
> > >     struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
> > >     struct clk_hw *div_hw = &super->frac_div.hw;
> > > +   unsigned long rate;
> > >  
> > >     __clk_hw_set_clk(div_hw, hw);
> > >  
> > > -   return super->div_ops->round_rate(div_hw, rate, parent_rate);
> > > +   rate = super->div_ops->round_rate(div_hw, req->rate,
> > > +                                     &req->best_parent_rate);
> > > +   if (rate < 0)

There's the report that this condition is never possible. Maybe the
previous code was relying on an error value sometimes. Can we add
determine_rate to the div_ops and simplify this code? I asked on the
list for that earlier.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-06-20 19:09       ` Stephen Boyd
@ 2023-06-21 15:35         ` Thierry Reding
  2023-06-22 11:24           ` Maxime Ripard
                             ` (2 more replies)
  0 siblings, 3 replies; 98+ messages in thread
From: Thierry Reding @ 2023-06-21 15:35 UTC (permalink / raw)
  To: Stephen Boyd, Dmitry Osipenko
  Cc: Maxime Ripard, Michael Turquette, linux-clk, Jonathan Hunter,
	Peter De Schrijver, Prashant Gaikwad, linux-tegra

[-- Attachment #1: Type: text/plain, Size: 3024 bytes --]

On Tue, Jun 20, 2023 at 12:09:09PM -0700, Stephen Boyd wrote:
> Quoting Maxime Ripard (2023-06-19 00:26:19)
> > On Mon, Jun 19, 2023 at 02:38:59AM +0300, Dmitry Osipenko wrote:
> > > 05.05.2023 14:26, Maxime Ripard пишет:
> > > > 
> > > > diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
> > > > index 3f3a7a203c5f..7ec47942720c 100644
> > > > --- a/drivers/clk/tegra/clk-super.c
> > > > +++ b/drivers/clk/tegra/clk-super.c
> > > > @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
> > > >     .restore_context = clk_super_mux_restore_context,
> > > >  };
> > > >  
> > > > -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
> > > > -                            unsigned long *parent_rate)
> > > > +static int clk_super_determine_rate(struct clk_hw *hw,
> > > > +                               struct clk_rate_request *req)
> > > >  {
> > > >     struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
> > > >     struct clk_hw *div_hw = &super->frac_div.hw;
> > > > +   unsigned long rate;
> > > >  
> > > >     __clk_hw_set_clk(div_hw, hw);
> > > >  
> > > > -   return super->div_ops->round_rate(div_hw, rate, parent_rate);
> > > > +   rate = super->div_ops->round_rate(div_hw, req->rate,
> > > > +                                     &req->best_parent_rate);
> > > > +   if (rate < 0)
> 
> There's the report that this condition is never possible. Maybe the
> previous code was relying on an error value sometimes. Can we add
> determine_rate to the div_ops and simplify this code? I asked on the
> list for that earlier.

I was able to reproduce this on a Tegra30 Beaver, but the problem is
more straightforward than this. The crash I was seeing during boot was
because cclk_super_determine_rate() was still calling the round_rate()
callback from tegra_clk_super_ops, which this patch removed (and added
determine_rate() instead).

The following fixes the problem for me. It's basically converting the
round_rate() call to an equivalent determine_rate() call.

Dmitry, can you verify that this fixes the issue that you were seeing?

Thierry

--- >8 ---
diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c
index 68d7bcd5fc8a..8a2bb4ae4fd2 100644
--- a/drivers/clk/tegra/clk-tegra-super-cclk.c
+++ b/drivers/clk/tegra/clk-tegra-super-cclk.c
@@ -86,9 +86,16 @@ static int cclk_super_determine_rate(struct clk_hw *hw,
 	if (rate <= pllp_rate) {
 		if (super->flags & TEGRA20_SUPER_CLK)
 			rate = pllp_rate;
-		else
-			rate = tegra_clk_super_ops.round_rate(hw, rate,
-							      &pllp_rate);
+		else {
+			struct clk_rate_request parent = {
+				.rate = req->rate,
+				.best_parent_rate = pllp_rate,
+			};
+
+			tegra_clk_super_ops.determine_rate(hw, &parent);
+			pllp_rate = parent.best_parent_rate;
+			rate = parent.rate;
+		}
 
 		req->best_parent_rate = pllp_rate;
 		req->best_parent_hw = pllp_hw;
--- >8 ---

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-06-21 15:35         ` Thierry Reding
@ 2023-06-22 11:24           ` Maxime Ripard
  2023-06-23 14:51             ` Thierry Reding
  2023-06-22 11:32           ` Dmitry Osipenko
  2023-06-30  4:57           ` Stephen Boyd
  2 siblings, 1 reply; 98+ messages in thread
From: Maxime Ripard @ 2023-06-22 11:24 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Boyd, Dmitry Osipenko, Michael Turquette, linux-clk,
	Jonathan Hunter, Peter De Schrijver, Prashant Gaikwad,
	linux-tegra

[-- Attachment #1: Type: text/plain, Size: 3147 bytes --]

Hi,

On Wed, Jun 21, 2023 at 05:35:09PM +0200, Thierry Reding wrote:
> On Tue, Jun 20, 2023 at 12:09:09PM -0700, Stephen Boyd wrote:
> > Quoting Maxime Ripard (2023-06-19 00:26:19)
> > > On Mon, Jun 19, 2023 at 02:38:59AM +0300, Dmitry Osipenko wrote:
> > > > 05.05.2023 14:26, Maxime Ripard пишет:
> > > > > 
> > > > > diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
> > > > > index 3f3a7a203c5f..7ec47942720c 100644
> > > > > --- a/drivers/clk/tegra/clk-super.c
> > > > > +++ b/drivers/clk/tegra/clk-super.c
> > > > > @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
> > > > >     .restore_context = clk_super_mux_restore_context,
> > > > >  };
> > > > >  
> > > > > -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
> > > > > -                            unsigned long *parent_rate)
> > > > > +static int clk_super_determine_rate(struct clk_hw *hw,
> > > > > +                               struct clk_rate_request *req)
> > > > >  {
> > > > >     struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
> > > > >     struct clk_hw *div_hw = &super->frac_div.hw;
> > > > > +   unsigned long rate;
> > > > >  
> > > > >     __clk_hw_set_clk(div_hw, hw);
> > > > >  
> > > > > -   return super->div_ops->round_rate(div_hw, rate, parent_rate);
> > > > > +   rate = super->div_ops->round_rate(div_hw, req->rate,
> > > > > +                                     &req->best_parent_rate);
> > > > > +   if (rate < 0)
> > 
> > There's the report that this condition is never possible. Maybe the
> > previous code was relying on an error value sometimes. Can we add
> > determine_rate to the div_ops and simplify this code? I asked on the
> > list for that earlier.
> 
> I was able to reproduce this on a Tegra30 Beaver, but the problem is
> more straightforward than this. The crash I was seeing during boot was
> because cclk_super_determine_rate() was still calling the round_rate()
> callback from tegra_clk_super_ops, which this patch removed (and added
> determine_rate() instead).
> 
> The following fixes the problem for me. It's basically converting the
> round_rate() call to an equivalent determine_rate() call.

Thanks for figuring it out :)

> Dmitry, can you verify that this fixes the issue that you were seeing?
> 
> Thierry
> 
> --- >8 ---
> diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c
> index 68d7bcd5fc8a..8a2bb4ae4fd2 100644
> --- a/drivers/clk/tegra/clk-tegra-super-cclk.c
> +++ b/drivers/clk/tegra/clk-tegra-super-cclk.c
> @@ -86,9 +86,16 @@ static int cclk_super_determine_rate(struct clk_hw *hw,
>  	if (rate <= pllp_rate) {
>  		if (super->flags & TEGRA20_SUPER_CLK)
>  			rate = pllp_rate;
> -		else
> -			rate = tegra_clk_super_ops.round_rate(hw, rate,
> -							      &pllp_rate);
> +		else {
> +			struct clk_rate_request parent = {
> +				.rate = req->rate,
> +				.best_parent_rate = pllp_rate,
> +			};

If it works and you submit a patch later, this needs to be changed to
clk_hw_init_rate_request()

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-06-21 15:35         ` Thierry Reding
  2023-06-22 11:24           ` Maxime Ripard
@ 2023-06-22 11:32           ` Dmitry Osipenko
  2023-06-30  4:57           ` Stephen Boyd
  2 siblings, 0 replies; 98+ messages in thread
From: Dmitry Osipenko @ 2023-06-22 11:32 UTC (permalink / raw)
  To: Thierry Reding, Stephen Boyd
  Cc: Maxime Ripard, Michael Turquette, linux-clk, Jonathan Hunter,
	Peter De Schrijver, Prashant Gaikwad, linux-tegra

21.06.2023 18:35, Thierry Reding пишет:
> On Tue, Jun 20, 2023 at 12:09:09PM -0700, Stephen Boyd wrote:
>> Quoting Maxime Ripard (2023-06-19 00:26:19)
>>> On Mon, Jun 19, 2023 at 02:38:59AM +0300, Dmitry Osipenko wrote:
>>>> 05.05.2023 14:26, Maxime Ripard пишет:
>>>>>
>>>>> diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
>>>>> index 3f3a7a203c5f..7ec47942720c 100644
>>>>> --- a/drivers/clk/tegra/clk-super.c
>>>>> +++ b/drivers/clk/tegra/clk-super.c
>>>>> @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
>>>>>     .restore_context = clk_super_mux_restore_context,
>>>>>  };
>>>>>  
>>>>> -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
>>>>> -                            unsigned long *parent_rate)
>>>>> +static int clk_super_determine_rate(struct clk_hw *hw,
>>>>> +                               struct clk_rate_request *req)
>>>>>  {
>>>>>     struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
>>>>>     struct clk_hw *div_hw = &super->frac_div.hw;
>>>>> +   unsigned long rate;
>>>>>  
>>>>>     __clk_hw_set_clk(div_hw, hw);
>>>>>  
>>>>> -   return super->div_ops->round_rate(div_hw, rate, parent_rate);
>>>>> +   rate = super->div_ops->round_rate(div_hw, req->rate,
>>>>> +                                     &req->best_parent_rate);
>>>>> +   if (rate < 0)
>>
>> There's the report that this condition is never possible. Maybe the
>> previous code was relying on an error value sometimes. Can we add
>> determine_rate to the div_ops and simplify this code? I asked on the
>> list for that earlier.
> 
> I was able to reproduce this on a Tegra30 Beaver, but the problem is
> more straightforward than this. The crash I was seeing during boot was
> because cclk_super_determine_rate() was still calling the round_rate()
> callback from tegra_clk_super_ops, which this patch removed (and added
> determine_rate() instead).
> 
> The following fixes the problem for me. It's basically converting the
> round_rate() call to an equivalent determine_rate() call.
> 
> Dmitry, can you verify that this fixes the issue that you were seeing?
> 
> Thierry
> 
> --- >8 ---
> diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c
> index 68d7bcd5fc8a..8a2bb4ae4fd2 100644
> --- a/drivers/clk/tegra/clk-tegra-super-cclk.c
> +++ b/drivers/clk/tegra/clk-tegra-super-cclk.c
> @@ -86,9 +86,16 @@ static int cclk_super_determine_rate(struct clk_hw *hw,
>  	if (rate <= pllp_rate) {
>  		if (super->flags & TEGRA20_SUPER_CLK)
>  			rate = pllp_rate;
> -		else
> -			rate = tegra_clk_super_ops.round_rate(hw, rate,
> -							      &pllp_rate);
> +		else {
> +			struct clk_rate_request parent = {
> +				.rate = req->rate,
> +				.best_parent_rate = pllp_rate,
> +			};
> +
> +			tegra_clk_super_ops.determine_rate(hw, &parent);
> +			pllp_rate = parent.best_parent_rate;
> +			rate = parent.rate;
> +		}
>  
>  		req->best_parent_rate = pllp_rate;
>  		req->best_parent_hw = pllp_hw;
> --- >8 ---

Thank you for the fix, it works! Feel free to add my t-b :)



^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-06-22 11:24           ` Maxime Ripard
@ 2023-06-23 14:51             ` Thierry Reding
  2023-06-23 15:02               ` Maxime Ripard
  0 siblings, 1 reply; 98+ messages in thread
From: Thierry Reding @ 2023-06-23 14:51 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Stephen Boyd, Dmitry Osipenko, Michael Turquette, linux-clk,
	Jonathan Hunter, Peter De Schrijver, Prashant Gaikwad,
	linux-tegra

[-- Attachment #1: Type: text/plain, Size: 3862 bytes --]

On Thu, Jun 22, 2023 at 01:24:12PM +0200, Maxime Ripard wrote:
> Hi,
> 
> On Wed, Jun 21, 2023 at 05:35:09PM +0200, Thierry Reding wrote:
> > On Tue, Jun 20, 2023 at 12:09:09PM -0700, Stephen Boyd wrote:
> > > Quoting Maxime Ripard (2023-06-19 00:26:19)
> > > > On Mon, Jun 19, 2023 at 02:38:59AM +0300, Dmitry Osipenko wrote:
> > > > > 05.05.2023 14:26, Maxime Ripard пишет:
> > > > > > 
> > > > > > diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
> > > > > > index 3f3a7a203c5f..7ec47942720c 100644
> > > > > > --- a/drivers/clk/tegra/clk-super.c
> > > > > > +++ b/drivers/clk/tegra/clk-super.c
> > > > > > @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
> > > > > >     .restore_context = clk_super_mux_restore_context,
> > > > > >  };
> > > > > >  
> > > > > > -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
> > > > > > -                            unsigned long *parent_rate)
> > > > > > +static int clk_super_determine_rate(struct clk_hw *hw,
> > > > > > +                               struct clk_rate_request *req)
> > > > > >  {
> > > > > >     struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
> > > > > >     struct clk_hw *div_hw = &super->frac_div.hw;
> > > > > > +   unsigned long rate;
> > > > > >  
> > > > > >     __clk_hw_set_clk(div_hw, hw);
> > > > > >  
> > > > > > -   return super->div_ops->round_rate(div_hw, rate, parent_rate);
> > > > > > +   rate = super->div_ops->round_rate(div_hw, req->rate,
> > > > > > +                                     &req->best_parent_rate);
> > > > > > +   if (rate < 0)
> > > 
> > > There's the report that this condition is never possible. Maybe the
> > > previous code was relying on an error value sometimes. Can we add
> > > determine_rate to the div_ops and simplify this code? I asked on the
> > > list for that earlier.
> > 
> > I was able to reproduce this on a Tegra30 Beaver, but the problem is
> > more straightforward than this. The crash I was seeing during boot was
> > because cclk_super_determine_rate() was still calling the round_rate()
> > callback from tegra_clk_super_ops, which this patch removed (and added
> > determine_rate() instead).
> > 
> > The following fixes the problem for me. It's basically converting the
> > round_rate() call to an equivalent determine_rate() call.
> 
> Thanks for figuring it out :)
> 
> > Dmitry, can you verify that this fixes the issue that you were seeing?
> > 
> > Thierry
> > 
> > --- >8 ---
> > diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c
> > index 68d7bcd5fc8a..8a2bb4ae4fd2 100644
> > --- a/drivers/clk/tegra/clk-tegra-super-cclk.c
> > +++ b/drivers/clk/tegra/clk-tegra-super-cclk.c
> > @@ -86,9 +86,16 @@ static int cclk_super_determine_rate(struct clk_hw *hw,
> >  	if (rate <= pllp_rate) {
> >  		if (super->flags & TEGRA20_SUPER_CLK)
> >  			rate = pllp_rate;
> > -		else
> > -			rate = tegra_clk_super_ops.round_rate(hw, rate,
> > -							      &pllp_rate);
> > +		else {
> > +			struct clk_rate_request parent = {
> > +				.rate = req->rate,
> > +				.best_parent_rate = pllp_rate,
> > +			};
> 
> If it works and you submit a patch later, this needs to be changed to
> clk_hw_init_rate_request()

I've tried this and while it seems to work, this doesn't seem to be
exactly the same as what the original code does. From what I understand
the parent clock can be either pll-p or pll-x, but what we want to do in
this branch is check what a configuration would look like for pll-p as
the parent. clk_hw_init_rate_request() would initialize the request with
data for the current parent, even if that's not pll-p, so I'm a bit
hesitant to go with that instead of manually hard-coding this to pll-p.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-06-23 14:51             ` Thierry Reding
@ 2023-06-23 15:02               ` Maxime Ripard
  0 siblings, 0 replies; 98+ messages in thread
From: Maxime Ripard @ 2023-06-23 15:02 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Boyd, Dmitry Osipenko, Michael Turquette, linux-clk,
	Jonathan Hunter, Peter De Schrijver, Prashant Gaikwad,
	linux-tegra

[-- Attachment #1: Type: text/plain, Size: 4274 bytes --]

On Fri, Jun 23, 2023 at 04:51:27PM +0200, Thierry Reding wrote:
> On Thu, Jun 22, 2023 at 01:24:12PM +0200, Maxime Ripard wrote:
> > Hi,
> > 
> > On Wed, Jun 21, 2023 at 05:35:09PM +0200, Thierry Reding wrote:
> > > On Tue, Jun 20, 2023 at 12:09:09PM -0700, Stephen Boyd wrote:
> > > > Quoting Maxime Ripard (2023-06-19 00:26:19)
> > > > > On Mon, Jun 19, 2023 at 02:38:59AM +0300, Dmitry Osipenko wrote:
> > > > > > 05.05.2023 14:26, Maxime Ripard пишет:
> > > > > > > 
> > > > > > > diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
> > > > > > > index 3f3a7a203c5f..7ec47942720c 100644
> > > > > > > --- a/drivers/clk/tegra/clk-super.c
> > > > > > > +++ b/drivers/clk/tegra/clk-super.c
> > > > > > > @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = {
> > > > > > >     .restore_context = clk_super_mux_restore_context,
> > > > > > >  };
> > > > > > >  
> > > > > > > -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
> > > > > > > -                            unsigned long *parent_rate)
> > > > > > > +static int clk_super_determine_rate(struct clk_hw *hw,
> > > > > > > +                               struct clk_rate_request *req)
> > > > > > >  {
> > > > > > >     struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
> > > > > > >     struct clk_hw *div_hw = &super->frac_div.hw;
> > > > > > > +   unsigned long rate;
> > > > > > >  
> > > > > > >     __clk_hw_set_clk(div_hw, hw);
> > > > > > >  
> > > > > > > -   return super->div_ops->round_rate(div_hw, rate, parent_rate);
> > > > > > > +   rate = super->div_ops->round_rate(div_hw, req->rate,
> > > > > > > +                                     &req->best_parent_rate);
> > > > > > > +   if (rate < 0)
> > > > 
> > > > There's the report that this condition is never possible. Maybe the
> > > > previous code was relying on an error value sometimes. Can we add
> > > > determine_rate to the div_ops and simplify this code? I asked on the
> > > > list for that earlier.
> > > 
> > > I was able to reproduce this on a Tegra30 Beaver, but the problem is
> > > more straightforward than this. The crash I was seeing during boot was
> > > because cclk_super_determine_rate() was still calling the round_rate()
> > > callback from tegra_clk_super_ops, which this patch removed (and added
> > > determine_rate() instead).
> > > 
> > > The following fixes the problem for me. It's basically converting the
> > > round_rate() call to an equivalent determine_rate() call.
> > 
> > Thanks for figuring it out :)
> > 
> > > Dmitry, can you verify that this fixes the issue that you were seeing?
> > > 
> > > Thierry
> > > 
> > > --- >8 ---
> > > diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c
> > > index 68d7bcd5fc8a..8a2bb4ae4fd2 100644
> > > --- a/drivers/clk/tegra/clk-tegra-super-cclk.c
> > > +++ b/drivers/clk/tegra/clk-tegra-super-cclk.c
> > > @@ -86,9 +86,16 @@ static int cclk_super_determine_rate(struct clk_hw *hw,
> > >  	if (rate <= pllp_rate) {
> > >  		if (super->flags & TEGRA20_SUPER_CLK)
> > >  			rate = pllp_rate;
> > > -		else
> > > -			rate = tegra_clk_super_ops.round_rate(hw, rate,
> > > -							      &pllp_rate);
> > > +		else {
> > > +			struct clk_rate_request parent = {
> > > +				.rate = req->rate,
> > > +				.best_parent_rate = pllp_rate,
> > > +			};
> > 
> > If it works and you submit a patch later, this needs to be changed to
> > clk_hw_init_rate_request()
> 
> I've tried this and while it seems to work, this doesn't seem to be
> exactly the same as what the original code does. From what I understand
> the parent clock can be either pll-p or pll-x, but what we want to do in
> this branch is check what a configuration would look like for pll-p as
> the parent. clk_hw_init_rate_request() would initialize the request with
> data for the current parent, even if that's not pll-p, so I'm a bit
> hesitant to go with that instead of manually hard-coding this to pll-p.

Ah, yes, sorry.

Maybe we need some kind of variant to address this then, but for the
time being you can at least set req->min_rate and req->max_rate using
clk_hw_get_rate_range.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v4 65/68] clk: tegra: super: Switch to determine_rate
  2023-06-21 15:35         ` Thierry Reding
  2023-06-22 11:24           ` Maxime Ripard
  2023-06-22 11:32           ` Dmitry Osipenko
@ 2023-06-30  4:57           ` Stephen Boyd
  2 siblings, 0 replies; 98+ messages in thread
From: Stephen Boyd @ 2023-06-30  4:57 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding
  Cc: Maxime Ripard, Michael Turquette, linux-clk, Jonathan Hunter,
	Peter De Schrijver, Prashant Gaikwad, linux-tegra

Quoting Thierry Reding (2023-06-21 08:35:09)
> 
> I was able to reproduce this on a Tegra30 Beaver, but the problem is
> more straightforward than this. The crash I was seeing during boot was
> because cclk_super_determine_rate() was still calling the round_rate()
> callback from tegra_clk_super_ops, which this patch removed (and added
> determine_rate() instead).
> 
> The following fixes the problem for me. It's basically converting the
> round_rate() call to an equivalent determine_rate() call.
> 
> Dmitry, can you verify that this fixes the issue that you were seeing?
> 

Can you send this as a proper patch? I'd like to send this early next
week.

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2023-06-30  4:57 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-05 11:25 [PATCH v4 00/68] clk: Make determine_rate mandatory for muxes Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 01/68] clk: Export clk_hw_forward_rate_request() Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 02/68] clk: test: Fix type sign of rounded rate variables Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 03/68] clk: Move no reparent case into a separate function Maxime Ripard
     [not found]   ` <CGME20230613111502eucas1p2644889c9de1abfe1a14a3b549772f247@eucas1p2.samsung.com>
2023-06-13 11:15     ` Marek Szyprowski
     [not found]       ` <CGME20230613121511eucas1p2595e0de21fadbafc1f6ffdc5636b9271@eucas1p2.samsung.com>
2023-06-13 12:15         ` Marek Szyprowski
2023-06-13 12:29           ` Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 04/68] clk: Introduce clk_hw_determine_rate_no_reparent() Maxime Ripard
2023-05-05 17:15   ` kernel test robot
2023-05-05 11:25 ` [PATCH v4 05/68] clk: lan966x: Remove unused round_rate hook Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 06/68] clk: nodrv: Add a determine_rate hook Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 07/68] clk: test: " Maxime Ripard
2023-06-09  1:41   ` Stephen Boyd
2023-06-13  8:21     ` Maxime Ripard
2023-06-13 18:39       ` Stephen Boyd
2023-06-19 13:20         ` Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 08/68] clk: actions: composite: Add a determine_rate hook for pass clk Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 09/68] clk: at91: main: Add a determine_rate hook Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 10/68] clk: at91: sckc: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 11/68] clk: berlin: div: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 12/68] clk: cdce706: " Maxime Ripard
2023-05-05 21:00   ` kernel test robot
2023-05-05 11:25 ` [PATCH v4 13/68] clk: k210: pll: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 14/68] clk: k210: aclk: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 15/68] clk: k210: mux: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 16/68] clk: lmk04832: clkout: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 17/68] clk: lochnagar: " Maxime Ripard
2023-05-05 17:46   ` kernel test robot
2023-05-05 18:47   ` kernel test robot
2023-05-05 11:25 ` [PATCH v4 18/68] clk: qoriq: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 19/68] clk: si5341: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 20/68] clk: stm32f4: mux: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 21/68] clk: vc5: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 22/68] clk: vc5: clkout: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 23/68] clk: wm831x: " Maxime Ripard
2023-05-05 18:06   ` kernel test robot
2023-05-05 11:25 ` [PATCH v4 24/68] clk: davinci: da8xx-cfgchip: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 25/68] " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 26/68] clk: imx: busy: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 27/68] clk: imx: fixup-mux: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 28/68] clk: imx: scu: " Maxime Ripard
2023-05-06  0:37   ` kernel test robot
2023-05-05 11:25 ` [PATCH v4 29/68] clk: mediatek: cpumux: " Maxime Ripard
2023-05-08  2:36   ` Chen-Yu Tsai
2023-05-05 11:25 ` [PATCH v4 30/68] clk: pxa: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 31/68] clk: renesas: r9a06g032: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 32/68] clk: socfpga: gate: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 33/68] clk: stm32: core: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 34/68] clk: tegra: bpmp: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 35/68] clk: tegra: super: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 36/68] clk: tegra: periph: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 37/68] clk: ux500: prcmu: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 38/68] clk: ux500: sysctrl: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 39/68] clk: versatile: sp810: " Maxime Ripard
2023-05-05 11:30   ` Linus Walleij
2023-05-05 19:04     ` Pawel Moll
2023-05-05 11:25 ` [PATCH v4 40/68] drm/tegra: sor: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 41/68] phy: cadence: sierra: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 42/68] phy: cadence: torrent: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 43/68] phy: ti: am654-serdes: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 44/68] phy: ti: j721e-wiz: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 45/68] rtc: sun6i: " Maxime Ripard
2023-05-05 18:46   ` Jernej Škrabec
2023-05-05 11:25 ` [PATCH v4 46/68] ASoC: tlv320aic32x4: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 47/68] clk: actions: composite: div: Switch to determine_rate Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 48/68] clk: actions: composite: fact: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 49/68] clk: at91: smd: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 50/68] clk: axi-clkgen: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 51/68] clk: cdce706: divider: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 52/68] clk: cdce706: clkout: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 53/68] clk: si5341: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 54/68] clk: si5351: pll: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 55/68] clk: si5351: msynth: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 56/68] clk: si5351: clkout: " Maxime Ripard
2023-05-05 11:25 ` [PATCH v4 57/68] clk: da8xx: clk48: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 58/68] clk: imx: scu: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 59/68] clk: ingenic: cgu: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 60/68] clk: ingenic: tcu: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 61/68] clk: sprd: composite: " Maxime Ripard
2023-06-13 17:11   ` Harshit Mogalapalli
2023-06-13 19:21     ` Stephen Boyd
2023-06-13 19:45       ` Harshit Mogalapalli
2023-05-05 11:26 ` [PATCH v4 62/68] clk: st: flexgen: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 63/68] clk: stm32: composite: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 64/68] clk: tegra: periph: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 65/68] clk: tegra: super: " Maxime Ripard
2023-06-18 23:38   ` Dmitry Osipenko
2023-06-19  7:26     ` Maxime Ripard
2023-06-20 19:09       ` Stephen Boyd
2023-06-21 15:35         ` Thierry Reding
2023-06-22 11:24           ` Maxime Ripard
2023-06-23 14:51             ` Thierry Reding
2023-06-23 15:02               ` Maxime Ripard
2023-06-22 11:32           ` Dmitry Osipenko
2023-06-30  4:57           ` Stephen Boyd
2023-05-05 11:26 ` [PATCH v4 66/68] ASoC: tlv320aic32x4: pll: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 67/68] ASoC: tlv320aic32x4: div: " Maxime Ripard
2023-05-05 11:26 ` [PATCH v4 68/68] clk: Forbid to register a mux without determine_rate Maxime Ripard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).