lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260108-clk-divider-round-rate-v1-1-535a3ed73bf3@redhat.com>
Date: Thu, 08 Jan 2026 16:16:19 -0500
From: Brian Masney <bmasney@...hat.com>
To: Michael Turquette <mturquette@...libre.com>, 
 Stephen Boyd <sboyd@...nel.org>
Cc: linux-clk@...r.kernel.org, linux-kernel@...r.kernel.org, 
 Brian Masney <bmasney@...hat.com>, Chen Wang <unicorn_wang@...look.com>, 
 Inochi Amaoto <inochiama@...il.com>, sophgo@...ts.linux.dev
Subject: [PATCH 01/27] clk: sophgo: cv18xx-ip: convert from
 divider_round_rate() to divider_determine_rate()

The divider_round_rate() function is now deprecated, so let's migrate
to divider_determine_rate() instead so that this deprecated API can be
removed. Also go ahead and convert all of the driver from round rate
type to determine rate that accepts a 'struct clk_rate_request' to
simplify the overall driver code.

Signed-off-by: Brian Masney <bmasney@...hat.com>

---
To: Chen Wang <unicorn_wang@...look.com>
To: Inochi Amaoto <inochiama@...il.com>
Cc: sophgo@...ts.linux.dev
---
 drivers/clk/sophgo/clk-cv18xx-ip.c | 154 ++++++++++++++++++++-----------------
 1 file changed, 85 insertions(+), 69 deletions(-)

diff --git a/drivers/clk/sophgo/clk-cv18xx-ip.c b/drivers/clk/sophgo/clk-cv18xx-ip.c
index c2b58faf0938b7d537dc3a81aef59c549b9c9c79..e936e315400393662a24e0d0189f7f74e01fa586 100644
--- a/drivers/clk/sophgo/clk-cv18xx-ip.c
+++ b/drivers/clk/sophgo/clk-cv18xx-ip.c
@@ -152,28 +152,27 @@ static u32 div_helper_get_clockdiv(struct cv1800_clk_common *common,
 	return clockdiv;
 }
 
-static u32 div_helper_round_rate(struct cv1800_clk_regfield *div,
-				 struct clk_hw *hw, struct clk_hw *parent,
-				 unsigned long rate, unsigned long *prate)
+static int div_helper_determine_rate(struct cv1800_clk_regfield *div,
+				     struct clk_hw *hw,
+				     struct clk_rate_request *req)
 {
 	if (div->width == 0) {
 		if (div->initval <= 0)
-			return DIV_ROUND_UP_ULL(*prate, 1);
+			req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, 1);
 		else
-			return DIV_ROUND_UP_ULL(*prate, div->initval);
+			req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div->initval);
+
+		return 0;
 	}
 
-	return divider_round_rate_parent(hw, parent, rate, prate, NULL,
-					 div->width, div->flags);
+	return divider_determine_rate(hw, req, NULL, div->width, div->flags);
 }
 
-static long div_round_rate(struct clk_hw *parent, unsigned long *parent_rate,
-			   unsigned long rate, int id, void *data)
+static int do_div_determine_rate(struct clk_rate_request *req, int id, void *data)
 {
 	struct cv1800_clk_div *div = data;
 
-	return div_helper_round_rate(&div->div, &div->common.hw, parent,
-				     rate, parent_rate);
+	return div_helper_determine_rate(&div->div, &div->common.hw, req);
 }
 
 static bool div_is_better_rate(struct cv1800_clk_common *common,
@@ -188,53 +187,60 @@ static bool div_is_better_rate(struct cv1800_clk_common *common,
 
 static int mux_helper_determine_rate(struct cv1800_clk_common *common,
 				     struct clk_rate_request *req,
-				     long (*round)(struct clk_hw *,
-						   unsigned long *,
-						   unsigned long,
-						   int,
-						   void *),
+				     int (*round)(struct clk_rate_request *,
+						  int,
+						  void *),
 				     void *data)
 {
 	unsigned long best_parent_rate = 0, best_rate = 0;
 	struct clk_hw *best_parent, *hw = &common->hw;
 	unsigned int i;
+	int ret;
 
 	if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
-		unsigned long adj_parent_rate;
+		struct clk_rate_request tmp_req = *req;
 
 		best_parent = clk_hw_get_parent(hw);
-		best_parent_rate = clk_hw_get_rate(best_parent);
+		tmp_req.best_parent_hw = best_parent;
+		tmp_req.best_parent_rate = clk_hw_get_rate(best_parent);
 
-		best_rate = round(best_parent, &adj_parent_rate,
-				  req->rate, -1, data);
+		ret = round(&tmp_req, -1, data);
+		if (ret)
+			return ret;
+
+		best_parent_rate = tmp_req.best_parent_rate;
+		best_rate = tmp_req.rate;
 
 		goto find;
 	}
 
 	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
-		unsigned long tmp_rate, parent_rate;
+		struct clk_rate_request tmp_req = *req;
 		struct clk_hw *parent;
 
 		parent = clk_hw_get_parent_by_index(hw, i);
 		if (!parent)
 			continue;
 
-		parent_rate = clk_hw_get_rate(parent);
+		tmp_req.best_parent_hw = parent;
+		tmp_req.best_parent_rate = clk_hw_get_rate(parent);
 
-		tmp_rate = round(parent, &parent_rate, req->rate, i, data);
+		ret = round(&tmp_req, i, data);
+		if (ret)
+			continue;
 
-		if (tmp_rate == req->rate) {
+		if (tmp_req.rate == req->rate) {
 			best_parent = parent;
-			best_parent_rate = parent_rate;
-			best_rate = tmp_rate;
+			best_parent_rate = tmp_req.best_parent_rate;
+			best_rate = tmp_req.rate;
 			goto find;
 		}
 
 		if (div_is_better_rate(common, req->rate,
-				       tmp_rate, best_rate)) {
+				       tmp_req.rate, best_rate)) {
 			best_parent = parent;
-			best_parent_rate = parent_rate;
-			best_rate = tmp_rate;
+			best_parent_rate = tmp_req.best_parent_rate;
+			best_rate = tmp_req.rate;
 		}
 	}
 
@@ -254,7 +260,7 @@ static int div_determine_rate(struct clk_hw *hw,
 	struct cv1800_clk_div *div = hw_to_cv1800_clk_div(hw);
 
 	return mux_helper_determine_rate(&div->common, req,
-					 div_round_rate, div);
+					 do_div_determine_rate, div);
 }
 
 static unsigned long div_recalc_rate(struct clk_hw *hw,
@@ -301,24 +307,28 @@ hw_to_cv1800_clk_bypass_div(struct clk_hw *hw)
 	return container_of(div, struct cv1800_clk_bypass_div, div);
 }
 
-static long bypass_div_round_rate(struct clk_hw *parent,
-				  unsigned long *parent_rate,
-				  unsigned long rate, int id, void *data)
+static int do_bypass_div_determine_rate(struct clk_rate_request *req, int id,
+					void *data)
 {
 	struct cv1800_clk_bypass_div *div = data;
 
 	if (id == -1) {
-		if (cv1800_clk_checkbit(&div->div.common, &div->bypass))
-			return *parent_rate;
-		else
-			return div_round_rate(parent, parent_rate, rate,
-					      -1, &div->div);
+		if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) {
+			req->rate = req->best_parent_rate;
+
+			return 0;
+		}
+
+		return do_div_determine_rate(req, -1, &div->div);
 	}
 
-	if (id == 0)
-		return *parent_rate;
+	if (id == 0) {
+		req->rate = req->best_parent_rate;
+
+		return 0;
+	}
 
-	return div_round_rate(parent, parent_rate, rate, id - 1, &div->div);
+	return do_div_determine_rate(req, id - 1, &div->div);
 }
 
 static int bypass_div_determine_rate(struct clk_hw *hw,
@@ -327,7 +337,7 @@ static int bypass_div_determine_rate(struct clk_hw *hw,
 	struct cv1800_clk_bypass_div *div = hw_to_cv1800_clk_bypass_div(hw);
 
 	return mux_helper_determine_rate(&div->div.common, req,
-					 bypass_div_round_rate, div);
+					 do_bypass_div_determine_rate, div);
 }
 
 static unsigned long bypass_div_recalc_rate(struct clk_hw *hw,
@@ -414,13 +424,11 @@ static int mux_is_enabled(struct clk_hw *hw)
 	return cv1800_clk_checkbit(&mux->common, &mux->gate);
 }
 
-static long mux_round_rate(struct clk_hw *parent, unsigned long *parent_rate,
-			   unsigned long rate, int id, void *data)
+static int do_mux_determine_rate(struct clk_rate_request *req, int id, void *data)
 {
 	struct cv1800_clk_mux *mux = data;
 
-	return div_helper_round_rate(&mux->div, &mux->common.hw, parent,
-				     rate, parent_rate);
+	return div_helper_determine_rate(&mux->div, &mux->common.hw, req);
 }
 
 static int mux_determine_rate(struct clk_hw *hw,
@@ -429,7 +437,7 @@ static int mux_determine_rate(struct clk_hw *hw,
 	struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw);
 
 	return mux_helper_determine_rate(&mux->common, req,
-					 mux_round_rate, mux);
+					 do_mux_determine_rate, mux);
 }
 
 static unsigned long mux_recalc_rate(struct clk_hw *hw,
@@ -512,24 +520,28 @@ hw_to_cv1800_clk_bypass_mux(struct clk_hw *hw)
 	return container_of(mux, struct cv1800_clk_bypass_mux, mux);
 }
 
-static long bypass_mux_round_rate(struct clk_hw *parent,
-				  unsigned long *parent_rate,
-				  unsigned long rate, int id, void *data)
+static int do_bypass_mux_determine_rate(struct clk_rate_request *req, int id,
+					void *data)
 {
 	struct cv1800_clk_bypass_mux *mux = data;
 
 	if (id == -1) {
-		if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass))
-			return *parent_rate;
-		else
-			return mux_round_rate(parent, parent_rate, rate,
-					      -1, &mux->mux);
+		if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) {
+			req->rate = req->best_parent_rate;
+
+			return 0;
+		}
+
+		return do_mux_determine_rate(req, -1, &mux->mux);
 	}
 
-	if (id == 0)
-		return *parent_rate;
+	if (id == 0) {
+		req->rate = req->best_parent_rate;
+
+		return 0;
+	}
 
-	return mux_round_rate(parent, parent_rate, rate, id - 1, &mux->mux);
+	return do_mux_determine_rate(req, id - 1, &mux->mux);
 }
 
 static int bypass_mux_determine_rate(struct clk_hw *hw,
@@ -538,7 +550,7 @@ static int bypass_mux_determine_rate(struct clk_hw *hw,
 	struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw);
 
 	return mux_helper_determine_rate(&mux->mux.common, req,
-					 bypass_mux_round_rate, mux);
+					 do_bypass_mux_determine_rate, mux);
 }
 
 static unsigned long bypass_mux_recalc_rate(struct clk_hw *hw,
@@ -639,27 +651,31 @@ static int mmux_is_enabled(struct clk_hw *hw)
 	return cv1800_clk_checkbit(&mmux->common, &mmux->gate);
 }
 
-static long mmux_round_rate(struct clk_hw *parent, unsigned long *parent_rate,
-			    unsigned long rate, int id, void *data)
+static int do_mmux_determine_rate(struct clk_rate_request *req, int id, void *data)
 {
 	struct cv1800_clk_mmux *mmux = data;
 	s8 div_id;
 
 	if (id == -1) {
-		if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass))
-			return *parent_rate;
+		if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) {
+			req->rate = req->best_parent_rate;
+
+			return 0;
+		}
 
 		id = mmux_get_parent_id(mmux);
 	}
 
 	div_id = mmux->parent2sel[id];
 
-	if (div_id < 0)
-		return *parent_rate;
+	if (div_id < 0) {
+		req->rate = req->best_parent_rate;
+
+		return 0;
+	}
 
-	return div_helper_round_rate(&mmux->div[div_id],
-				     &mmux->common.hw, parent,
-				     rate, parent_rate);
+	return div_helper_determine_rate(&mmux->div[div_id], &mmux->common.hw,
+					 req);
 }
 
 static int mmux_determine_rate(struct clk_hw *hw,
@@ -668,7 +684,7 @@ static int mmux_determine_rate(struct clk_hw *hw,
 	struct cv1800_clk_mmux *mmux = hw_to_cv1800_clk_mmux(hw);
 
 	return mux_helper_determine_rate(&mmux->common, req,
-					 mmux_round_rate, mmux);
+					 do_mmux_determine_rate, mmux);
 }
 
 static unsigned long mmux_recalc_rate(struct clk_hw *hw,

-- 
2.52.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ