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 >