Browse Source

qcacld-3.0: Add a condition to check for PM QOS vote

In the case of kernel 5.10, we are not receiving PM QoS Vote
notification due to which device is entering runtime suspend
in the case where the device should not enter runtime suspend.
Adding check inside runtime suspend to check if there is any
global PM QoS vote and based upon vote decide if to enter runtime
suspend or not.

Change-Id: Ie6d35254d607e546abdd3ad70720f96d6eb8484d
CRs-Fixed: 3009024
Amit Mehta 3 years ago
parent
commit
001a2e78de
3 changed files with 45 additions and 0 deletions
  1. 17 0
      core/hdd/inc/wlan_hdd_power.h
  2. 5 0
      core/hdd/src/wlan_hdd_driver_ops.c
  3. 23 0
      core/hdd/src/wlan_hdd_power.c

+ 17 - 0
core/hdd/inc/wlan_hdd_power.h

@@ -435,6 +435,23 @@ int wlan_hdd_ipv4_changed(struct notifier_block *nb,
  */
 int wlan_hdd_pm_qos_notify(struct notifier_block *nb, unsigned long curr_val,
 			   void *context);
+
+/**
+ * wlan_hdd_is_cpu_pm_qos_in_progress() - WLAN HDD PM QoS Status Function
+ *
+ * This function check for PM QoS global vote.
+ *
+ * Return: true if there is PM QoS global vote,
+ *	   or an false otherwise
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
+bool wlan_hdd_is_cpu_pm_qos_in_progress(void);
+#else
+static inline bool wlan_hdd_is_cpu_pm_qos_in_progress(void)
+{
+	return false;
+}
+#endif
 #endif
 /**
  * wlan_hdd_ipv6_changed() - IPv6 change notifier callback

+ 5 - 0
core/hdd/src/wlan_hdd_driver_ops.c

@@ -1622,6 +1622,11 @@ static int wlan_hdd_runtime_suspend(struct device *dev)
 		return -EBUSY;
 	}
 
+	if (wlan_hdd_is_cpu_pm_qos_in_progress()) {
+		hdd_debug("PM QoS Latency constraint, ignore runtime suspend");
+		return -EBUSY;
+	}
+
 	status = ucfg_pmo_psoc_bus_runtime_suspend(hdd_ctx->psoc,
 						   hdd_pld_runtime_suspend_cb);
 	err = qdf_status_to_os_return(status);

+ 23 - 0
core/hdd/src/wlan_hdd_power.c

@@ -87,6 +87,7 @@
 #include "wlan_hdd_object_manager.h"
 #include <linux/igmp.h>
 #include "qdf_types.h"
+#include <linux/cpuidle.h>
 /* Preprocessor definitions and constants */
 #ifdef QCA_WIFI_EMULATION
 #define HDD_SSR_BRING_UP_TIME 3000000
@@ -1211,6 +1212,28 @@ int wlan_hdd_pm_qos_notify(struct notifier_block *nb, unsigned long curr_val,
 
 	return NOTIFY_DONE;
 }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
+bool wlan_hdd_is_cpu_pm_qos_in_progress(void)
+{
+	unsigned long pm_qos_cpu_latency;
+	long long curr_val;
+	int max_cpu_num;
+
+	max_cpu_num  = nr_cpu_ids - 1;
+	pm_qos_cpu_latency = wlan_hdd_get_pm_qos_cpu_latency() * NSEC_PER_USEC;
+
+	/* Get PM QoS vote from last cpu, as no device votes on that cpu
+	 * so by default we get global PM QoS vote from last cpu.
+	 */
+	curr_val = cpuidle_governor_latency_req(max_cpu_num);
+	if (curr_val != pm_qos_cpu_latency) {
+		hdd_debug("PM QoS current value: %lld", curr_val);
+		return true;
+	}
+	return false;
+}
+#endif
 #endif
 
 /**