Skip to content

Commit 5f43644

Browse files
committed
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Two runtime PM fixes and one leak fix" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: iop3xx: Fix memory leak in probe error path i2c: tegra: Properly disable runtime PM on driver's probe error i2c: tegra: Fix suspending in active runtime PM state
2 parents 8f8972a + e641757 commit 5f43644

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

drivers/i2c/busses/i2c-iop3xx.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,13 +433,17 @@ iop3xx_i2c_probe(struct platform_device *pdev)
433433
adapter_data->gpio_scl = devm_gpiod_get_optional(&pdev->dev,
434434
"scl",
435435
GPIOD_ASIS);
436-
if (IS_ERR(adapter_data->gpio_scl))
437-
return PTR_ERR(adapter_data->gpio_scl);
436+
if (IS_ERR(adapter_data->gpio_scl)) {
437+
ret = PTR_ERR(adapter_data->gpio_scl);
438+
goto free_both;
439+
}
438440
adapter_data->gpio_sda = devm_gpiod_get_optional(&pdev->dev,
439441
"sda",
440442
GPIOD_ASIS);
441-
if (IS_ERR(adapter_data->gpio_sda))
442-
return PTR_ERR(adapter_data->gpio_sda);
443+
if (IS_ERR(adapter_data->gpio_sda)) {
444+
ret = PTR_ERR(adapter_data->gpio_sda);
445+
goto free_both;
446+
}
443447

444448
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
445449
if (!res) {

drivers/i2c/busses/i2c-tegra.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,22 +1608,26 @@ static int tegra_i2c_probe(struct platform_device *pdev)
16081608
}
16091609

16101610
pm_runtime_enable(&pdev->dev);
1611-
if (!pm_runtime_enabled(&pdev->dev))
1611+
if (!pm_runtime_enabled(&pdev->dev)) {
16121612
ret = tegra_i2c_runtime_resume(&pdev->dev);
1613-
else
1613+
if (ret < 0) {
1614+
dev_err(&pdev->dev, "runtime resume failed\n");
1615+
goto unprepare_div_clk;
1616+
}
1617+
} else {
16141618
ret = pm_runtime_get_sync(i2c_dev->dev);
1615-
1616-
if (ret < 0) {
1617-
dev_err(&pdev->dev, "runtime resume failed\n");
1618-
goto unprepare_div_clk;
1619+
if (ret < 0) {
1620+
dev_err(&pdev->dev, "runtime resume failed\n");
1621+
goto disable_rpm;
1622+
}
16191623
}
16201624

16211625
if (i2c_dev->is_multimaster_mode) {
16221626
ret = clk_enable(i2c_dev->div_clk);
16231627
if (ret < 0) {
16241628
dev_err(i2c_dev->dev, "div_clk enable failed %d\n",
16251629
ret);
1626-
goto disable_rpm;
1630+
goto put_rpm;
16271631
}
16281632
}
16291633

@@ -1671,11 +1675,16 @@ static int tegra_i2c_probe(struct platform_device *pdev)
16711675
if (i2c_dev->is_multimaster_mode)
16721676
clk_disable(i2c_dev->div_clk);
16731677

1674-
disable_rpm:
1675-
pm_runtime_disable(&pdev->dev);
1676-
if (!pm_runtime_status_suspended(&pdev->dev))
1678+
put_rpm:
1679+
if (pm_runtime_enabled(&pdev->dev))
1680+
pm_runtime_put_sync(&pdev->dev);
1681+
else
16771682
tegra_i2c_runtime_suspend(&pdev->dev);
16781683

1684+
disable_rpm:
1685+
if (pm_runtime_enabled(&pdev->dev))
1686+
pm_runtime_disable(&pdev->dev);
1687+
16791688
unprepare_div_clk:
16801689
clk_unprepare(i2c_dev->div_clk);
16811690

@@ -1710,9 +1719,14 @@ static int tegra_i2c_remove(struct platform_device *pdev)
17101719
static int __maybe_unused tegra_i2c_suspend(struct device *dev)
17111720
{
17121721
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
1722+
int err;
17131723

17141724
i2c_mark_adapter_suspended(&i2c_dev->adapter);
17151725

1726+
err = pm_runtime_force_suspend(dev);
1727+
if (err < 0)
1728+
return err;
1729+
17161730
return 0;
17171731
}
17181732

@@ -1733,6 +1747,10 @@ static int __maybe_unused tegra_i2c_resume(struct device *dev)
17331747
if (err)
17341748
return err;
17351749

1750+
err = pm_runtime_force_resume(dev);
1751+
if (err < 0)
1752+
return err;
1753+
17361754
i2c_mark_adapter_resumed(&i2c_dev->adapter);
17371755

17381756
return 0;

0 commit comments

Comments
 (0)