Linux clock framework development
 help / color / mirror / Atom feed
* [PATCH 0/2] clk: renesas: rzv2h: Convert to clk_hw provider API
@ 2026-09-02 10:49 Ovidiu Panait
  2026-09-02 10:49 ` [PATCH 1/2] clk: renesas: rzv2h: Drop duplicated parent lookup in fixed_mod_status_clk_register() Ovidiu Panait
  2026-09-02 10:49 ` [PATCH 2/2] clk: renesas: rzv2h: Convert to clk_hw based provider API Ovidiu Panait
  0 siblings, 2 replies; 6+ messages in thread
From: Ovidiu Panait @ 2026-09-02 10:49 UTC (permalink / raw)
  To: geert+renesas, sboyd, bmasney+clk, jbrunet+clk
  Cc: linux-renesas-soc, linux-clk, linux-kernel, Ovidiu Panait

Hi,

The rzv2h-cpg driver stores its clocks as struct clk and uses the consumer
clk API internally, even though it is a clock provider.

This series converts it to use clk_hw, like rzg2l-cpg.c already does.

No functional change intended.

Thanks,
Ovidiu

John Madieu (2):
  clk: renesas: rzv2h: Drop duplicated parent lookup in
    fixed_mod_status_clk_register()
  clk: renesas: rzv2h: Convert to clk_hw based provider API

 drivers/clk/renesas/rzv2h-cpg.c | 154 ++++++++++++++------------------
 1 file changed, 68 insertions(+), 86 deletions(-)

-- 
2.34.1


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

* [PATCH 1/2] clk: renesas: rzv2h: Drop duplicated parent lookup in fixed_mod_status_clk_register()
  2026-09-02 10:49 [PATCH 0/2] clk: renesas: rzv2h: Convert to clk_hw provider API Ovidiu Panait
@ 2026-09-02 10:49 ` Ovidiu Panait
  2026-09-03 13:07   ` Geert Uytterhoeven
  2026-09-02 10:49 ` [PATCH 2/2] clk: renesas: rzv2h: Convert to clk_hw based provider API Ovidiu Panait
  1 sibling, 1 reply; 6+ messages in thread
From: Ovidiu Panait @ 2026-09-02 10:49 UTC (permalink / raw)
  To: geert+renesas, sboyd, bmasney+clk, jbrunet+clk
  Cc: linux-renesas-soc, linux-clk, linux-kernel, John Madieu,
	Ovidiu Panait

From: John Madieu <john.madieu.xa@bp.renesas.com>

rzv2h_cpg_fixed_mod_status_clk_register() looks up priv->clks[core->parent]
twice, with an IS_ERR() check after each lookup. The second lookup is a
leftover from an earlier refactor: the value cannot have changed between
the two reads, so the second IS_ERR() check is dead code.

Drop the duplicated lookup and check.

No functional change intended.

Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
---
 drivers/clk/renesas/rzv2h-cpg.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index 7003d59ac34b..86f6f2f700a6 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c
@@ -923,9 +923,6 @@ rzv2h_cpg_fixed_mod_status_clk_register(const struct cpg_core_clk *core,
 		return ERR_CAST(parent);
 
 	parent_name = __clk_get_name(parent);
-	parent = priv->clks[core->parent];
-	if (IS_ERR(parent))
-		return ERR_CAST(parent);
 
 	clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
 	if (!clk_hw_data)
-- 
2.34.1


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

* [PATCH 2/2] clk: renesas: rzv2h: Convert to clk_hw based provider API
  2026-09-02 10:49 [PATCH 0/2] clk: renesas: rzv2h: Convert to clk_hw provider API Ovidiu Panait
  2026-09-02 10:49 ` [PATCH 1/2] clk: renesas: rzv2h: Drop duplicated parent lookup in fixed_mod_status_clk_register() Ovidiu Panait
@ 2026-09-02 10:49 ` Ovidiu Panait
  2026-09-02 11:04   ` sashiko-bot
  2026-09-03 13:39   ` Geert Uytterhoeven
  1 sibling, 2 replies; 6+ messages in thread
From: Ovidiu Panait @ 2026-09-02 10:49 UTC (permalink / raw)
  To: geert+renesas, sboyd, bmasney+clk, jbrunet+clk
  Cc: linux-renesas-soc, linux-clk, linux-kernel, John Madieu,
	Ovidiu Panait

From: John Madieu <john.madieu.xa@bp.renesas.com>

The driver mixes the clk consumer API with the clk_hw provider API for
its internal clock storage and OF lookup callback. Convert it to use
clk_hw consistently.

No functional change intended.

Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
---
 drivers/clk/renesas/rzv2h-cpg.c | 151 ++++++++++++++------------------
 1 file changed, 68 insertions(+), 83 deletions(-)

diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index 86f6f2f700a6..9b0d691b1f5d 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c
@@ -99,7 +99,7 @@ struct rzv2h_pll_dsi_info {
  * @dev: CPG device
  * @base: CPG register block base address
  * @rmw_lock: protects register accesses
- * @clks: Array containing all Core and Module Clocks
+ * @clks: Array containing all Core and Module clk_hw entries
  * @num_core_clks: Number of Core Clocks in clks[]
  * @num_mod_clks: Number of Module Clocks in clks[]
  * @resets: Array of resets
@@ -115,7 +115,7 @@ struct rzv2h_cpg_priv {
 	void __iomem *base;
 	spinlock_t rmw_lock;
 
-	struct clk **clks;
+	struct clk_hw **clks;
 	unsigned int num_core_clks;
 	unsigned int num_mod_clks;
 	struct rzv2h_reset *resets;
@@ -332,14 +332,14 @@ static const struct clk_ops rzv2h_cpg_plldsi_div_ops = {
 	.set_rate = rzv2h_cpg_plldsi_div_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core,
 				  struct rzv2h_cpg_priv *priv)
 {
 	struct rzv2h_plldsi_div_clk *clk_hw_data;
-	struct clk **clks = priv->clks;
+	struct clk_hw **clks = priv->clks;
 	struct clk_init_data init = {};
-	const struct clk *parent;
+	const struct clk_hw *parent;
 	const char *parent_name;
 	struct clk_hw *clk_hw;
 	int ret;
@@ -356,7 +356,7 @@ rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core,
 	clk_hw_data->ddiv = core->cfg.ddiv;
 	clk_hw_data->dtable = core->dtable;
 
-	parent_name = __clk_get_name(parent);
+	parent_name = clk_hw_get_name(parent);
 	init.name = core->name;
 	init.ops = &rzv2h_cpg_plldsi_div_ops;
 	init.flags = core->flag;
@@ -370,7 +370,7 @@ rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core,
 	if (ret)
 		return ERR_PTR(ret);
 
-	return clk_hw->clk;
+	return clk_hw;
 }
 
 static int rzv2h_cpg_plldsi_determine_rate(struct clk_hw *hw,
@@ -577,7 +577,7 @@ static const struct clk_ops rzv2h_cpg_plldsi_smux_ops = {
 	.set_duty_cycle = rzv2h_cpg_plldsi_smux_set_duty_cycle,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 rzv2h_cpg_plldsi_smux_clk_register(const struct cpg_core_clk *core,
 				   struct rzv2h_cpg_priv *priv)
 {
@@ -620,7 +620,7 @@ rzv2h_cpg_plldsi_smux_clk_register(const struct cpg_core_clk *core,
 	if (ret)
 		return ERR_PTR(ret);
 
-	return clk_hw->clk;
+	return clk_hw;
 }
 
 static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw)
@@ -705,14 +705,14 @@ static const struct clk_ops rzv2h_cpg_pll_ops = {
 	.recalc_rate = rzv2h_cpg_pll_clk_recalc_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core,
 			   struct rzv2h_cpg_priv *priv,
 			   const struct clk_ops *ops)
 {
 	struct device *dev = priv->dev;
 	struct clk_init_data init = {};
-	const struct clk *parent;
+	const struct clk_hw *parent;
 	const char *parent_name;
 	struct pll_clk *pll_clk;
 	int ret;
@@ -729,7 +729,7 @@ rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core,
 		priv->pll_dsi_info[core->cfg.pll.instance].pll_dsi_limits =
 			core->cfg.pll.limits;
 
-	parent_name = __clk_get_name(parent);
+	parent_name = clk_hw_get_name(parent);
 	init.name = core->name;
 	init.ops = ops;
 	init.flags = 0;
@@ -744,7 +744,7 @@ rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core,
 	if (ret)
 		return ERR_PTR(ret);
 
-	return pll_clk->hw.clk;
+	return &pll_clk->hw;
 }
 
 static unsigned long rzv2h_ddiv_recalc_rate(struct clk_hw *hw,
@@ -820,7 +820,7 @@ static const struct clk_ops rzv2h_ddiv_clk_divider_ops = {
 	.set_rate = rzv2h_ddiv_set_rate,
 };
 
-static struct clk * __init
+static struct clk_hw * __init
 rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core,
 			    struct rzv2h_cpg_priv *priv)
 {
@@ -829,7 +829,7 @@ rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core,
 	struct device *dev = priv->dev;
 	u8 shift = cfg_ddiv.shift;
 	u8 width = cfg_ddiv.width;
-	const struct clk *parent;
+	const struct clk_hw *parent;
 	const char *parent_name;
 	struct clk_divider *div;
 	struct ddiv_clk *ddiv;
@@ -839,7 +839,7 @@ rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core,
 	if (IS_ERR(parent))
 		return ERR_CAST(parent);
 
-	parent_name = __clk_get_name(parent);
+	parent_name = clk_hw_get_name(parent);
 
 	if ((shift + width) > 16)
 		return ERR_PTR(-EINVAL);
@@ -872,15 +872,15 @@ rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core,
 	if (ret)
 		return ERR_PTR(ret);
 
-	return div->hw.clk;
+	return &div->hw;
 }
 
-static struct clk * __init
+static struct clk_hw * __init
 rzv2h_cpg_mux_clk_register(const struct cpg_core_clk *core,
 			   struct rzv2h_cpg_priv *priv)
 {
 	struct smuxed mux = core->cfg.smux;
-	const struct clk_hw *clk_hw;
+	struct clk_hw *clk_hw;
 
 	clk_hw = devm_clk_hw_register_mux(priv->dev, core->name,
 					  core->parent_names, core->num_parents,
@@ -890,7 +890,7 @@ rzv2h_cpg_mux_clk_register(const struct cpg_core_clk *core,
 	if (IS_ERR(clk_hw))
 		return ERR_CAST(clk_hw);
 
-	return clk_hw->clk;
+	return clk_hw;
 }
 
 static int
@@ -906,14 +906,14 @@ rzv2h_clk_ff_mod_status_is_enabled(struct clk_hw *hw)
 	return !!(val & bitmask);
 }
 
-static struct clk * __init
+static struct clk_hw * __init
 rzv2h_cpg_fixed_mod_status_clk_register(const struct cpg_core_clk *core,
 					struct rzv2h_cpg_priv *priv)
 {
 	struct rzv2h_ff_mod_status_clk *clk_hw_data;
 	struct clk_init_data init = { };
 	struct clk_fixed_factor *fix;
-	const struct clk *parent;
+	const struct clk_hw *parent;
 	const char *parent_name;
 	int ret;
 
@@ -922,7 +922,7 @@ rzv2h_cpg_fixed_mod_status_clk_register(const struct cpg_core_clk *core,
 	if (IS_ERR(parent))
 		return ERR_CAST(parent);
 
-	parent_name = __clk_get_name(parent);
+	parent_name = clk_hw_get_name(parent);
 
 	clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
 	if (!clk_hw_data)
@@ -946,18 +946,18 @@ rzv2h_cpg_fixed_mod_status_clk_register(const struct cpg_core_clk *core,
 	if (ret)
 		return ERR_PTR(ret);
 
-	return clk_hw_data->fix.hw.clk;
+	return &clk_hw_data->fix.hw;
 }
 
-static struct clk
+static struct clk_hw
 *rzv2h_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,
 			       void *data)
 {
 	unsigned int clkidx = clkspec->args[1];
 	struct rzv2h_cpg_priv *priv = data;
 	struct device *dev = priv->dev;
+	struct clk_hw *clk_hw;
 	const char *type;
-	struct clk *clk;
 
 	switch (clkspec->args[0]) {
 	case CPG_CORE:
@@ -966,7 +966,7 @@ static struct clk
 			dev_err(dev, "Invalid %s clock index %u\n", type, clkidx);
 			return ERR_PTR(-EINVAL);
 		}
-		clk = priv->clks[clkidx];
+		clk_hw = priv->clks[clkidx];
 		break;
 
 	case CPG_MOD:
@@ -975,7 +975,7 @@ static struct clk
 			dev_err(dev, "Invalid %s clock index %u\n", type, clkidx);
 			return ERR_PTR(-EINVAL);
 		}
-		clk = priv->clks[priv->num_core_clks + clkidx];
+		clk_hw = priv->clks[priv->num_core_clks + clkidx];
 		break;
 
 	default:
@@ -983,25 +983,25 @@ static struct clk
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (IS_ERR(clk))
+	if (IS_ERR(clk_hw))
 		dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx,
-			PTR_ERR(clk));
+			PTR_ERR(clk_hw));
 	else
-		dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
-			clkspec->args[0], clkspec->args[1], clk,
-			clk_get_rate(clk));
-	return clk;
+		dev_dbg(dev, "clock (%u, %u) is %s at %lu Hz\n",
+			clkspec->args[0], clkspec->args[1],
+			clk_hw_get_name(clk_hw), clk_hw_get_rate(clk_hw));
+	return clk_hw;
 }
 
 static void __init
 rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core,
 			    struct rzv2h_cpg_priv *priv)
 {
-	struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent;
+	struct clk_hw *clk_hw = ERR_PTR(-EOPNOTSUPP), *parent;
 	unsigned int id = core->id, div = core->div;
 	struct device *dev = priv->dev;
 	const char *parent_name;
-	struct clk_hw *clk_hw;
+	struct clk *clk;
 
 	WARN_DEBUG(id >= priv->num_core_clks);
 	WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
@@ -1009,70 +1009,72 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core,
 	switch (core->type) {
 	case CLK_TYPE_IN:
 		clk = of_clk_get_by_name(priv->dev->of_node, core->name);
+		if (IS_ERR(clk)) {
+			clk_hw = ERR_CAST(clk);
+			goto fail;
+		}
+		clk_hw = __clk_get_hw(clk);
 		break;
 	case CLK_TYPE_FF:
 		WARN_DEBUG(core->parent >= priv->num_core_clks);
 		parent = priv->clks[core->parent];
 		if (IS_ERR(parent)) {
-			clk = parent;
+			clk_hw = parent;
 			goto fail;
 		}
 
-		parent_name = __clk_get_name(parent);
+		parent_name = clk_hw_get_name(parent);
 		clk_hw = devm_clk_hw_register_fixed_factor(dev, core->name,
 							   parent_name, CLK_SET_RATE_PARENT,
 							   core->mult, div);
-		if (IS_ERR(clk_hw))
-			clk = ERR_CAST(clk_hw);
-		else
-			clk = clk_hw->clk;
 		break;
 	case CLK_TYPE_FF_MOD_STATUS:
 		if (!priv->ff_mod_status_ops) {
 			priv->ff_mod_status_ops =
 				devm_kzalloc(dev, sizeof(*priv->ff_mod_status_ops), GFP_KERNEL);
 			if (!priv->ff_mod_status_ops) {
-				clk = ERR_PTR(-ENOMEM);
+				clk_hw = ERR_PTR(-ENOMEM);
 				goto fail;
 			}
 			memcpy(priv->ff_mod_status_ops, &clk_fixed_factor_ops,
 			       sizeof(const struct clk_ops));
 			priv->ff_mod_status_ops->is_enabled = rzv2h_clk_ff_mod_status_is_enabled;
 		}
-		clk = rzv2h_cpg_fixed_mod_status_clk_register(core, priv);
+		clk_hw = rzv2h_cpg_fixed_mod_status_clk_register(core, priv);
 		break;
 	case CLK_TYPE_PLL:
-		clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_pll_ops);
+		clk_hw = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_pll_ops);
 		break;
 	case CLK_TYPE_DDIV:
-		clk = rzv2h_cpg_ddiv_clk_register(core, priv);
+		clk_hw = rzv2h_cpg_ddiv_clk_register(core, priv);
 		break;
 	case CLK_TYPE_SMUX:
-		clk = rzv2h_cpg_mux_clk_register(core, priv);
+		clk_hw = rzv2h_cpg_mux_clk_register(core, priv);
 		break;
 	case CLK_TYPE_PLLDSI:
-		clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_plldsi_ops);
+		clk_hw = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_plldsi_ops);
 		break;
 	case CLK_TYPE_PLLDSI_DIV:
-		clk = rzv2h_cpg_plldsi_div_clk_register(core, priv);
+		clk_hw = rzv2h_cpg_plldsi_div_clk_register(core, priv);
 		break;
 	case CLK_TYPE_PLLDSI_SMUX:
-		clk = rzv2h_cpg_plldsi_smux_clk_register(core, priv);
+		clk_hw = rzv2h_cpg_plldsi_smux_clk_register(core, priv);
 		break;
 	default:
 		goto fail;
 	}
 
-	if (IS_ERR(clk))
+	if (IS_ERR(clk_hw))
 		goto fail;
 
-	dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
-	priv->clks[id] = clk;
+	dev_dbg(dev, "Core clock %s at %lu Hz\n",
+		clk_hw_get_name(clk_hw), clk_hw_get_rate(clk_hw));
+	priv->clks[id] = clk_hw;
 	return;
 
 fail:
 	dev_err(dev, "Failed to register core clock %s: %ld\n",
-		core->name, PTR_ERR(clk));
+		core->name, PTR_ERR(clk_hw));
 }
 
 static void rzv2h_mod_clock_mstop_enable(struct rzv2h_cpg_priv *priv,
@@ -1119,15 +1121,10 @@ static void rzv2h_mod_clock_mstop_disable(struct rzv2h_cpg_priv *priv,
 
 static int rzv2h_parent_clk_mux_to_index(struct clk_hw *hw)
 {
-	struct clk_hw *parent_hw;
-	struct clk *parent_clk;
+	struct clk_hw *parent_hw = clk_hw_get_parent(hw);
 	struct clk_mux *mux;
 	u32 val;
 
-	/* This will always succeed, so no need to check for IS_ERR() */
-	parent_clk = clk_get_parent(hw->clk);
-
-	parent_hw = __clk_get_hw(parent_clk);
 	mux = to_clk_mux(parent_hw);
 
 	val = readl(mux->reg) >> mux->shift;
@@ -1227,8 +1224,8 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
 	struct mod_clock *clock = NULL;
 	struct device *dev = priv->dev;
 	struct clk_init_data init = {};
-	struct clk *parent, *clk;
 	const char *parent_name;
+	struct clk_hw *parent;
 	unsigned int id;
 	int ret;
 
@@ -1239,13 +1236,13 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
 
 	parent = priv->clks[mod->parent];
 	if (IS_ERR(parent)) {
-		clk = parent;
+		ret = PTR_ERR(parent);
 		goto fail;
 	}
 
 	clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL);
 	if (!clock) {
-		clk = ERR_PTR(-ENOMEM);
+		ret = -ENOMEM;
 		goto fail;
 	}
 
@@ -1255,7 +1252,7 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
 	if (mod->critical)
 		init.flags |= CLK_IS_CRITICAL;
 
-	parent_name = __clk_get_name(parent);
+	parent_name = clk_hw_get_name(parent);
 	init.parent_names = &parent_name;
 	init.num_parents = 1;
 
@@ -1270,12 +1267,10 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
 	clock->mstop_data = mod->mstop_data;
 
 	ret = devm_clk_hw_register(dev, &clock->hw);
-	if (ret) {
-		clk = ERR_PTR(ret);
+	if (ret)
 		goto fail;
-	}
 
-	priv->clks[id] = clock->hw.clk;
+	priv->clks[id] = &clock->hw;
 
 	/*
 	 * Ensure the module clocks and MSTOP bits are synchronized when they are
@@ -1314,8 +1309,8 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
 	return;
 
 fail:
-	dev_err(dev, "Failed to register module clock %s: %ld\n",
-		mod->name, PTR_ERR(clk));
+	dev_err(dev, "Failed to register module clock %s: %d\n",
+		mod->name, ret);
 }
 
 static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev,
@@ -1448,7 +1443,7 @@ static bool rzv2h_cpg_is_pm_clk(struct rzv2h_cpg_pd *pd,
 		if (priv->clks[priv->num_core_clks + id] == ERR_PTR(-ENOENT))
 			return false;
 
-		clock = to_mod_clock(__clk_get_hw(priv->clks[priv->num_core_clks + id]));
+		clock = to_mod_clock(priv->clks[priv->num_core_clks + id]);
 
 		return !clock->no_pm;
 	}
@@ -1547,19 +1542,13 @@ static int __init rzv2h_cpg_add_pm_domains(struct rzv2h_cpg_priv *priv)
 	return of_genpd_add_provider_simple(np, &pd->genpd);
 }
 
-static void rzv2h_cpg_del_clk_provider(void *data)
-{
-	of_clk_del_provider(data);
-}
-
 static int __init rzv2h_cpg_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
 	const struct rzv2h_cpg_info *info;
 	struct rzv2h_cpg_priv *priv;
 	unsigned int nclks, i;
-	struct clk **clks;
+	struct clk_hw **clks;
 	int error;
 
 	info = of_device_get_match_data(dev);
@@ -1610,11 +1599,7 @@ static int __init rzv2h_cpg_probe(struct platform_device *pdev)
 	for (i = 0; i < info->num_mod_clks; i++)
 		rzv2h_cpg_register_mod_clk(&info->mod_clks[i], priv);
 
-	error = of_clk_add_provider(np, rzv2h_cpg_clk_src_twocell_get, priv);
-	if (error)
-		return error;
-
-	error = devm_add_action_or_reset(dev, rzv2h_cpg_del_clk_provider, np);
+	error = devm_of_clk_add_hw_provider(dev, rzv2h_cpg_clk_src_twocell_get, priv);
 	if (error)
 		return error;
 
-- 
2.34.1


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

* Re: [PATCH 2/2] clk: renesas: rzv2h: Convert to clk_hw based provider API
  2026-09-02 10:49 ` [PATCH 2/2] clk: renesas: rzv2h: Convert to clk_hw based provider API Ovidiu Panait
@ 2026-09-02 11:04   ` sashiko-bot
  2026-09-03 13:39   ` Geert Uytterhoeven
  1 sibling, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-09-02 11:04 UTC (permalink / raw)
  To: Ovidiu Panait; +Cc: linux-clk, wsa+renesas

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing OF genpd provider cleanup on the probe error path leads to a Use-After-Free.
--

commit a63d8b10a46c55aa614df9d149b0a17736dc2cc5
Author: John Madieu <john.madieu.xa@bp.renesas.com>

clk: renesas: rzv2h: Convert to clk_hw based provider API

The driver mixes the clk consumer API with the clk_hw provider API for its
internal clock storage and OF lookup callback. Convert it to use clk_hw
consistently.

> diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
> index 86f6f2f700a65..9b0d691b1f5d0 100644
> --- a/drivers/clk/renesas/rzv2h-cpg.c
> +++ b/drivers/clk/renesas/rzv2h-cpg.c
[ ... ]
> @@ -1547,19 +1542,13 @@ static int __init rzv2h_cpg_add_pm_domains(struct rzv2h_cpg_priv *priv)
>  	return of_genpd_add_provider_simple(np, &pd->genpd);

[Severity: High]
This is a pre-existing issue, but does this missing OF genpd provider cleanup
on the probe error path lead to a Use-After-Free?

If a subsequent operation in rzv2h_cpg_probe() (such as
rzv2h_cpg_reset_controller_register()) fails, the devm framework automatically
frees the struct rzv2h_cpg_pd that was allocated with devm_kzalloc().

However, the cleanup action pm_genpd_remove() returns -EBUSY and aborts
because of_genpd_add_provider_simple() sets genpd->has_provider = true.
Because of_genpd_del_provider() is never called to unset this flag and
remove the provider, the domain remains registered in the global
of_genpd_providers list, gpd_list, and the device core.

When a consumer device subsequently probes and looks up its PM domain, or
when the PM domain core walks the lists, it could dereference the freed
pd->genpd memory.

>  }
>  
> -static void rzv2h_cpg_del_clk_provider(void *data)
> -{
> -	of_clk_del_provider(data);
> -}
> -

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902104939.25522-1-ovidiu.panait.rb@renesas.com?part=2

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

* Re: [PATCH 1/2] clk: renesas: rzv2h: Drop duplicated parent lookup in fixed_mod_status_clk_register()
  2026-09-02 10:49 ` [PATCH 1/2] clk: renesas: rzv2h: Drop duplicated parent lookup in fixed_mod_status_clk_register() Ovidiu Panait
@ 2026-09-03 13:07   ` Geert Uytterhoeven
  0 siblings, 0 replies; 6+ messages in thread
From: Geert Uytterhoeven @ 2026-09-03 13:07 UTC (permalink / raw)
  To: Ovidiu Panait
  Cc: sboyd, bmasney+clk, jbrunet+clk, linux-renesas-soc, linux-clk,
	linux-kernel, John Madieu

On Wed, 2 Sept 2026 at 12:50, Ovidiu Panait
<ovidiu.panait.rb@renesas.com> wrote:
> From: John Madieu <john.madieu.xa@bp.renesas.com>
>
> rzv2h_cpg_fixed_mod_status_clk_register() looks up priv->clks[core->parent]
> twice, with an IS_ERR() check after each lookup. The second lookup is a
> leftover from an earlier refactor: the value cannot have changed between
> the two reads, so the second IS_ERR() check is dead code.
>
> Drop the duplicated lookup and check.
>
> No functional change intended.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-clk for v7.4.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 2/2] clk: renesas: rzv2h: Convert to clk_hw based provider API
  2026-09-02 10:49 ` [PATCH 2/2] clk: renesas: rzv2h: Convert to clk_hw based provider API Ovidiu Panait
  2026-09-02 11:04   ` sashiko-bot
@ 2026-09-03 13:39   ` Geert Uytterhoeven
  1 sibling, 0 replies; 6+ messages in thread
From: Geert Uytterhoeven @ 2026-09-03 13:39 UTC (permalink / raw)
  To: Ovidiu Panait
  Cc: sboyd, bmasney+clk, jbrunet+clk, linux-renesas-soc, linux-clk,
	linux-kernel, John Madieu

Hi Ovidiu,

On Wed, 2 Sept 2026 at 12:50, Ovidiu Panait
<ovidiu.panait.rb@renesas.com> wrote:
> From: John Madieu <john.madieu.xa@bp.renesas.com>
>
> The driver mixes the clk consumer API with the clk_hw provider API for
> its internal clock storage and OF lookup callback. Convert it to use
> clk_hw consistently.
>
> No functional change intended.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>

Nice, thanks a lot for picking up John's legacy!

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-clk for v7.4.

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

end of thread, other threads:[~2026-09-03 13:39 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 10:49 [PATCH 0/2] clk: renesas: rzv2h: Convert to clk_hw provider API Ovidiu Panait
2026-09-02 10:49 ` [PATCH 1/2] clk: renesas: rzv2h: Drop duplicated parent lookup in fixed_mod_status_clk_register() Ovidiu Panait
2026-09-03 13:07   ` Geert Uytterhoeven
2026-09-02 10:49 ` [PATCH 2/2] clk: renesas: rzv2h: Convert to clk_hw based provider API Ovidiu Panait
2026-09-02 11:04   ` sashiko-bot
2026-09-03 13:39   ` Geert Uytterhoeven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox