mfd: adnc: added error handling for pm_runtime_get_sync
When the chip crashes in iaxxx_wakeup_chip(), an error will be
returned by iaxxx_wakeup_chip() and fail pm_runtime_get_sync().
The flag dev->power.runtime_error will also be set and block the
following pm_runtime_get_sync() and pm_runtime_put_sync() for firmware
recovery.
When the chip crashes in iaxxx_wakeup_chip(), it will also start
the firmware recovery process. Use pm_runtime_set_active() to
reset runtime_error state and allow the following firmware recovery.
Bug: 158204264
Change-Id: I36c04d33b1033756afb10634ebf58345cedaac2a
Signed-off-by: JJ Lee <leejj@google.com>
diff --git a/drivers/mfd/adnc/iaxxx-pwr-mgmt.c b/drivers/mfd/adnc/iaxxx-pwr-mgmt.c
index 929e37b..3669911 100644
--- a/drivers/mfd/adnc/iaxxx-pwr-mgmt.c
+++ b/drivers/mfd/adnc/iaxxx-pwr-mgmt.c
@@ -113,6 +113,14 @@
if (ret == -EACCES) {
dev_dbg(dev, "%s() runtime PM disabled\n", __func__);
ret = 0;
+ } else if (ret == -EIO || ret == -EINVAL) {
+ /* When the chip crashes and we just triggered recovery
+ * in pm_runtime_get_sync() context, it is expected to
+ * get -EIO or -EINVAL here. Use pm_runtime_set_active
+ * to clear the state of runtime_error.
+ */
+ if (test_bit(IAXXX_FLG_FW_CRASH, &priv->flags))
+ pm_runtime_set_active(priv->dev);
} else
dev_err(dev, "%s() failed %d\n", __func__, ret);
}