ソースを参照

qcacmn: Cancel runtime suspend if acquired wakelock

Issue happens when
step 1: kernel pm core start to runtime suspend
step 2: host get wma_acquire_wakelock & send PDEV_SET_HW_MODE.
step 3: host send wow_enable cmd
step 4: wow suspend finished and wow resume happens as step2
	send pm_runtime_get
step 5: fw dop PDEV_SET_HW_MODE as enter wow mode

so host can't get PDEV_SET_HW_MODE_RESP from fw.

Fix is:
   Don't allow suspend if sending PDEV_SET_HW_MODE.

After change logical will be:
   1 if PDEV_SET_HW_MODE before send hif_pre_runtime_suspend->
   hif_runtime_pm_set_state_suspending, then wow suspend
   will return failure.
   2 if PDEV_SET_HW_MODE send after hif_pre_runtime_suspend->
   hif_runtime_pm_set_state_suspending, it will request resume
   and send after wow resume.

Change-Id: I91eea70f841cf9e5d6767f6005eb9662515657a6
CRs-Fixed: 2850561
Jingxiang Ge 4 年 前
コミット
aad342aeb5
1 ファイル変更34 行追加1 行削除
  1. 34 1
      hif/src/hif_runtime_pm.c

+ 34 - 1
hif/src/hif_runtime_pm.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -733,6 +733,31 @@ void hif_process_runtime_suspend_failure(struct hif_opaque_softc *hif_ctx)
 	hif_runtime_pm_set_state_on(scn);
 }
 
+static void hif_pm_runtime_print_prevent_list(struct hif_softc *scn)
+{
+	struct hif_runtime_pm_ctx *rpm_ctx = hif_bus_get_rpm_ctx(scn);
+	struct hif_pm_runtime_lock *ctx;
+
+	hif_info("prevent_suspend_cnt %u", rpm_ctx->prevent_suspend_cnt);
+	list_for_each_entry(ctx, &rpm_ctx->prevent_suspend_list, list)
+		hif_info("%s", ctx->name);
+}
+
+static bool hif_pm_runtime_is_suspend_allowed(struct hif_softc *scn)
+{
+	struct hif_runtime_pm_ctx *rpm_ctx = hif_bus_get_rpm_ctx(scn);
+	bool ret;
+
+	if (!scn->hif_config.enable_runtime_pm)
+		return 0;
+
+	spin_lock_bh(&rpm_ctx->runtime_lock);
+	ret = (rpm_ctx->prevent_suspend_cnt == 0);
+	spin_unlock_bh(&rpm_ctx->runtime_lock);
+
+	return ret;
+}
+
 /**
  * hif_pre_runtime_suspend() - bookkeeping before beginning runtime suspend
  *
@@ -754,6 +779,14 @@ int hif_pre_runtime_suspend(struct hif_opaque_softc *hif_ctx)
 	}
 
 	hif_runtime_pm_set_state_suspending(scn);
+
+	/* keep this after set suspending */
+	if (!hif_pm_runtime_is_suspend_allowed(scn)) {
+		hif_info("Runtime PM not allowed now");
+		hif_pm_runtime_print_prevent_list(scn);
+		return -EINVAL;
+	}
+
 	return 0;
 }