aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBaolin Wang <baolin.wang@linaro.org>2018-04-09 02:40:54 -0400
committerWolfram Sang <wsa@the-dreams.de>2018-04-27 08:12:17 -0400
commitda33aa03fa34c918faf2c371ebda0dd961d7ccb2 (patch)
treee84cbc68a2d68b3dc2afb61e62e6a9bdc9852173
parent23a27722b5292ef0b27403c87a109feea8296a5c (diff)
i2c: sprd: Prevent i2c accesses after suspend is called
Add one flag to indicate if the i2c controller has been in suspend state, which can prevent i2c accesses after i2c controller is suspended following system suspend. Signed-off-by: Baolin Wang <baolin.wang@linaro.org> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--drivers/i2c/busses/i2c-sprd.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c
index 25fcc3c1e32b..2fdad63a23a1 100644
--- a/drivers/i2c/busses/i2c-sprd.c
+++ b/drivers/i2c/busses/i2c-sprd.c
@@ -86,6 +86,7 @@ struct sprd_i2c {
86 u32 count; 86 u32 count;
87 int irq; 87 int irq;
88 int err; 88 int err;
89 bool is_suspended;
89}; 90};
90 91
91static void sprd_i2c_set_count(struct sprd_i2c *i2c_dev, u32 count) 92static void sprd_i2c_set_count(struct sprd_i2c *i2c_dev, u32 count)
@@ -283,6 +284,9 @@ static int sprd_i2c_master_xfer(struct i2c_adapter *i2c_adap,
283 struct sprd_i2c *i2c_dev = i2c_adap->algo_data; 284 struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
284 int im, ret; 285 int im, ret;
285 286
287 if (i2c_dev->is_suspended)
288 return -EBUSY;
289
286 ret = pm_runtime_get_sync(i2c_dev->dev); 290 ret = pm_runtime_get_sync(i2c_dev->dev);
287 if (ret < 0) 291 if (ret < 0)
288 return ret; 292 return ret;
@@ -586,11 +590,23 @@ static int sprd_i2c_remove(struct platform_device *pdev)
586 590
587static int __maybe_unused sprd_i2c_suspend_noirq(struct device *pdev) 591static int __maybe_unused sprd_i2c_suspend_noirq(struct device *pdev)
588{ 592{
593 struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
594
595 i2c_lock_adapter(&i2c_dev->adap);
596 i2c_dev->is_suspended = true;
597 i2c_unlock_adapter(&i2c_dev->adap);
598
589 return pm_runtime_force_suspend(pdev); 599 return pm_runtime_force_suspend(pdev);
590} 600}
591 601
592static int __maybe_unused sprd_i2c_resume_noirq(struct device *pdev) 602static int __maybe_unused sprd_i2c_resume_noirq(struct device *pdev)
593{ 603{
604 struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
605
606 i2c_lock_adapter(&i2c_dev->adap);
607 i2c_dev->is_suspended = false;
608 i2c_unlock_adapter(&i2c_dev->adap);
609
594 return pm_runtime_force_resume(pdev); 610 return pm_runtime_force_resume(pdev);
595} 611}
596 612