lpi2c_imx_probe() prepares and enables the controller clocks before enabling runtime PM. After probe succeeds, clock management is handed over to the runtime PM callbacks. However, lpi2c_imx_remove() only disables runtime PM and autosuspend. It does not ensure that the device is active before teardown or drop the clock references acquired during probe. For platforms which do not require clock prepare/unprepare in the runtime PM callbacks, runtime suspend only disables the clocks, leaving the prepare references held for the lifetime of the driver. Since the remove path never unprepares them, these references are leaked when the driver is unbound. For platforms which prepare and unprepare clocks during runtime PM, an unbind while the device is still runtime active can similarly leave the clock prepare and enable references outstanding. Resume the device before disabling runtime PM so that the clocks are in a known enabled and prepared state. Then drop the temporary runtime PM reference and disable and unprepare the clocks during final teardown. Mark the device suspended after the hardware resources have been released. This issue was found by manual code inspection. Fixes: 13d6eb20fc79 ("i2c: imx-lpi2c: add runtime pm support") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li --- drivers/i2c/busses/i2c-imx-lpi2c.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index e1a4338bc51e..481950004b2a 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -1604,8 +1604,13 @@ static void lpi2c_imx_remove(struct platform_device *pdev) i2c_del_adapter(&lpi2c_imx->adapter); + pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); + + clk_bulk_disable_unprepare(lpi2c_imx->num_clks, lpi2c_imx->clks); + pm_runtime_set_suspended(&pdev->dev); } static int __maybe_unused lpi2c_runtime_suspend(struct device *dev) -- 2.43.0