Commit 24a49678 authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Wolfram Sang

i2c: tegra: Properly disable runtime PM on driver's probe error

One of the recent Tegra I2C commits made a change that resumes runtime PM
during driver's probe, but it missed to put the RPM in a case of error.
Note that it's not correct to use pm_runtime_status_suspended because it
breaks RPM refcounting.

Fixes: 8ebf15e9 ("i2c: tegra: Move suspend handling to NOIRQ phase")
Cc: <stable@vger.kernel.org> # v5.4+
Tested-by: default avatarThierry Reding <treding@nvidia.com>
Signed-off-by: default avatarDmitry Osipenko <digetx@gmail.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 9f42de8d
...@@ -1608,14 +1608,18 @@ static int tegra_i2c_probe(struct platform_device *pdev) ...@@ -1608,14 +1608,18 @@ static int tegra_i2c_probe(struct platform_device *pdev)
} }
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) if (!pm_runtime_enabled(&pdev->dev)) {
ret = tegra_i2c_runtime_resume(&pdev->dev); ret = tegra_i2c_runtime_resume(&pdev->dev);
else if (ret < 0) {
dev_err(&pdev->dev, "runtime resume failed\n");
goto unprepare_div_clk;
}
} else {
ret = pm_runtime_get_sync(i2c_dev->dev); ret = pm_runtime_get_sync(i2c_dev->dev);
if (ret < 0) {
if (ret < 0) { dev_err(&pdev->dev, "runtime resume failed\n");
dev_err(&pdev->dev, "runtime resume failed\n"); goto disable_rpm;
goto unprepare_div_clk; }
} }
if (i2c_dev->is_multimaster_mode) { if (i2c_dev->is_multimaster_mode) {
...@@ -1623,7 +1627,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) ...@@ -1623,7 +1627,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
if (ret < 0) { if (ret < 0) {
dev_err(i2c_dev->dev, "div_clk enable failed %d\n", dev_err(i2c_dev->dev, "div_clk enable failed %d\n",
ret); ret);
goto disable_rpm; goto put_rpm;
} }
} }
...@@ -1671,11 +1675,16 @@ static int tegra_i2c_probe(struct platform_device *pdev) ...@@ -1671,11 +1675,16 @@ static int tegra_i2c_probe(struct platform_device *pdev)
if (i2c_dev->is_multimaster_mode) if (i2c_dev->is_multimaster_mode)
clk_disable(i2c_dev->div_clk); clk_disable(i2c_dev->div_clk);
disable_rpm: put_rpm:
pm_runtime_disable(&pdev->dev); if (pm_runtime_enabled(&pdev->dev))
if (!pm_runtime_status_suspended(&pdev->dev)) pm_runtime_put_sync(&pdev->dev);
else
tegra_i2c_runtime_suspend(&pdev->dev); tegra_i2c_runtime_suspend(&pdev->dev);
disable_rpm:
if (pm_runtime_enabled(&pdev->dev))
pm_runtime_disable(&pdev->dev);
unprepare_div_clk: unprepare_div_clk:
clk_unprepare(i2c_dev->div_clk); clk_unprepare(i2c_dev->div_clk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment