Linux IIO development
 help / color / mirror / Atom feed
* [PATCH v2 0/3] counter: rz-mtu3-cnt: check clock and runtime PM errors
@ 2026-08-31  5:44 Li Youhong
  2026-08-31  5:44 ` [PATCH v2 1/3] counter: rz-mtu3-cnt: check clk_prepare_enable() and pm_runtime_set_active() Li Youhong
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Li Youhong @ 2026-08-31  5:44 UTC (permalink / raw)
  To: biju.das.jz, wbg; +Cc: linux-iio, linux-renesas-soc, Li Youhong

From: Li Youhong <liyouhong@kylinos.cn>

v1 checked only clk_prepare_enable() in probe/resume. Reviewers asked
to also handle pm_runtime_set_active() and all pm_runtime_get_sync()
call sites. Split into three patches, including a follow-up for a
pre-existing runtime PM usage leak on counter init failure.

Changes v1->v2
Link to v1: https://lore.kernel.org/all/20260828071123.179670-1-dayou5941@163.com/
- Also check pm_runtime_set_active() in probe
- Check pm_runtime_get_sync() everywhere
- New patch: put runtime PM ref if counter init fails after get


Li Youhong (3):
  counter: rz-mtu3-cnt: check clk_prepare_enable() and
    pm_runtime_set_active()
  counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values
  counter: rz-mtu3-cnt: put runtime PM ref if counter init fails

 drivers/counter/rz-mtu3-cnt.c | 119 +++++++++++++++++++++++++++-------
 1 file changed, 94 insertions(+), 25 deletions(-)

-- 
2.25.1


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

* [PATCH v2 1/3] counter: rz-mtu3-cnt: check clk_prepare_enable() and pm_runtime_set_active()
  2026-08-31  5:44 [PATCH v2 0/3] counter: rz-mtu3-cnt: check clock and runtime PM errors Li Youhong
@ 2026-08-31  5:44 ` Li Youhong
  2026-08-31  5:44 ` [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values Li Youhong
  2026-08-31  5:44 ` [PATCH v2 3/3] counter: rz-mtu3-cnt: put runtime PM ref if counter init fails Li Youhong
  2 siblings, 0 replies; 6+ messages in thread
From: Li Youhong @ 2026-08-31  5:44 UTC (permalink / raw)
  To: biju.das.jz, wbg; +Cc: linux-iio, linux-renesas-soc, Li Youhong

From: Li Youhong <liyouhong@kylinos.cn>

The driver ignored clk_prepare_enable() failures during probe and
runtime resume, and ignored pm_runtime_set_active() failures during
probe. Propagate the errors so probe does not continue with the clock
disabled or an inconsistent runtime PM state, and resume does not
report success falsely.

Fixes: 0be8907359df ("counter: Add Renesas RZ/G2L MTU3a counter driver")
Suggested-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Li Youhong <liyouhong@kylinos.cn>
---
 drivers/counter/rz-mtu3-cnt.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/counter/rz-mtu3-cnt.c b/drivers/counter/rz-mtu3-cnt.c
index 7bfb6979193c..3654e0fdab20 100644
--- a/drivers/counter/rz-mtu3-cnt.c
+++ b/drivers/counter/rz-mtu3-cnt.c
@@ -817,9 +817,7 @@ static int rz_mtu3_cnt_pm_runtime_resume(struct device *dev)
 {
 	struct clk *const clk = dev_get_drvdata(dev);
 
-	clk_prepare_enable(clk);
-
-	return 0;
+	return clk_prepare_enable(clk);
 }
 
 static DEFINE_RUNTIME_DEV_PM_OPS(rz_mtu3_cnt_pm_ops,
@@ -861,8 +859,14 @@ static int rz_mtu3_cnt_probe(struct platform_device *pdev)
 
 	mutex_init(&priv->lock);
 	platform_set_drvdata(pdev, priv->clk);
-	clk_prepare_enable(priv->clk);
-	pm_runtime_set_active(&pdev->dev);
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_set_active(&pdev->dev);
+	if (ret)
+		goto disable_clock;
+
 	pm_runtime_enable(&pdev->dev);
 	ret = devm_add_action_or_reset(&pdev->dev, rz_mtu3_cnt_pm_disable, dev);
 	if (ret < 0)
-- 
2.25.1


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

* [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values
  2026-08-31  5:44 [PATCH v2 0/3] counter: rz-mtu3-cnt: check clock and runtime PM errors Li Youhong
  2026-08-31  5:44 ` [PATCH v2 1/3] counter: rz-mtu3-cnt: check clk_prepare_enable() and pm_runtime_set_active() Li Youhong
@ 2026-08-31  5:44 ` Li Youhong
  2026-09-03  6:53   ` Biju Das
  2026-08-31  5:44 ` [PATCH v2 3/3] counter: rz-mtu3-cnt: put runtime PM ref if counter init fails Li Youhong
  2 siblings, 1 reply; 6+ messages in thread
From: Li Youhong @ 2026-08-31  5:44 UTC (permalink / raw)
  To: biju.das.jz, wbg; +Cc: linux-iio, linux-renesas-soc, Li Youhong

From: Li Youhong <liyouhong@kylinos.cn>

The driver ignored pm_runtime_get_sync() return values. When runtime
resume fails, pm_runtime_get_sync() returns a negative error code, but
the driver continued with register accesses anyway. Check all call sites
and propagate the error to the caller.

Fixes: 0be8907359df ("counter: Add Renesas RZ/G2L MTU3a counter driver")
Signed-off-by: Li Youhong <liyouhong@kylinos.cn>
---
 drivers/counter/rz-mtu3-cnt.c | 98 ++++++++++++++++++++++++++++-------
 1 file changed, 80 insertions(+), 18 deletions(-)

diff --git a/drivers/counter/rz-mtu3-cnt.c b/drivers/counter/rz-mtu3-cnt.c
index 3654e0fdab20..17912491e522 100644
--- a/drivers/counter/rz-mtu3-cnt.c
+++ b/drivers/counter/rz-mtu3-cnt.c
@@ -102,22 +102,27 @@ static inline struct rz_mtu3_channel *rz_mtu3_get_ch(struct counter_device *coun
 	return &priv->ch[ch_id];
 }
 
-static bool rz_mtu3_is_counter_invalid(struct counter_device *counter, int id)
+static int rz_mtu3_validate_counter(struct counter_device *counter, int id)
 {
 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
 	unsigned long tmdr;
+	int ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		return ret;
+	}
 	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
 	pm_runtime_put(counter->parent);
 
 	if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
-		return false;
+		return 0;
 
 	if (id != RZ_MTU3_32_BIT_CH && !test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
-		return false;
+		return 0;
 
-	return true;
+	return -EBUSY;
 }
 
 static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
@@ -125,6 +130,8 @@ static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
 					    struct rz_mtu3_cnt *const priv,
 					    int id)
 {
+	int ret;
+
 	mutex_lock(&priv->lock);
 
 	if (ch->is_busy && !priv->count_is_enabled[id]) {
@@ -132,9 +139,10 @@ static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
 		return -EINVAL;
 	}
 
-	if (rz_mtu3_is_counter_invalid(counter, id)) {
+	ret = rz_mtu3_validate_counter(counter, id);
+	if (ret) {
 		mutex_unlock(&priv->lock);
-		return -EBUSY;
+		return ret;
 	}
 
 	return 0;
@@ -165,7 +173,12 @@ static int rz_mtu3_count_read(struct counter_device *counter,
 	if (ret)
 		return ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	if (count->id == RZ_MTU3_32_BIT_CH)
 		*val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW);
 	else
@@ -187,7 +200,12 @@ static int rz_mtu3_count_write(struct counter_device *counter,
 	if (ret)
 		return ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	if (count->id == RZ_MTU3_32_BIT_CH)
 		rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val);
 	else
@@ -203,8 +221,13 @@ static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch,
 					      enum counter_function *function)
 {
 	u8 timer_mode;
+	int ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		return ret;
+	}
 	timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1);
 	pm_runtime_put(counter->parent);
 
@@ -279,7 +302,12 @@ static int rz_mtu3_count_function_write(struct counter_device *counter,
 		return -EINVAL;
 	}
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, timer_mode);
 	pm_runtime_put(counter->parent);
 	mutex_unlock(&priv->lock);
@@ -300,7 +328,12 @@ static int rz_mtu3_count_direction_read(struct counter_device *counter,
 	if (ret)
 		return ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR);
 	pm_runtime_put(counter->parent);
 
@@ -377,7 +410,12 @@ static int rz_mtu3_count_ceiling_write(struct counter_device *counter,
 		return -EINVAL;
 	}
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	if (count->id == RZ_MTU3_32_BIT_CH)
 		rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, ceiling);
 	else
@@ -504,7 +542,11 @@ static int rz_mtu3_count_enable_write(struct counter_device *counter,
 		goto exit;
 
 	if (enable) {
-		pm_runtime_get_sync(counter->parent);
+		ret = pm_runtime_get_sync(counter->parent);
+		if (ret < 0) {
+			pm_runtime_put_noidle(counter->parent);
+			goto exit;
+		}
 		ret = rz_mtu3_initialize_counter(counter, count->id);
 		if (ret == 0)
 			priv->count_is_enabled[count->id] = true;
@@ -543,7 +585,12 @@ static int rz_mtu3_cascade_counts_enable_get(struct counter_device *counter,
 	if (ret)
 		return ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
 	pm_runtime_put(counter->parent);
 	*cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr);
@@ -562,7 +609,12 @@ static int rz_mtu3_cascade_counts_enable_set(struct counter_device *counter,
 	if (ret)
 		return ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
 				      RZ_MTU3_TMDR3_LWA, cascade_enable);
 	pm_runtime_put(counter->parent);
@@ -582,7 +634,12 @@ static int rz_mtu3_ext_input_phase_clock_select_get(struct counter_device *count
 	if (ret)
 		return ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
 	pm_runtime_put(counter->parent);
 	*ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr);
@@ -601,7 +658,12 @@ static int rz_mtu3_ext_input_phase_clock_select_set(struct counter_device *count
 	if (ret)
 		return ret;
 
-	pm_runtime_get_sync(counter->parent);
+	ret = pm_runtime_get_sync(counter->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(counter->parent);
+		mutex_unlock(&priv->lock);
+		return ret;
+	}
 	rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
 				      RZ_MTU3_TMDR3_PHCKSEL,
 				      ext_input_phase_clock_select);
-- 
2.25.1


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

* [PATCH v2 3/3] counter: rz-mtu3-cnt: put runtime PM ref if counter init fails
  2026-08-31  5:44 [PATCH v2 0/3] counter: rz-mtu3-cnt: check clock and runtime PM errors Li Youhong
  2026-08-31  5:44 ` [PATCH v2 1/3] counter: rz-mtu3-cnt: check clk_prepare_enable() and pm_runtime_set_active() Li Youhong
  2026-08-31  5:44 ` [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values Li Youhong
@ 2026-08-31  5:44 ` Li Youhong
  2 siblings, 0 replies; 6+ messages in thread
From: Li Youhong @ 2026-08-31  5:44 UTC (permalink / raw)
  To: biju.das.jz, wbg; +Cc: linux-iio, linux-renesas-soc, Li Youhong

From: Li Youhong <liyouhong@kylinos.cn>

Counter enable takes a runtime PM reference before initialization but
only puts it on disable. Drop the reference if initialization fails.

Fixes: 0be8907359df ("counter: Add Renesas RZ/G2L MTU3a counter driver")
Signed-off-by: Li Youhong <liyouhong@kylinos.cn>
---
 drivers/counter/rz-mtu3-cnt.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/counter/rz-mtu3-cnt.c b/drivers/counter/rz-mtu3-cnt.c
index 17912491e522..d3f66fbb9bef 100644
--- a/drivers/counter/rz-mtu3-cnt.c
+++ b/drivers/counter/rz-mtu3-cnt.c
@@ -548,8 +548,11 @@ static int rz_mtu3_count_enable_write(struct counter_device *counter,
 			goto exit;
 		}
 		ret = rz_mtu3_initialize_counter(counter, count->id);
-		if (ret == 0)
-			priv->count_is_enabled[count->id] = true;
+		if (ret < 0) {
+			pm_runtime_put(counter->parent);
+			goto exit;
+		}
+		priv->count_is_enabled[count->id] = true;
 	} else {
 		rz_mtu3_terminate_counter(counter, count->id);
 		priv->count_is_enabled[count->id] = false;
-- 
2.25.1


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

* RE: [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values
  2026-08-31  5:44 ` [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values Li Youhong
@ 2026-09-03  6:53   ` Biju Das
  2026-09-03  7:06     ` 李佑鸿 
  0 siblings, 1 reply; 6+ messages in thread
From: Biju Das @ 2026-09-03  6:53 UTC (permalink / raw)
  To: Li Youhong, wbg@kernel.org
  Cc: linux-iio@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	Li Youhong

Hi Li Youhong,

> -----Original Message-----
> From: Li Youhong <dayou5941@163.com>
> Sent: 31 August 2026 06:44
> Subject: [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values
> 
> From: Li Youhong <liyouhong@kylinos.cn>
> 
> The driver ignored pm_runtime_get_sync() return values. When runtime resume fails, pm_runtime_get_sync()
> returns a negative error code, but the driver continued with register accesses anyway. Check all call
> sites and propagate the error to the caller.
> 
> Fixes: 0be8907359df ("counter: Add Renesas RZ/G2L MTU3a counter driver")
> Signed-off-by: Li Youhong <liyouhong@kylinos.cn>
> ---
>  drivers/counter/rz-mtu3-cnt.c | 98 ++++++++++++++++++++++++++++-------
>  1 file changed, 80 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/counter/rz-mtu3-cnt.c b/drivers/counter/rz-mtu3-cnt.c index
> 3654e0fdab20..17912491e522 100644
> --- a/drivers/counter/rz-mtu3-cnt.c
> +++ b/drivers/counter/rz-mtu3-cnt.c
> @@ -102,22 +102,27 @@ static inline struct rz_mtu3_channel *rz_mtu3_get_ch(struct counter_device *coun
>  	return &priv->ch[ch_id];
>  }
> 
> -static bool rz_mtu3_is_counter_invalid(struct counter_device *counter, int id)
> +static int rz_mtu3_validate_counter(struct counter_device *counter, int
> +id)
>  {
>  	struct rz_mtu3_cnt *const priv = counter_priv(counter);
>  	unsigned long tmdr;
> +	int ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);

There is a better API for error check, pm_runtime_resume_and_get()
Which will avoid code duplication below.

Can you please switch to this API?

Cheers,
Biju


> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		return ret;
> +	}
>  	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
>  	pm_runtime_put(counter->parent);
> 
>  	if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
> -		return false;
> +		return 0;
> 
>  	if (id != RZ_MTU3_32_BIT_CH && !test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
> -		return false;
> +		return 0;
> 
> -	return true;
> +	return -EBUSY;
>  }
> 
>  static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter, @@ -125,6 +130,8 @@ static
> int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
>  					    struct rz_mtu3_cnt *const priv,
>  					    int id)
>  {
> +	int ret;
> +
>  	mutex_lock(&priv->lock);
> 
>  	if (ch->is_busy && !priv->count_is_enabled[id]) { @@ -132,9 +139,10 @@ static int
> rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
>  		return -EINVAL;
>  	}
> 
> -	if (rz_mtu3_is_counter_invalid(counter, id)) {
> +	ret = rz_mtu3_validate_counter(counter, id);
> +	if (ret) {
>  		mutex_unlock(&priv->lock);
> -		return -EBUSY;
> +		return ret;
>  	}
> 
>  	return 0;
> @@ -165,7 +173,12 @@ static int rz_mtu3_count_read(struct counter_device *counter,
>  	if (ret)
>  		return ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	if (count->id == RZ_MTU3_32_BIT_CH)
>  		*val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW);
>  	else
> @@ -187,7 +200,12 @@ static int rz_mtu3_count_write(struct counter_device *counter,
>  	if (ret)
>  		return ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	if (count->id == RZ_MTU3_32_BIT_CH)
>  		rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val);
>  	else
> @@ -203,8 +221,13 @@ static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch,
>  					      enum counter_function *function)  {
>  	u8 timer_mode;
> +	int ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		return ret;
> +	}
>  	timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1);
>  	pm_runtime_put(counter->parent);
> 
> @@ -279,7 +302,12 @@ static int rz_mtu3_count_function_write(struct counter_device *counter,
>  		return -EINVAL;
>  	}
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, timer_mode);
>  	pm_runtime_put(counter->parent);
>  	mutex_unlock(&priv->lock);
> @@ -300,7 +328,12 @@ static int rz_mtu3_count_direction_read(struct counter_device *counter,
>  	if (ret)
>  		return ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR);
>  	pm_runtime_put(counter->parent);
> 
> @@ -377,7 +410,12 @@ static int rz_mtu3_count_ceiling_write(struct counter_device *counter,
>  		return -EINVAL;
>  	}
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	if (count->id == RZ_MTU3_32_BIT_CH)
>  		rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, ceiling);
>  	else
> @@ -504,7 +542,11 @@ static int rz_mtu3_count_enable_write(struct counter_device *counter,
>  		goto exit;
> 
>  	if (enable) {
> -		pm_runtime_get_sync(counter->parent);
> +		ret = pm_runtime_get_sync(counter->parent);
> +		if (ret < 0) {
> +			pm_runtime_put_noidle(counter->parent);
> +			goto exit;
> +		}
>  		ret = rz_mtu3_initialize_counter(counter, count->id);
>  		if (ret == 0)
>  			priv->count_is_enabled[count->id] = true; @@ -543,7 +585,12 @@ static int
> rz_mtu3_cascade_counts_enable_get(struct counter_device *counter,
>  	if (ret)
>  		return ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
>  	pm_runtime_put(counter->parent);
>  	*cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr); @@ -562,7 +609,12 @@ static int
> rz_mtu3_cascade_counts_enable_set(struct counter_device *counter,
>  	if (ret)
>  		return ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
>  				      RZ_MTU3_TMDR3_LWA, cascade_enable);
>  	pm_runtime_put(counter->parent);
> @@ -582,7 +634,12 @@ static int rz_mtu3_ext_input_phase_clock_select_get(struct counter_device *count
>  	if (ret)
>  		return ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
>  	pm_runtime_put(counter->parent);
>  	*ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr); @@ -601,7 +658,12 @@
> static int rz_mtu3_ext_input_phase_clock_select_set(struct counter_device *count
>  	if (ret)
>  		return ret;
> 
> -	pm_runtime_get_sync(counter->parent);
> +	ret = pm_runtime_get_sync(counter->parent);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(counter->parent);
> +		mutex_unlock(&priv->lock);
> +		return ret;
> +	}
>  	rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
>  				      RZ_MTU3_TMDR3_PHCKSEL,
>  				      ext_input_phase_clock_select);
> --
> 2.25.1


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

* Re:RE: [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values
  2026-09-03  6:53   ` Biju Das
@ 2026-09-03  7:06     ` 李佑鸿 
  0 siblings, 0 replies; 6+ messages in thread
From: 李佑鸿  @ 2026-09-03  7:06 UTC (permalink / raw)
  To: Biju Das
  Cc: wbg@kernel.org, linux-iio@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org, Li Youhong









Hi Biju,








At 2026-09-03 14:53:24, "Biju Das" <biju.das.jz@bp.renesas.com> wrote:
>Hi Li Youhong,
>
>> -----Original Message-----
>> From: Li Youhong <dayou5941@163.com>
>> Sent: 31 August 2026 06:44
>> Subject: [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values
>> 
>> From: Li Youhong <liyouhong@kylinos.cn>
>> 
>> The driver ignored pm_runtime_get_sync() return values. When runtime resume fails, pm_runtime_get_sync()
>> returns a negative error code, but the driver continued with register accesses anyway. Check all call
>> sites and propagate the error to the caller.
>> 
>> Fixes: 0be8907359df ("counter: Add Renesas RZ/G2L MTU3a counter driver")
>> Signed-off-by: Li Youhong <liyouhong@kylinos.cn>
>> ---
>>  drivers/counter/rz-mtu3-cnt.c | 98 ++++++++++++++++++++++++++++-------
>>  1 file changed, 80 insertions(+), 18 deletions(-)
>> 
>> diff --git a/drivers/counter/rz-mtu3-cnt.c b/drivers/counter/rz-mtu3-cnt.c index
>> 3654e0fdab20..17912491e522 100644
>> --- a/drivers/counter/rz-mtu3-cnt.c
>> +++ b/drivers/counter/rz-mtu3-cnt.c
>> @@ -102,22 +102,27 @@ static inline struct rz_mtu3_channel *rz_mtu3_get_ch(struct counter_device *coun
>>  	return &priv->ch[ch_id];
>>  }
>> 
>> -static bool rz_mtu3_is_counter_invalid(struct counter_device *counter, int id)
>> +static int rz_mtu3_validate_counter(struct counter_device *counter, int
>> +id)
>>  {
>>  	struct rz_mtu3_cnt *const priv = counter_priv(counter);
>>  	unsigned long tmdr;
>> +	int ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>
>There is a better API for error check, pm_runtime_resume_and_get()
>Which will avoid code duplication below.
>
>Can you please switch to this API?
>
>Cheers,

>Biju


Thanks for the suggestion. Will switch to pm_runtime_resume_and_get ()
and send a v3.

Regards,
Li Youhong


>
>
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		return ret;
>> +	}
>>  	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
>>  	pm_runtime_put(counter->parent);
>> 
>>  	if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
>> -		return false;
>> +		return 0;
>> 
>>  	if (id != RZ_MTU3_32_BIT_CH && !test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
>> -		return false;
>> +		return 0;
>> 
>> -	return true;
>> +	return -EBUSY;
>>  }
>> 
>>  static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter, @@ -125,6 +130,8 @@ static
>> int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
>>  					    struct rz_mtu3_cnt *const priv,
>>  					    int id)
>>  {
>> +	int ret;
>> +
>>  	mutex_lock(&priv->lock);
>> 
>>  	if (ch->is_busy && !priv->count_is_enabled[id]) { @@ -132,9 +139,10 @@ static int
>> rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
>>  		return -EINVAL;
>>  	}
>> 
>> -	if (rz_mtu3_is_counter_invalid(counter, id)) {
>> +	ret = rz_mtu3_validate_counter(counter, id);
>> +	if (ret) {
>>  		mutex_unlock(&priv->lock);
>> -		return -EBUSY;
>> +		return ret;
>>  	}
>> 
>>  	return 0;
>> @@ -165,7 +173,12 @@ static int rz_mtu3_count_read(struct counter_device *counter,
>>  	if (ret)
>>  		return ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	if (count->id == RZ_MTU3_32_BIT_CH)
>>  		*val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW);
>>  	else
>> @@ -187,7 +200,12 @@ static int rz_mtu3_count_write(struct counter_device *counter,
>>  	if (ret)
>>  		return ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	if (count->id == RZ_MTU3_32_BIT_CH)
>>  		rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val);
>>  	else
>> @@ -203,8 +221,13 @@ static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch,
>>  					      enum counter_function *function)  {
>>  	u8 timer_mode;
>> +	int ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		return ret;
>> +	}
>>  	timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1);
>>  	pm_runtime_put(counter->parent);
>> 
>> @@ -279,7 +302,12 @@ static int rz_mtu3_count_function_write(struct counter_device *counter,
>>  		return -EINVAL;
>>  	}
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, timer_mode);
>>  	pm_runtime_put(counter->parent);
>>  	mutex_unlock(&priv->lock);
>> @@ -300,7 +328,12 @@ static int rz_mtu3_count_direction_read(struct counter_device *counter,
>>  	if (ret)
>>  		return ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR);
>>  	pm_runtime_put(counter->parent);
>> 
>> @@ -377,7 +410,12 @@ static int rz_mtu3_count_ceiling_write(struct counter_device *counter,
>>  		return -EINVAL;
>>  	}
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	if (count->id == RZ_MTU3_32_BIT_CH)
>>  		rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, ceiling);
>>  	else
>> @@ -504,7 +542,11 @@ static int rz_mtu3_count_enable_write(struct counter_device *counter,
>>  		goto exit;
>> 
>>  	if (enable) {
>> -		pm_runtime_get_sync(counter->parent);
>> +		ret = pm_runtime_get_sync(counter->parent);
>> +		if (ret < 0) {
>> +			pm_runtime_put_noidle(counter->parent);
>> +			goto exit;
>> +		}
>>  		ret = rz_mtu3_initialize_counter(counter, count->id);
>>  		if (ret == 0)
>>  			priv->count_is_enabled[count->id] = true; @@ -543,7 +585,12 @@ static int
>> rz_mtu3_cascade_counts_enable_get(struct counter_device *counter,
>>  	if (ret)
>>  		return ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
>>  	pm_runtime_put(counter->parent);
>>  	*cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr); @@ -562,7 +609,12 @@ static int
>> rz_mtu3_cascade_counts_enable_set(struct counter_device *counter,
>>  	if (ret)
>>  		return ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
>>  				      RZ_MTU3_TMDR3_LWA, cascade_enable);
>>  	pm_runtime_put(counter->parent);
>> @@ -582,7 +634,12 @@ static int rz_mtu3_ext_input_phase_clock_select_get(struct counter_device *count
>>  	if (ret)
>>  		return ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
>>  	pm_runtime_put(counter->parent);
>>  	*ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr); @@ -601,7 +658,12 @@
>> static int rz_mtu3_ext_input_phase_clock_select_set(struct counter_device *count
>>  	if (ret)
>>  		return ret;
>> 
>> -	pm_runtime_get_sync(counter->parent);
>> +	ret = pm_runtime_get_sync(counter->parent);
>> +	if (ret < 0) {
>> +		pm_runtime_put_noidle(counter->parent);
>> +		mutex_unlock(&priv->lock);
>> +		return ret;
>> +	}
>>  	rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
>>  				      RZ_MTU3_TMDR3_PHCKSEL,
>>  				      ext_input_phase_clock_select);
>> --
>> 2.25.1

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

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

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31  5:44 [PATCH v2 0/3] counter: rz-mtu3-cnt: check clock and runtime PM errors Li Youhong
2026-08-31  5:44 ` [PATCH v2 1/3] counter: rz-mtu3-cnt: check clk_prepare_enable() and pm_runtime_set_active() Li Youhong
2026-08-31  5:44 ` [PATCH v2 2/3] counter: rz-mtu3-cnt: check pm_runtime_get_sync() return values Li Youhong
2026-09-03  6:53   ` Biju Das
2026-09-03  7:06     ` 李佑鸿 
2026-08-31  5:44 ` [PATCH v2 3/3] counter: rz-mtu3-cnt: put runtime PM ref if counter init fails Li Youhong

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