Re: [PATCH] i2c: qcom-cci: fix autosuspend cleanup

Loic Poulain <[email protected]> Wed, 12 Aug 2026 15:50:50 +0200
Newsgroups org.kernel.vger.linux-i2c,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <CAFEp6-177whXgFj1uViqg1Gv=68GkqzG_gYqEbV1kX-9UXkSHw@mail.gmail.com>
On Wed, Aug 12, 2026 at 11:46 AM Guangshuo Li <[email protected]> wrote:
>
> cci_probe() calls pm_runtime_use_autosuspend(), but the remove path
> does not call the matching pm_runtime_dont_use_autosuspend() before
> disabling runtime PM.
>
> If the autosuspend delay is set to a negative value while autosuspend
> is enabled, the runtime PM core increments usage_count to prevent
> runtime suspend. Without undoing the autosuspend setting during
> teardown, this reference is not dropped and usage_count remains
> unbalanced.
>
> Use devm_pm_runtime_set_active_enabled() to manage the runtime PM
> state. Its managed cleanup disables autosuspend and runtime PM and
> restores the suspended state on probe failure and driver removal.
> Remove the now redundant manual runtime PM cleanup.
>
> This issue was found by manual code inspection.
>
> Fixes: e517526195de ("i2c: Add Qualcomm CCI I2C driver")
> Cc: [email protected]
> Signed-off-by: Guangshuo Li <[email protected]>

Reviewed-by: Loic Poulain <[email protected]>

> ---
>  drivers/i2c/busses/i2c-qcom-cci.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
> index bdeda3979c48..25b6e4e9e3fa 100644
> --- a/drivers/i2c/busses/i2c-qcom-cci.c
> +++ b/drivers/i2c/busses/i2c-qcom-cci.c
> @@ -595,9 +595,11 @@ static int cci_probe(struct platform_device *pdev)
>                 goto disable_clocks;
>
>         pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
> +       ret = devm_pm_runtime_set_active_enabled(dev);
> +       if (ret)
> +               goto disable_clocks;
> +
>         pm_runtime_use_autosuspend(dev);
> -       pm_runtime_set_active(dev);
> -       pm_runtime_enable(dev);
>
>         for (i = 0; i < cci->data->num_masters; i++) {
>                 if (!cci->master[i].cci)
> @@ -613,8 +615,6 @@ static int cci_probe(struct platform_device *pdev)
>         return 0;
>
>  error_i2c:
> -       pm_runtime_disable(dev);
> -       pm_runtime_dont_use_autosuspend(dev);
>
>         for (--i ; i >= 0; i--) {
>                 if (cci->master[i].cci) {
> @@ -640,9 +640,6 @@ static void cci_remove(struct platform_device *pdev)
>                         cci_halt(cci, i);
>                 }
>         }
> -
> -       pm_runtime_disable(&pdev->dev);
> -       pm_runtime_set_suspended(&pdev->dev);
>  }
>
>  static const struct cci_data cci_v1_data = {
> --
> 2.43.0
>