From 06d7f57b55d9373e2de4ba4c62df7cfb46e76c9b Mon Sep 17 00:00:00 2001 From: Akash Asthana Date: Thu, 10 Sep 2020 12:45:14 +0530 Subject: [PATCH] i2c-msm-geni: Register suspend_late instead of suspend_noirq While executing suspend_noirq callbacks non-wakeup interrupts are disabled, wake-up interrupts are enabled but their handling is deferred till the completion of suspend_noirq stage. GENI I2C unvote the resources in the suspend_noirq stage. There is no issue wrt managing clk and pinctrl resources at noirq stage however ICC BW voting can't be done at noirq stage. ICC requests are converted to ack based requested for RPM driver, the ack here is nothing but interrupt from IPCC driver and it can't be processed at noirq stage, hence flow is indefinitely stuck in I2C suspend_noirq callback. This is for platforms using IPCC driver and also it is no harm in making this change applicable to all platforms. Change-Id: I9bf95e1dd990acb6ccc96e5a0ed9850de466a598 Signed-off-by: Akash Asthana --- drivers/i2c/busses/i2c-msm-geni.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-msm-geni.c b/drivers/i2c/busses/i2c-msm-geni.c index 11345b627f99..ad91cbc45e3e 100644 --- a/drivers/i2c/busses/i2c-msm-geni.c +++ b/drivers/i2c/busses/i2c-msm-geni.c @@ -1359,7 +1359,7 @@ static int geni_i2c_remove(struct platform_device *pdev) return 0; } -static int geni_i2c_resume_noirq(struct device *device) +static int geni_i2c_resume_early(struct device *device) { struct geni_i2c_dev *gi2c = dev_get_drvdata(device); @@ -1448,11 +1448,12 @@ static int geni_i2c_runtime_resume(struct device *dev) return 0; } -static int geni_i2c_suspend_noirq(struct device *device) +static int geni_i2c_suspend_late(struct device *device) { struct geni_i2c_dev *gi2c = dev_get_drvdata(device); int ret; + GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); /* Make sure no transactions are pending */ ret = i2c_trylock_bus(&gi2c->adap, I2C_LOCK_SEGMENT); if (!ret) { @@ -1462,7 +1463,7 @@ static int geni_i2c_suspend_noirq(struct device *device) } if (!pm_runtime_status_suspended(device)) { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, - "%s\n", __func__); + "%s: Force suspend\n", __func__); geni_i2c_runtime_suspend(device); pm_runtime_disable(device); pm_runtime_set_suspended(device); @@ -1482,15 +1483,15 @@ static int geni_i2c_runtime_resume(struct device *dev) return 0; } -static int geni_i2c_suspend_noirq(struct device *device) +static int geni_i2c_suspend_late(struct device *device) { return 0; } #endif static const struct dev_pm_ops geni_i2c_pm_ops = { - .suspend_noirq = geni_i2c_suspend_noirq, - .resume_noirq = geni_i2c_resume_noirq, + .suspend_late = geni_i2c_suspend_late, + .resume_early = geni_i2c_resume_early, .runtime_suspend = geni_i2c_runtime_suspend, .runtime_resume = geni_i2c_runtime_resume, };