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
This commit is contained in:
Коммит
5f43644394
|
@ -433,13 +433,17 @@ iop3xx_i2c_probe(struct platform_device *pdev)
|
|||
adapter_data->gpio_scl = devm_gpiod_get_optional(&pdev->dev,
|
||||
"scl",
|
||||
GPIOD_ASIS);
|
||||
if (IS_ERR(adapter_data->gpio_scl))
|
||||
return PTR_ERR(adapter_data->gpio_scl);
|
||||
if (IS_ERR(adapter_data->gpio_scl)) {
|
||||
ret = PTR_ERR(adapter_data->gpio_scl);
|
||||
goto free_both;
|
||||
}
|
||||
adapter_data->gpio_sda = devm_gpiod_get_optional(&pdev->dev,
|
||||
"sda",
|
||||
GPIOD_ASIS);
|
||||
if (IS_ERR(adapter_data->gpio_sda))
|
||||
return PTR_ERR(adapter_data->gpio_sda);
|
||||
if (IS_ERR(adapter_data->gpio_sda)) {
|
||||
ret = PTR_ERR(adapter_data->gpio_sda);
|
||||
goto free_both;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
|
|
|
@ -1608,14 +1608,18 @@ static int tegra_i2c_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
if (!pm_runtime_enabled(&pdev->dev))
|
||||
if (!pm_runtime_enabled(&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);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "runtime resume failed\n");
|
||||
goto unprepare_div_clk;
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "runtime resume failed\n");
|
||||
goto disable_rpm;
|
||||
}
|
||||
}
|
||||
|
||||
if (i2c_dev->is_multimaster_mode) {
|
||||
|
@ -1623,7 +1627,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
|
|||
if (ret < 0) {
|
||||
dev_err(i2c_dev->dev, "div_clk enable failed %d\n",
|
||||
ret);
|
||||
goto disable_rpm;
|
||||
goto put_rpm;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1671,11 +1675,16 @@ disable_div_clk:
|
|||
if (i2c_dev->is_multimaster_mode)
|
||||
clk_disable(i2c_dev->div_clk);
|
||||
|
||||
disable_rpm:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
put_rpm:
|
||||
if (pm_runtime_enabled(&pdev->dev))
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
else
|
||||
tegra_i2c_runtime_suspend(&pdev->dev);
|
||||
|
||||
disable_rpm:
|
||||
if (pm_runtime_enabled(&pdev->dev))
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
unprepare_div_clk:
|
||||
clk_unprepare(i2c_dev->div_clk);
|
||||
|
||||
|
@ -1710,9 +1719,14 @@ static int tegra_i2c_remove(struct platform_device *pdev)
|
|||
static int __maybe_unused tegra_i2c_suspend(struct device *dev)
|
||||
{
|
||||
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
i2c_mark_adapter_suspended(&i2c_dev->adapter);
|
||||
|
||||
err = pm_runtime_force_suspend(dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1733,6 +1747,10 @@ static int __maybe_unused tegra_i2c_resume(struct device *dev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
err = pm_runtime_force_resume(dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
i2c_mark_adapter_resumed(&i2c_dev->adapter);
|
||||
|
||||
return 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче