Procházet zdrojové kódy

qcacld-3.0: RTPM sync lock for system suspend and resume

If driver SSR has happened after system suspend then RTPM lock
acquired during system suspend is not getting released which
leads to mismatch in RTPM reference count.

Use RTPM prevent suspend sync API to ensure system is in
resume state before acquiring RTPM prevent suspend lock
and in the driver SSR sequence, call to RTPM lock deinit
cleans up any acquired lock.

Change-Id: Icf1d564aa74d9c081a71fe173895e4d29b95c90b
CRs-Fixed: 3254539
Vinod Kumar Pirla před 2 roky
rodič
revize
3364ad4472

+ 2 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -923,6 +923,7 @@ struct hdd_chan_change_params {
  * @is_user_wakelock_acquired: boolean to check if user wakelock status
  * @monitor_mode: monitor mode context to prevent/allow runtime pm
  * @wow_unit_test: wow unit test mode context to prevent/allow runtime pm
+ * @system_suspend: system suspend context to prevent/allow runtime pm
  *
  * Runtime PM control for underlying activities
  */
@@ -933,6 +934,7 @@ struct hdd_runtime_pm_context {
 	bool is_user_wakelock_acquired;
 	qdf_runtime_lock_t monitor_mode;
 	qdf_runtime_lock_t wow_unit_test;
+	qdf_runtime_lock_t system_suspend;
 };
 
 /*

+ 2 - 0
core/hdd/src/wlan_hdd_main.c

@@ -1225,6 +1225,7 @@ static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
 	qdf_runtime_lock_init(&ctx->user);
 	qdf_runtime_lock_init(&ctx->monitor_mode);
 	qdf_runtime_lock_init(&ctx->wow_unit_test);
+	qdf_runtime_lock_init(&ctx->system_suspend);
 
 	qdf_rtpm_register(QDF_RTPM_ID_WIPHY_SUSPEND, NULL);
 	qdf_rtpm_register(QDF_RTPM_ID_PM_QOS_NOTIFY, NULL);
@@ -1252,6 +1253,7 @@ static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
 	qdf_runtime_lock_deinit(&ctx->user);
 	qdf_runtime_lock_deinit(&ctx->connect);
 	qdf_runtime_lock_deinit(&ctx->dfs);
+	qdf_runtime_lock_deinit(&ctx->system_suspend);
 
 	qdf_rtpm_deregister(QDF_RTPM_ID_WIPHY_SUSPEND);
 	qdf_rtpm_deregister(QDF_RTPM_ID_PM_QOS_NOTIFY);

+ 9 - 4
core/hdd/src/wlan_hdd_power.c

@@ -2353,10 +2353,9 @@ exit_with_code:
 static int _wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
 {
 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	qdf_runtime_lock_t *suspend_lock;
 	int errno;
 
-	qdf_rtpm_put(QDF_RTPM_PUT, QDF_RTPM_ID_WIPHY_SUSPEND);
-
 	if (!hdd_ctx) {
 		hdd_err_rl("hdd context is null");
 		return -ENODEV;
@@ -2372,6 +2371,10 @@ static int _wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
 	if (errno)
 		return errno;
 
+	suspend_lock = &hdd_ctx->runtime_context.system_suspend;
+	errno = qdf_runtime_pm_allow_suspend(suspend_lock);
+	if (errno)
+		return errno;
 
 	errno = __wlan_hdd_cfg80211_resume_wlan(wiphy);
 
@@ -2689,6 +2692,7 @@ static int _wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
 {
 	void *hif_ctx;
 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	qdf_runtime_lock_t *suspend_lock;
 	int errno;
 
 	if (!hdd_ctx) {
@@ -2714,13 +2718,14 @@ static int _wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
 	if (!hif_ctx)
 		return -EINVAL;
 
-	errno = qdf_rtpm_get(QDF_RTPM_GET_SYNC, QDF_RTPM_ID_WIPHY_SUSPEND);
+	suspend_lock = &hdd_ctx->runtime_context.system_suspend;
+	errno = qdf_runtime_pm_prevent_suspend_sync(suspend_lock);
 	if (errno)
 		return errno;
 
 	errno = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
 	if (errno) {
-		qdf_rtpm_put(QDF_RTPM_PUT, QDF_RTPM_ID_WIPHY_SUSPEND);
+		qdf_runtime_pm_allow_suspend(suspend_lock);
 		return errno;
 	}