mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-07 03:18:31 +00:00
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 <rafael.j.wysocki@intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This commit is contained in:
parent
9e66317d3c
commit
126dbc6b49
1 changed files with 22 additions and 12 deletions
|
@ -249,6 +249,14 @@ static void dw_i2c_set_fifo_size(struct dw_i2c_dev *dev, int id)
|
|||
}
|
||||
}
|
||||
|
||||
static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
|
||||
{
|
||||
pm_runtime_disable(dev->dev);
|
||||
|
||||
if (dev->pm_disabled)
|
||||
pm_runtime_put_noidle(dev->dev);
|
||||
}
|
||||
|
||||
static int dw_i2c_plat_probe(struct platform_device *pdev)
|
||||
{
|
||||
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)
|
|||
ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev));
|
||||
adap->dev.of_node = pdev->dev.of_node;
|
||||
|
||||
if (dev->pm_disabled) {
|
||||
pm_runtime_forbid(&pdev->dev);
|
||||
} else {
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
}
|
||||
/* The code below assumes runtime PM to be disabled. */
|
||||
WARN_ON(pm_runtime_enabled(&pdev->dev));
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
|
||||
if (dev->pm_disabled)
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
if (dev->mode == DW_IC_SLAVE)
|
||||
ret = i2c_dw_probe_slave(dev);
|
||||
|
@ -382,8 +393,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
|
||||
exit_probe:
|
||||
if (!dev->pm_disabled)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
dw_i2c_plat_pm_cleanup(dev);
|
||||
exit_reset:
|
||||
if (!IS_ERR_OR_NULL(dev->rst))
|
||||
reset_control_assert(dev->rst);
|
||||
|
@ -402,8 +412,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
|
|||
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
if (!dev->pm_disabled)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
dw_i2c_plat_pm_cleanup(dev);
|
||||
|
||||
if (!IS_ERR_OR_NULL(dev->rst))
|
||||
reset_control_assert(dev->rst);
|
||||
|
||||
|
|
Loading…
Reference in a new issue