diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-imx.c')
-rw-r--r-- | drivers/i2c/busses/i2c-imx.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 9c1be9378dfd..9a2422a0177a 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -884,10 +884,17 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter, unsigned int i, temp; int result; bool is_lastmsg = false; + bool enable_runtime_pm = false; struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter); dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); + + if (!pm_runtime_enabled(i2c_imx->adapter.dev.parent)) { + pm_runtime_enable(i2c_imx->adapter.dev.parent); + enable_runtime_pm = true; + } + result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent); if (result < 0) goto out; @@ -959,6 +966,9 @@ fail0: pm_runtime_put_autosuspend(i2c_imx->adapter.dev.parent); out: + if (enable_runtime_pm) + pm_runtime_disable(i2c_imx->adapter.dev.parent); + dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__, (result < 0) ? "error" : "success msg", (result < 0) ? result : num); @@ -1100,8 +1110,8 @@ static int i2c_imx_probe(struct platform_device *pdev) } /* Request IRQ */ - ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0, - pdev->name, i2c_imx); + ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, + IRQF_NO_SUSPEND, pdev->name, i2c_imx); if (ret) { dev_err(&pdev->dev, "can't claim irq %d\n", irq); goto clk_disable; @@ -1209,6 +1219,7 @@ static int i2c_imx_runtime_suspend(struct device *dev) struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev); clk_disable_unprepare(i2c_imx->clk); + pinctrl_pm_select_sleep_state(dev); return 0; } @@ -1218,6 +1229,7 @@ static int i2c_imx_runtime_resume(struct device *dev) struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev); int ret; + pinctrl_pm_select_default_state(dev); ret = clk_prepare_enable(i2c_imx->clk); if (ret) dev_err(dev, "can't enable I2C clock, ret=%d\n", ret); @@ -1225,7 +1237,20 @@ static int i2c_imx_runtime_resume(struct device *dev) return ret; } +static int i2c_imx_suspend(struct device *dev) +{ + pinctrl_pm_select_sleep_state(dev); + return 0; +} + +static int i2c_imx_resume(struct device *dev) +{ + pinctrl_pm_select_default_state(dev); + return 0; +} + static const struct dev_pm_ops i2c_imx_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(i2c_imx_suspend, i2c_imx_resume) SET_RUNTIME_PM_OPS(i2c_imx_runtime_suspend, i2c_imx_runtime_resume, NULL) }; |