All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Ripard <maxime@cerno.tech>
To: Mike Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	linux-clk@vger.kernel.org
Cc: Yassine Oudjana <y.oudjana@protonmail.com>,
	Tony Lindgren <tony@atomide.com>,
	Alexander Stein <alexander.stein@ew.tq-group.com>,
	Jerome Brunet <jbrunet@baylibre.com>,
	Naresh Kamboju <naresh.kamboju@linaro.org>,
	Neil Armstrong <narmstrong@baylibre.com>,
	Marek Szyprowski <m.szyprowski@samsung.com>,
	Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
	Maxime Ripard <maxime@cerno.tech>
Subject: [PATCH v6 18/28] clk: Move clk_core_init_rate_req() from clk_core_round_rate_nolock() to its caller
Date: Mon, 11 Jul 2022 17:24:14 +0200	[thread overview]
Message-ID: <20220711152424.701311-19-maxime@cerno.tech> (raw)
In-Reply-To: <20220711152424.701311-1-maxime@cerno.tech>

The clk_rate_request structure is used internally as an argument for
the clk_core_determine_round_nolock() and clk_core_round_rate_nolock().

In both cases, the clk_core_init_rate_req() function is used to
initialize the clk_rate_request structure.

However, the expectation on who gets to call that function is
inconsistent between those two functions. Indeed,
clk_core_determine_round_nolock() will assume the structure is properly
initialized and will just use it.

On the other hand, clk_core_round_rate_nolock() will call
clk_core_init_rate_req() itself, expecting the caller to have filled
only a minimal set of parameters (rate, min_rate and max_rate).

If we ignore the calling convention inconsistency, this leads to a
second inconsistency for drivers:

   * If they get called by the framework through
     clk_core_round_rate_nolock(), the rate, min_rate and max_rate
     fields will be filled by the caller, and the best_parent_rate and
     best_parent_hw fields will get filled by clk_core_init_rate_req().

   * If they get called by a driver through __clk_determine_rate (and
     thus clk_core_round_rate_nolock), only best_parent_rate and
     best_parent_hw are being explicitly set by the framework. Even
     though we can reasonably expect rate to be set, only one of the 6
     in-tree users explicitly set min_rate and max_rate.

   * If they get called by the framework through
     clk_core_determine_round_nolock(), then we have two callpaths.
     Either it will be called by clk_core_round_rate_nolock() itself, or
     it will be called by clk_calc_new_rates(), which will properly
     initialize rate, min_rate, max_rate itself, and best_parent_rate
     and best_parent_hw through clk_core_init_rate_req().

Even though the first and third case seems equivalent, they aren't when
the clock has CLK_SET_RATE_PARENT. Indeed, in such a case
clk_core_round_rate_nolock() will call itself on the current parent
clock with the same clk_rate_request structure.

The clk_core_init_rate_req() function will then be called on the parent
clock, with the child clk_rate_request pointer and will fill the
best_parent_rate and best_parent_hw fields with the parent context.

When the whole recursion stops and the call returns, the initial caller
will end up with a clk_rate_request structure with some informations of
the child clock (rate, min_rate, max_rate) and some others of the last
clock up the tree whose child had CLK_SET_RATE_PARENT (best_parent_hw,
best_parent_rate).

In the most common case, best_parent_rate is going to be equal on all
the parent clocks so it's not a big deal. However, best_parent_hw is
going to point to a clock that never has been a valid parent for that
clock which is definitely confusing.

In order to fix the calling inconsistency, let's move the
clk_core_init_rate_req() calls to the callers, which will also help a
bit with the clk_core_round_rate_nolock() recursion.

Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> # imx8mp
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> # exynos4210, meson g12b
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/clk/clk.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 6670e61edb31..7a071c567800 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1415,8 +1415,6 @@ static int clk_core_round_rate_nolock(struct clk_core *core,
 		return 0;
 	}
 
-	clk_core_init_rate_req(core, req, req->rate);
-
 	if (clk_core_can_round(core))
 		return clk_core_determine_round_nolock(core, req);
 	else if (core->flags & CLK_SET_RATE_PARENT)
@@ -1464,8 +1462,8 @@ unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate)
 	int ret;
 	struct clk_rate_request req;
 
+	clk_core_init_rate_req(hw->core, &req, rate);
 	clk_core_get_boundaries(hw->core, &req.min_rate, &req.max_rate);
-	req.rate = rate;
 
 	ret = clk_core_round_rate_nolock(hw->core, &req);
 	if (ret)
@@ -1497,8 +1495,8 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 	if (clk->exclusive_count)
 		clk_core_rate_unprotect(clk->core);
 
+	clk_core_init_rate_req(clk->core, &req, rate);
 	clk_core_get_boundaries(clk->core, &req.min_rate, &req.max_rate);
-	req.rate = rate;
 
 	ret = clk_core_round_rate_nolock(clk->core, &req);
 
@@ -2206,8 +2204,8 @@ static unsigned long clk_core_req_round_rate_nolock(struct clk_core *core,
 	if (cnt < 0)
 		return cnt;
 
+	clk_core_init_rate_req(core, &req, req_rate);
 	clk_core_get_boundaries(core, &req.min_rate, &req.max_rate);
-	req.rate = req_rate;
 
 	ret = clk_core_round_rate_nolock(core, &req);
 
-- 
2.36.1


  parent reply	other threads:[~2022-07-11 15:25 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-11 15:23 [PATCH v6 00/28] clk: More clock rate fixes and tests Maxime Ripard
2022-07-11 15:23 ` [PATCH v6 01/28] clk: bcm: rpi: Create helper to retrieve private data Maxime Ripard
2022-07-11 15:23 ` [PATCH v6 02/28] clk: bcm: rpi: Add a function to retrieve the maximum Maxime Ripard
2022-07-14 17:13   ` kernel test robot
2022-07-16  4:54   ` kernel test robot
2022-07-11 15:23 ` [PATCH v6 03/28] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 04/28] clk: test: Switch to clk_hw_get_clk Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 05/28] clk: Drop the rate range on clk_put() Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 06/28] clk: Skip clamping when rounding if there's no boundaries Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 07/28] clk: Mention that .recalc_rate can return 0 on error Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 08/28] clk: Clarify clk_get_rate() expectations Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 09/28] clk: tests: Add test suites description Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 10/28] clk: tests: Add reference to the orphan mux bug report Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 11/28] clk: tests: Add tests for uncached clock Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 12/28] clk: tests: Add tests for single parent mux Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 13/28] clk: tests: Add tests for mux with multiple parents Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 14/28] clk: tests: Add some tests for orphan " Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 15/28] clk: Take into account uncached clocks in clk_set_rate_range() Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 16/28] clk: Set req_rate on reparenting Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 17/28] clk: Change clk_core_init_rate_req prototype Maxime Ripard
2022-07-11 15:24 ` Maxime Ripard [this message]
2022-07-11 15:24 ` [PATCH v6 19/28] clk: Introduce clk_hw_init_rate_request() Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 20/28] clk: Add our request boundaries in clk_core_init_rate_req Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 21/28] clk: Switch from __clk_determine_rate to clk_core_round_rate_nolock Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 22/28] clk: Introduce clk_core_has_parent() Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 23/28] clk: Constify clk_has_parent() Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 24/28] clk: Stop forwarding clk_rate_requests to the parent Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 25/28] clk: Zero the clk_rate_request structure Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 26/28] clk: Introduce the clk_hw_get_rate_range function Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 27/28] clk: qcom: clk-rcg2: Take clock boundaries into consideration for gfx3d Maxime Ripard
2022-07-11 15:24 ` [PATCH v6 28/28] clk: tests: Add missing test case for ranges Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220711152424.701311-19-maxime@cerno.tech \
    --to=maxime@cerno.tech \
    --cc=alexander.stein@ew.tq-group.com \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=jbrunet@baylibre.com \
    --cc=linux-clk@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=mturquette@baylibre.com \
    --cc=naresh.kamboju@linaro.org \
    --cc=narmstrong@baylibre.com \
    --cc=sboyd@kernel.org \
    --cc=tony@atomide.com \
    --cc=y.oudjana@protonmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.