On my HiKey board, I'm seeing clk warnings on suspend/resume, which
seem to be caused by runtime pm suspending the device, then the same
suspend hook being called again on suspend time.

Thus this patch adds suspend state tracking to avoid runtime pm and
suspend causing double suspend calls on i2c-designware-platdrv.

Feedback would be greatly appreciated!

Cc: Jarkko Nikula <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: Mika Westerberg <[email protected]>
Cc: Wolfram Sang <[email protected]>
Cc: [email protected]
Signed-off-by: John Stultz <[email protected]>
---
 drivers/i2c/busses/i2c-designware-core.h    | 1 +
 drivers/i2c/busses/i2c-designware-platdrv.c | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/i2c/busses/i2c-designware-core.h 
b/drivers/i2c/busses/i2c-designware-core.h
index 26250b4..386cacb 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -126,6 +126,7 @@ struct dw_i2c_dev {
        void                    (*release_lock)(struct dw_i2c_dev *dev);
        bool                    pm_runtime_disabled;
        bool                    dynamic_tar_update_enabled;
+       bool                    suspended;
 };
 
 #define ACCESS_SWAP            0x00000001
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c 
b/drivers/i2c/busses/i2c-designware-platdrv.c
index 6ce4313..54084fe 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -340,8 +340,12 @@ static int dw_i2c_plat_suspend(struct device *dev)
        struct platform_device *pdev = to_platform_device(dev);
        struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
 
+       if (i_dev->suspended)
+               return 0;
+
        i2c_dw_disable(i_dev);
        i2c_dw_plat_prepare_clk(i_dev, false);
+       i_dev->suspended = true;
 
        return 0;
 }
@@ -351,11 +355,16 @@ 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);
 
+       if (!i_dev->suspended)
+               return 0;
+
        i2c_dw_plat_prepare_clk(i_dev, true);
 
        if (!i_dev->pm_runtime_disabled)
                i2c_dw_init(i_dev);
 
+       i_dev->suspended = false;
+
        return 0;
 }
 
-- 
2.7.4

Reply via email to