[PATCH 01/27] clk: sophgo: cv18xx-ip: convert from divider_round_rate() to divider_determine_rate()

Brian Masney <[email protected]>
Newsgroups dev.linux.lists.sophgo,org.kernel.vger.linux-clk,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
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 <[email protected]>

---
To: Chen Wang <[email protected]>
To: Inochi Amaoto <[email protected]>
Cc: [email protected]
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.