summaryrefslogtreecommitdiff
path: root/drivers/i2c/busses/i2c-designware-platdrv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-platdrv.c')
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c104
1 files changed, 52 insertions, 52 deletions
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 9e094478b9b3..a2ae2213ef3e 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -209,17 +209,16 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
dev->clk = devm_clk_get(&pdev->dev, NULL);
- if (!IS_ERR(dev->clk)) {
- r = clk_prepare_enable(dev->clk);
- if (r)
- return r;
+ dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
+ if (IS_ERR(dev->clk))
+ return PTR_ERR(dev->clk);
+ clk_prepare_enable(dev->clk);
- dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
+ if (!dev->sda_hold_time && ht) {
+ u32 ic_clk = dev->get_clk_rate_khz(dev);
- if (!dev->sda_hold_time && ht)
- dev->sda_hold_time = div_u64(
- (u64)dev->get_clk_rate_khz(dev) * ht + 500000,
- 1000000);
+ dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
+ 1000000);
}
if (!dev->tx_fifo_depth) {
@@ -236,26 +235,18 @@ 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;
- pm_runtime_get_noresume(&pdev->dev);
- 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);
-
- if (dev->pm_runtime_disabled)
- pm_runtime_get_noresume(&pdev->dev);
+ if (dev->pm_runtime_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);
+ }
r = i2c_dw_probe(dev);
- if (r) {
- if (!IS_ERR(dev->clk))
- clk_disable_unprepare(dev->clk);
+ if (r && !dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev);
- pm_runtime_dont_use_autosuspend(&pdev->dev);
- if (dev->pm_runtime_disabled)
- pm_runtime_put_noidle(&pdev->dev);
- }
- pm_runtime_mark_last_busy(&pdev->dev);
- pm_runtime_put(&pdev->dev);
return r;
}
@@ -270,16 +261,10 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
i2c_dw_disable(dev);
- if (!IS_ERR(dev->clk))
- clk_disable_unprepare(dev->clk);
-
- pm_runtime_disable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
- if (dev->pm_runtime_disabled)
- pm_runtime_put_noidle(&pdev->dev);
-
- pm_runtime_put_noidle(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_put_sync(&pdev->dev);
+ if (!dev->pm_runtime_disabled)
+ pm_runtime_disable(&pdev->dev);
return 0;
}
@@ -292,47 +277,62 @@ static const struct of_device_id dw_i2c_of_match[] = {
MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
#endif
-#ifdef CONFIG_PM
-static int i2c_dw_plat_prepare_clk(struct dw_i2c_dev *i_dev, bool prepare)
+#ifdef CONFIG_PM_SLEEP
+static int dw_i2c_plat_prepare(struct device *dev)
{
- if (IS_ERR(i_dev->clk))
- return PTR_ERR(i_dev->clk);
-
- if (prepare)
- return clk_prepare_enable(i_dev->clk);
+ return pm_runtime_suspended(dev);
+}
- clk_disable_unprepare(i_dev->clk);
- return 0;
+static void dw_i2c_plat_complete(struct device *dev)
+{
+ if (dev->power.direct_complete)
+ pm_request_resume(dev);
}
+#else
+#define dw_i2c_plat_prepare NULL
+#define dw_i2c_plat_complete NULL
+#endif
+#ifdef CONFIG_PM
static int dw_i2c_plat_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
i2c_dw_disable(i_dev);
- i2c_dw_plat_prepare_clk(i_dev, false);
+ clk_disable_unprepare(i_dev->clk);
return 0;
}
-static int dw_i2c_plat_runtime_resume(struct device *dev)
+static int dw_i2c_plat_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
- i2c_dw_plat_prepare_clk(i_dev, true);
- i2c_dw_init(i_dev);
+ clk_prepare_enable(i_dev->clk);
+
+ if (!i_dev->pm_runtime_disabled)
+ i2c_dw_init(i_dev);
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int dw_i2c_plat_suspend(struct device *dev)
+{
+ pm_runtime_resume(dev);
+ return dw_i2c_plat_runtime_suspend(dev);
+}
+#endif
+
static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
- pm_runtime_force_resume)
+ .prepare = dw_i2c_plat_prepare,
+ .complete = dw_i2c_plat_complete,
+ SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend,
- dw_i2c_plat_runtime_resume,
- NULL)
+ dw_i2c_plat_resume,
+ NULL)
};
#define DW_I2C_DEV_PMOPS (&dw_i2c_dev_pm_ops)