i2c: tegra: Ensure that device is suspended before driver is removed
authorDmitry Osipenko <digetx@gmail.com>
Tue, 19 Oct 2021 23:29:19 +0000 (02:29 +0300)
committerWolfram Sang <wsa@kernel.org>
Fri, 29 Oct 2021 19:51:31 +0000 (21:51 +0200)
Tegra I2C device isn't guaranteed to be suspended after removal of
the driver since driver uses pm_runtime_put() that is asynchronous and
pm_runtime_disable() cancels pending power-change requests. This means
that potentially refcount of the clocks may become unbalanced after
removal of the driver. This a very minor problem which unlikely to
happen in practice and won't cause any visible problems, nevertheless
let's replace pm_runtime_disable() with pm_runtime_force_suspend() and
use pm_runtime_put_sync() which disables RPM of the device and puts it
into suspend before driver is removed.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
drivers/i2c/busses/i2c-tegra.c

index c883044..b3184c4 100644 (file)
@@ -1700,7 +1700,7 @@ static int tegra_i2c_init_hardware(struct tegra_i2c_dev *i2c_dev)
        else
                ret = tegra_i2c_init(i2c_dev);
 
-       pm_runtime_put(i2c_dev->dev);
+       pm_runtime_put_sync(i2c_dev->dev);
 
        return ret;
 }
@@ -1819,7 +1819,7 @@ static int tegra_i2c_remove(struct platform_device *pdev)
        struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
 
        i2c_del_adapter(&i2c_dev->adapter);
-       pm_runtime_disable(i2c_dev->dev);
+       pm_runtime_force_suspend(i2c_dev->dev);
 
        tegra_i2c_release_dma(i2c_dev);
        tegra_i2c_release_clocks(i2c_dev);