Skip to content

Commit 126dbc6

Browse files
rafaeljwWolfram Sang
authored andcommitted
PM: i2c-designware-platdrv: Clean up PM handling in probe
The power management handling in dw_i2c_plat_probe() is somewhat messy and it is rather hard to figure out the code intention for the case when pm_disabled is set. In that case, the driver doesn't enable runtime PM at all, but in addition to that it calls pm_runtime_forbid() as though it wasn't sure if runtime PM might be enabled for the device later by someone else. Although that concern doesn't seem to be actually valid, the device is clearly still expected to be PM-capable even in the pm_disabled set case, so a better approach would be to enable runtime PM for it unconditionally and prevent it from being runtime-suspended by using pm_runtime_get_noresume(). Make the driver do that. Signed-off-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 9e66317 commit 126dbc6

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

drivers/i2c/busses/i2c-designware-platdrv.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,14 @@ static void dw_i2c_set_fifo_size(struct dw_i2c_dev *dev, int id)
249249
}
250250
}
251251

252+
static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
253+
{
254+
pm_runtime_disable(dev->dev);
255+
256+
if (dev->pm_disabled)
257+
pm_runtime_put_noidle(dev->dev);
258+
}
259+
252260
static int dw_i2c_plat_probe(struct platform_device *pdev)
253261
{
254262
struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -362,14 +370,17 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
362370
ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev));
363371
adap->dev.of_node = pdev->dev.of_node;
364372

365-
if (dev->pm_disabled) {
366-
pm_runtime_forbid(&pdev->dev);
367-
} else {
368-
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
369-
pm_runtime_use_autosuspend(&pdev->dev);
370-
pm_runtime_set_active(&pdev->dev);
371-
pm_runtime_enable(&pdev->dev);
372-
}
373+
/* The code below assumes runtime PM to be disabled. */
374+
WARN_ON(pm_runtime_enabled(&pdev->dev));
375+
376+
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
377+
pm_runtime_use_autosuspend(&pdev->dev);
378+
pm_runtime_set_active(&pdev->dev);
379+
380+
if (dev->pm_disabled)
381+
pm_runtime_get_noresume(&pdev->dev);
382+
383+
pm_runtime_enable(&pdev->dev);
373384

374385
if (dev->mode == DW_IC_SLAVE)
375386
ret = i2c_dw_probe_slave(dev);
@@ -382,8 +393,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
382393
return ret;
383394

384395
exit_probe:
385-
if (!dev->pm_disabled)
386-
pm_runtime_disable(&pdev->dev);
396+
dw_i2c_plat_pm_cleanup(dev);
387397
exit_reset:
388398
if (!IS_ERR_OR_NULL(dev->rst))
389399
reset_control_assert(dev->rst);
@@ -402,8 +412,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
402412

403413
pm_runtime_dont_use_autosuspend(&pdev->dev);
404414
pm_runtime_put_sync(&pdev->dev);
405-
if (!dev->pm_disabled)
406-
pm_runtime_disable(&pdev->dev);
415+
dw_i2c_plat_pm_cleanup(dev);
416+
407417
if (!IS_ERR_OR_NULL(dev->rst))
408418
reset_control_assert(dev->rst);
409419

0 commit comments

Comments
 (0)