[PATCH v7 1/2] i2c: qcom-geni: Handle runtime PM disabled state during early resume
From: Mukesh Kumar Savaliya
Date: Thu Jul 09 2026 - 10:19:14 EST
During the noirq resume phase, the GENI I2C controller may receive
transfer requests before runtime PM has been fully restored. In this
window pm_runtime_get_sync() can return -EACCES, causing transfers to
fail even though the controller is in the process of resuming.
Treat -EACCES as a transient condition and allow the transfer path to
proceed while preserving existing error handling for other runtime PM
failures.
Also enable runtime PM in the resume_noirq callback when it remains
disabled and allow the controller interrupt to remain active across
system suspend/resume transitions by requesting it with
IRQF_NO_SUSPEND and IRQF_EARLY_RESUME.
These changes prevent spurious transfer failures during early resume
and allow the adapter to become operational before the normal resume
phase completes.
Co-developed-by: Viken Dadhaniya <viken.dadhaniya@xxxxxxxxxxxxxxxx>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@xxxxxxxxxxxxxxxx>
Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@xxxxxxxxxxxxxxxx>
Acked-by: Aniket Randive <aniketrandive@xxxxxxxxxxxxxxxx>
---
drivers/i2c/busses/i2c-qcom-geni.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 96dbf04138be..4bc00922cd97 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -917,6 +917,10 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
gi2c->err = 0;
reinit_completion(&gi2c->done);
ret = pm_runtime_get_sync(gi2c->se.dev);
+ if (ret == -EACCES) {
+ dev_warn(gi2c->se.dev, "Runtime PM is disabled:%d\n", ret);
+ ret = 0;
+ }
if (ret < 0) {
dev_err(gi2c->se.dev, "error turning SE resources:%d\n", ret);
pm_runtime_put_noidle(gi2c->se.dev);
@@ -1115,7 +1119,8 @@ static int geni_i2c_probe(struct platform_device *pdev)
return ret;
/* Keep interrupts disabled initially to allow for low-power modes */
- ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq, IRQF_NO_AUTOEN,
+ ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq,
+ IRQF_NO_AUTOEN | IRQF_NO_SUSPEND | IRQF_EARLY_RESUME,
dev_name(dev), gi2c);
if (ret)
return dev_err_probe(dev, ret,
@@ -1223,7 +1228,12 @@ static int __maybe_unused geni_i2c_resume_noirq(struct device *dev)
if (ret)
return ret;
+ /* Enforced disable_depth = 0 to actually enable runtime PM during noirq phase */
+ if (!pm_runtime_enabled(dev))
+ pm_runtime_enable(dev);
+
i2c_mark_adapter_resumed(&gi2c->adap);
+
return 0;
}
--
2.43.0