[PATCH] iio: gyro: mpu3050: Balance runtime PM on trigger enable errors

Linmao Li posted 1 patch 1 week, 4 days ago
drivers/iio/gyro/mpu3050-core.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
[PATCH] iio: gyro: mpu3050: Balance runtime PM on trigger enable errors
Posted by Linmao Li 1 week, 4 days ago
mpu3050_drdy_trigger_set_state() takes a runtime PM reference before
configuring the FIFO and data-ready interrupt. Five configuration failure
paths return without dropping that reference. The IIO trigger core does not
call the disable callback after a failed enable, so each failure increments
the device usage counter permanently.

Use pm_runtime_resume_and_get() to handle resume failures without changing
the usage counter, and drop the reference on subsequent configuration
errors. Only mark the hardware trigger active immediately before enabling
its interrupt, and clear the flag if that operation fails.

Fixes: 3904b28efb2c ("iio: gyro: Add driver for the MPU-3050 gyroscope")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
---
 drivers/iio/gyro/mpu3050-core.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c
index d84e04e4b431..6bee1caadd81 100644
--- a/drivers/iio/gyro/mpu3050-core.c
+++ b/drivers/iio/gyro/mpu3050-core.c
@@ -988,20 +988,21 @@ static int mpu3050_drdy_trigger_set_state(struct iio_trigger *trig,
 		return 0;
 	} else {
 		/* Else we're enabling the trigger from this point */
-		pm_runtime_get_sync(mpu3050->dev);
-		mpu3050->hw_irq_trigger = true;
+		ret = pm_runtime_resume_and_get(mpu3050->dev);
+		if (ret)
+			return ret;
 
 		/* Disable all things in the FIFO */
 		ret = regmap_write(mpu3050->map, MPU3050_FIFO_EN, 0);
 		if (ret)
-			return ret;
+			goto err_pm_put;
 
 		/* Reset and enable the FIFO */
 		ret = regmap_set_bits(mpu3050->map, MPU3050_USR_CTRL,
 				      MPU3050_USR_CTRL_FIFO_EN |
 				      MPU3050_USR_CTRL_FIFO_RST);
 		if (ret)
-			return ret;
+			goto err_pm_put;
 
 		mpu3050->pending_fifo_footer = false;
 
@@ -1013,12 +1014,12 @@ static int mpu3050_drdy_trigger_set_state(struct iio_trigger *trig,
 				   MPU3050_FIFO_EN_GYRO_ZOUT |
 				   MPU3050_FIFO_EN_FOOTER);
 		if (ret)
-			return ret;
+			goto err_pm_put;
 
 		/* Configure the sample engine */
 		ret = mpu3050_start_sampling(mpu3050);
 		if (ret)
-			return ret;
+			goto err_pm_put;
 
 		/* Clear IRQ flag */
 		ret = regmap_read(mpu3050->map, MPU3050_INT_STATUS, &val);
@@ -1035,12 +1036,20 @@ static int mpu3050_drdy_trigger_set_state(struct iio_trigger *trig,
 		if (mpu3050->irq_opendrain)
 			val |= MPU3050_INT_OPEN;
 
+		mpu3050->hw_irq_trigger = true;
 		ret = regmap_write(mpu3050->map, MPU3050_INT_CFG, val);
 		if (ret)
-			return ret;
+			goto err_clear_trigger;
 	}
 
 	return 0;
+
+err_clear_trigger:
+	mpu3050->hw_irq_trigger = false;
+err_pm_put:
+	pm_runtime_put_autosuspend(mpu3050->dev);
+
+	return ret;
 }
 
 static const struct iio_trigger_ops mpu3050_trigger_ops = {
-- 
2.25.1
Re: [PATCH] iio: gyro: mpu3050: Balance runtime PM on trigger enable errors
Posted by Jonathan Cameron 5 days, 16 hours ago
On Tue, 14 Jul 2026 17:39:08 +0800
Linmao Li <lilinmao@kylinos.cn> wrote:

> mpu3050_drdy_trigger_set_state() takes a runtime PM reference before
> configuring the FIFO and data-ready interrupt. Five configuration failure
> paths return without dropping that reference. The IIO trigger core does not
> call the disable callback after a failed enable, so each failure increments
> the device usage counter permanently.
> 
> Use pm_runtime_resume_and_get() to handle resume failures without changing
> the usage counter, and drop the reference on subsequent configuration
> errors. Only mark the hardware trigger active immediately before enabling
> its interrupt, and clear the flag if that operation fails.
> 
> Fixes: 3904b28efb2c ("iio: gyro: Add driver for the MPU-3050 gyroscope")
> Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Hi.

Thanks for the patch.


There is another patch on list for this issue.
https://lore.kernel.org/all/20260714131426.4257-2-birenpandya@gmail.com/

(and another approach before that)

Thanks,

Jonathan

> ---
>  drivers/iio/gyro/mpu3050-core.c | 23 ++++++++++++++++-------
>  1 file changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c
> index d84e04e4b431..6bee1caadd81 100644
> --- a/drivers/iio/gyro/mpu3050-core.c
> +++ b/drivers/iio/gyro/mpu3050-core.c
> @@ -988,20 +988,21 @@ static int mpu3050_drdy_trigger_set_state(struct iio_trigger *trig,
>  		return 0;
>  	} else {
>  		/* Else we're enabling the trigger from this point */
> -		pm_runtime_get_sync(mpu3050->dev);
> -		mpu3050->hw_irq_trigger = true;
> +		ret = pm_runtime_resume_and_get(mpu3050->dev);
> +		if (ret)
> +			return ret;
>  
>  		/* Disable all things in the FIFO */
>  		ret = regmap_write(mpu3050->map, MPU3050_FIFO_EN, 0);
>  		if (ret)
> -			return ret;
> +			goto err_pm_put;
>  
>  		/* Reset and enable the FIFO */
>  		ret = regmap_set_bits(mpu3050->map, MPU3050_USR_CTRL,
>  				      MPU3050_USR_CTRL_FIFO_EN |
>  				      MPU3050_USR_CTRL_FIFO_RST);
>  		if (ret)
> -			return ret;
> +			goto err_pm_put;
>  
>  		mpu3050->pending_fifo_footer = false;
>  
> @@ -1013,12 +1014,12 @@ static int mpu3050_drdy_trigger_set_state(struct iio_trigger *trig,
>  				   MPU3050_FIFO_EN_GYRO_ZOUT |
>  				   MPU3050_FIFO_EN_FOOTER);
>  		if (ret)
> -			return ret;
> +			goto err_pm_put;
>  
>  		/* Configure the sample engine */
>  		ret = mpu3050_start_sampling(mpu3050);
>  		if (ret)
> -			return ret;
> +			goto err_pm_put;
>  
>  		/* Clear IRQ flag */
>  		ret = regmap_read(mpu3050->map, MPU3050_INT_STATUS, &val);
> @@ -1035,12 +1036,20 @@ static int mpu3050_drdy_trigger_set_state(struct iio_trigger *trig,
>  		if (mpu3050->irq_opendrain)
>  			val |= MPU3050_INT_OPEN;
>  
> +		mpu3050->hw_irq_trigger = true;
>  		ret = regmap_write(mpu3050->map, MPU3050_INT_CFG, val);
>  		if (ret)
> -			return ret;
> +			goto err_clear_trigger;
>  	}
>  
>  	return 0;
> +
> +err_clear_trigger:
> +	mpu3050->hw_irq_trigger = false;
> +err_pm_put:
> +	pm_runtime_put_autosuspend(mpu3050->dev);
> +
> +	return ret;
>  }
>  
>  static const struct iio_trigger_ops mpu3050_trigger_ops = {