slim_ngd: Rely on pm_runtime resume to put device in active state
Since we use auto-suspend feature of pm_runtime (to avoid thrashing
between low-power and active state of device), it's possible that
device was not put in low power mode by pm_runtime suspend. System
suspend puts the device in low power mode in this case. However, if
pm_runtime's status is set to suspended for the device, we can safely
change system-resume to no-op. Next pm_runtime active request will
then put the device in active state.
If runtime_pm is not supported, then make sure the device becomes
active in first transaction after system-suspend, instead of
system-resume.
Change-Id: I595040572dba7a7a65ba1148803fe6138f0937e3
Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index eb741ef..10c69c3 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -224,6 +224,17 @@
u8 la = txn->la;
u8 wbuf[SLIM_RX_MSGQ_BUF_LEN];
+ if (!pm_runtime_enabled(dev->dev) && dev->state == MSM_CTRL_ASLEEP &&
+ txn->mc != SLIM_USR_MC_REPORT_SATELLITE) {
+ /*
+ * Counter-part of system-suspend when runtime-pm is not enabled
+ * This way, resume can be left empty and device will be put in
+ * active mode only if client requests anything on the bus
+ * If the state was DOWN, SSR UP notification will take
+ * care of putting the device in active state.
+ */
+ ngd_slim_runtime_resume(dev->dev);
+ }
if (txn->mc == (SLIM_MSG_CLK_PAUSE_SEQ_FLG |
SLIM_MSG_MC_RECONFIGURE_NOW)) {
if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) {
@@ -1172,6 +1183,19 @@
if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
dev_dbg(dev, "system suspend");
ret = ngd_slim_runtime_suspend(dev);
+ /*
+ * If runtime-PM still thinks it's active, then make sure its
+ * status is in sync with HW status.
+ * Since this suspend calls QMI api, it results in holding a
+ * wakelock. That results in failure of first suspend.
+ * Subsequent suspend should not call low-power transition
+ * again since the HW is already in suspended state.
+ */
+ if (!ret) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_enable(dev);
+ }
}
if (ret == -EBUSY) {
/*
@@ -1189,18 +1213,11 @@
static int ngd_slim_resume(struct device *dev)
{
- /* If runtime_pm is enabled, this resume shouldn't do anything */
- if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
- int ret;
- dev_dbg(dev, "system resume");
- ret = ngd_slim_runtime_resume(dev);
- if (!ret) {
- pm_runtime_mark_last_busy(dev);
- pm_request_autosuspend(dev);
- }
- return ret;
-
- }
+ /*
+ * Rely on runtime-PM to call resume in case it is enabled.
+ * Even if it's not enabled, rely on 1st client transaction to do
+ * clock/power on
+ */
return 0;
}
#endif /* CONFIG_PM_SLEEP */