Эх сурвалжийг харах

qcacld-3.0: Clean-up module init and exit

In module init, bunch of initializations are done which are not
required till probe call back gets called. Also in module exit,
some clean-up done which should wait till remove call back gets
called. Move the initialization done in module init to probe call back and
clean-up done in module exit to remove call back.

Change-Id: Id4a0cb21300de1ceab8ed043638b735f31d516d4
CRs-fixed: 950170
Prashanth Bhatta 9 жил өмнө
parent
commit
5da711e712

+ 2 - 3
core/cds/inc/cds_api.h

@@ -55,9 +55,8 @@
  */
 #define CDS_WMA_TIMEOUT  (15000)
 
-CDF_STATUS cds_alloc_global_context(v_CONTEXT_t *p_cds_context);
-
-CDF_STATUS cds_free_global_context(v_CONTEXT_t *p_cds_context);
+v_CONTEXT_t cds_init(void);
+void cds_deinit(void);
 
 CDF_STATUS cds_pre_enable(v_CONTEXT_t cds_context);
 

+ 22 - 41
core/cds/src/cds_api.c

@@ -80,70 +80,51 @@ static uint8_t cds_multicast_logging;
 void cds_sys_probe_thread_cback(void *pUserData);
 
 /**
- * cds_alloc_global_context() - allocate CDS global context
- * @p_cds_context: A pointer to where to store the CDS Context
+ * cds_init() - Initialize CDS
  *
- * cds_alloc_global_context() function allocates the CDS global Context,
- * but does not initialize all the members. This overal initialization will
- * happen at cds_open().
+ * This function allocates the resource required for CDS, but does not
+ * initialize all the members. This overall initialization will happen at
+ * cds_open().
  *
- * Return: CDF status
+ * Return: Global context on success and NULL on failure.
  */
-CDF_STATUS cds_alloc_global_context(v_CONTEXT_t *p_cds_context)
+v_CONTEXT_t cds_init(void)
 {
-	if (p_cds_context == NULL)
-		return CDF_STATUS_E_FAILURE;
+	cdf_mc_timer_manager_init();
+	cdf_mem_init();
 
-	/* allocate the CDS Context */
-	*p_cds_context = NULL;
 	gp_cds_context = &g_cds_context;
 
-	cdf_mem_zero(gp_cds_context, sizeof(cds_context_type));
-	*p_cds_context = gp_cds_context;
-
 	gp_cds_context->cdf_ctx = &g_cdf_ctx;
 	cdf_mem_zero(&g_cdf_ctx, sizeof(g_cdf_ctx));
 
-	/* initialize the spinlock */
 	cdf_trace_spin_lock_init();
-	/* it is the right time to initialize MTRACE structures */
+
 #if defined(TRACE_RECORD)
 	cdf_trace_init();
 #endif
-
 	cdf_dp_trace_init();
-	return CDF_STATUS_SUCCESS;
-} /* cds_alloc_global_context() */
+
+	cds_ssr_protect_init();
+
+	return gp_cds_context;
+}
 
 /**
- * cds_free_global_context() - free CDS global context
- * @p_cds_context: A pointer to where the CDS Context was stored
- *
- * cds_free_global_context() function frees the CDS Context.
+ * cds_deinit() - Deinitialize CDS
  *
- * Return: CDF status
+ * This function frees the CDS resources
  */
-CDF_STATUS cds_free_global_context(v_CONTEXT_t *p_cds_context)
+void cds_deinit(void)
 {
-	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
-		  "%s: De-allocating the CDS Context", __func__);
-
-	if ((p_cds_context == NULL) || (*p_cds_context == NULL)) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: vOS Context is Null", __func__);
-		return CDF_STATUS_E_FAILURE;
-	}
+	if (gp_cds_context == NULL)
+		return;
 
-	if (gp_cds_context != *p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: Context mismatch", __func__);
-		return CDF_STATUS_E_FAILURE;
-	}
 	gp_cds_context->cdf_ctx = NULL;
-	*p_cds_context = gp_cds_context = NULL;
+	gp_cds_context = NULL;
 
-	return CDF_STATUS_SUCCESS;
-} /* cds_free_global_context() */
+	return;
+}
 
 #ifdef WLAN_FEATURE_NAN
 /**

+ 3 - 1
core/hdd/inc/wlan_hdd_main.h

@@ -1425,6 +1425,9 @@ static inline void hdd_stop_bus_bw_computer_timer(hdd_adapter_t *pAdapter)
 }
 #endif
 
+int hdd_init(void);
+void hdd_deinit(void);
+
 int hdd_wlan_startup(struct device *dev, void *hif_sc);
 void __hdd_wlan_exit(void);
 int hdd_wlan_notify_modem_power_state(int state);
@@ -1517,7 +1520,6 @@ void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter);
 static inline void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter) {}
 static inline void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter) {}
 #endif
-cdf_wake_lock_t *hdd_wlan_get_wake_lock_ptr(void);
 
 #ifdef QCA_CONFIG_SMP
 int wlan_hdd_get_cpu(void);

+ 160 - 67
core/hdd/src/wlan_hdd_driver_ops.c

@@ -47,6 +47,7 @@
 #include "wma_api.h"
 #include "wlan_hdd_napi.h"
 #include "cds_concurrency.h"
+#include "qwlan_version.h"
 
 #ifdef MODULE
 #define WLAN_MODULE_NAME  module_name(THIS_MODULE)
@@ -72,6 +73,112 @@
 #define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \
 	icnss_unregister_driver(wlan_drv_ops)
 #endif /* HIF_PCI */
+#define DISABLE_KRAIT_IDLE_PS_VAL	200
+
+/*
+ * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
+ * a time, and wait for the completion interrupt to start the next transfer.
+ * During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS).
+ * The delay incurred for resuming from IDLE/SA PS is huge during driver load.
+ * So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency.
+ */
+#ifdef CONFIG_CNSS
+static inline void hdd_request_pm_qos(int val)
+{
+	cnss_request_pm_qos(val);
+}
+
+static inline void hdd_remove_pm_qos(void)
+{
+	cnss_remove_pm_qos();
+}
+#else
+static inline void hdd_request_pm_qos(int val)
+{
+}
+
+static inline void hdd_remove_pm_qos(void)
+{
+}
+#endif
+
+/**
+ * hdd_hif_open() - HIF open helper
+ * @dev: wlan device structure
+ * @bdev: bus device structure
+ * @bid: bus identifier for shared busses
+ * @bus_type: underlying bus type
+ * @reinit: true if we are reinitializing the driver during recovery phase
+ *
+ * This function brings-up HIF layer during load/recovery phase.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid,
+			enum ath_hal_bus_type bus_type, bool reinit)
+{
+	CDF_STATUS status;
+	int ret = 0;
+	void *hif_ctx;
+
+	status = hif_open();
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hif_open error = %d", status);
+		return cdf_status_to_os_return(status);
+	}
+
+	hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
+
+	ret = hdd_napi_create();
+	if (hdd_napi_enabled(HDD_NAPI_ANY)) {
+		hdd_info("hdd_napi_create returned: %d", status);
+		if (ret <= 0) {
+			hdd_err("NAPI creation error, rc: 0x%x, reinit = %d",
+				status, reinit);
+			ret = -EFAULT;
+			goto err_hif_close;
+		}
+	}
+
+	status = hif_enable(hif_ctx, dev, bdev, bid, bus_type,
+			    (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
+			    HIF_ENABLE_TYPE_PROBE);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hif_enable error = %d, reinit = %d",
+			status, reinit);
+		ret = cdf_status_to_os_return(status);
+		goto err_napi_destroy;
+	}
+
+	return 0;
+
+err_napi_destroy:
+	hdd_napi_destroy(true);
+
+err_hif_close:
+	hif_close(hif_ctx);
+
+	return ret;
+
+}
+
+/**
+ * hdd_hif_close() - HIF close helper
+ * @hif_ctx:	HIF context
+ *
+ * Helper function to close HIF
+ */
+static void hdd_hif_close(void *hif_ctx)
+{
+	if (hif_ctx == NULL)
+		return;
+
+	hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
+
+	hdd_napi_destroy(true);
+
+	hif_close(hif_ctx);
+}
 
 /**
  * wlan_hdd_probe() - handles probe request
@@ -91,69 +198,68 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid,
 {
 	void *hif_ctx;
 	CDF_STATUS status;
-	int ret;
+	int ret = 0;
+
+	pr_info("%s: %sprobing driver v%s\n", WLAN_MODULE_NAME,
+		reinit ? "re-" : "", QWLAN_VERSIONSTR);
+
+	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+
+	/*
+	* The Krait is going to Idle/Stand Alone Power Save
+	* more aggressively which is resulting in the longer driver load time.
+	* The Fix is to not allow Krait to enter Idle Power Save during driver
+	* load.
+	*/
+	hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL);
+
+	if (!reinit) {
+		ret = hdd_init();
+
+		if (ret)
+			goto out;
+	}
 
 	if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
 		status = epping_open();
 		if (status != CDF_STATUS_SUCCESS)
-			return status;
+			goto err_hdd_deinit;
 	}
 
-	status = hif_open();
-	if (status != CDF_STATUS_SUCCESS) {
-		hddLog(LOGE, FL("hif_open error = %d"), status);
-		return -EFAULT;
-	}
-	hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
-	if (reinit)
-		hdd_napi_destroy(true);
-	status = hdd_napi_create();
-	if (hdd_napi_enabled(HDD_NAPI_ANY)) {
-		hdd_info("hdd_napi_create returned: %d\n", status);
-		if (status <= 0) {
-			hdd_err("NAPI creation error, rc: 0x%x, reinit = %d",
-			status, reinit);
-			ret = -EFAULT;
-			goto end;
-		}
-	}
+	ret = hdd_hif_open(dev, bdev, bid, bus_type, reinit);
 
-	status = hif_enable(hif_ctx, dev, bdev, bid,
-				bus_type, (reinit == true) ?
-				HIF_ENABLE_TYPE_REINIT : HIF_ENABLE_TYPE_PROBE);
-	if (status != CDF_STATUS_SUCCESS) {
-		hdd_err("hif_enable error = %d, reinit = %d",
-			status, reinit);
-		ret = -EIO;
-		goto end;
-	}
+	if (ret)
+		goto err_epping_close;
+
+	hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
 
 	if (reinit)
 		ret = hdd_wlan_re_init(hif_ctx);
 	else
 		ret = hdd_wlan_startup(dev, hif_ctx);
 
-end:
-	if (ret) {
-		if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
-			hif_pktlogmod_exit(hif_ctx);
-			epping_disable();
-			htc_destroy(cds_get_context(CDF_MODULE_ID_HTC));
-			hif_disable(hif_ctx, (reinit == true) ?
-				HIF_ENABLE_TYPE_REINIT : HIF_ENABLE_TYPE_PROBE);
-			cds_free_context(NULL, CDF_MODULE_ID_HTC, NULL);
-			epping_close();
-		} else {
-			hif_pktlogmod_exit(hif_ctx);
-			__hdd_wlan_exit();
-			hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
-		}
-		hif_close(hif_ctx);
-	}
+	if (ret)
+		goto err_hif_close;
+
 
 	if (reinit)
 		cds_set_logp_in_progress(false);
 
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+	hdd_remove_pm_qos();
+
+	return 0;
+
+err_hif_close:
+	hdd_hif_close(hif_ctx);
+err_epping_close:
+	if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
+		epping_close();
+err_hdd_deinit:
+	hdd_deinit();
+out:
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+	hdd_remove_pm_qos();
 	return ret;
 }
 
@@ -168,38 +274,26 @@ end:
 static void wlan_hdd_remove(void)
 {
 	void *hif_ctx;
-	v_CONTEXT_t p_cds_context = NULL;
 
-	/* Get the global cds context */
-	p_cds_context = cds_get_global_context();
+	pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME,
+		QWLAN_VERSIONSTR);
 
 	hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
 
+	hif_pktlogmod_exit(hif_ctx);
+
 	if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
-		hif_pktlogmod_exit(hif_ctx);
 		epping_disable();
-		htc_destroy(cds_get_context(CDF_MODULE_ID_HTC));
-		hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
-		cds_free_context(NULL, CDF_MODULE_ID_HTC, NULL);
 		epping_close();
 	} else {
-		hif_pktlogmod_exit(hif_ctx);
 		__hdd_wlan_exit();
-		hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
 	}
 
-	hdd_napi_destroy(true);
-	hif_close(hif_ctx);
-
-	cds_free_global_context(&p_cds_context);
+	hdd_hif_close(hif_ctx);
 
-#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
-	wlan_logging_sock_deinit_svc();
-#endif
-
-	cdf_wake_lock_destroy(hdd_wlan_get_wake_lock_ptr());
+	hdd_deinit();
 
-	pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
+	pr_info("%s: Driver Removed\n", WLAN_MODULE_NAME);
 }
 
 /**
@@ -235,8 +329,7 @@ static void wlan_hdd_shutdown(void)
 		hdd_wlan_shutdown();
 	}
 
-	hif_disable(hif_ctx, HIF_DISABLE_TYPE_SHUTDOWN);
-	hif_close(hif_ctx);
+	hdd_hif_close(hif_ctx);
 }
 
 /**

+ 106 - 180
core/hdd/src/wlan_hdd_main.c

@@ -123,7 +123,6 @@ extern int hdd_hostapd_stop(struct net_device *dev);
 #define MEMORY_DEBUG_STR ""
 #endif
 
-#define DISABLE_KRAIT_IDLE_PS_VAL	1
 /* the Android framework expects this param even though we don't use it */
 #define BUF_LEN 20
 static char fwpath_buffer[BUF_LEN];
@@ -3610,10 +3609,18 @@ void __hdd_wlan_exit(void)
 
 	cds_set_load_unload_in_progress(true);
 
+	/* Check IPA HW Pipe shutdown */
+	hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
+
 #ifdef WLAN_FEATURE_LPSS
 	wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
 #endif
 
+	memdump_deinit();
+
+#ifdef QCA_PKT_PROTO_TRACE
+	cds_pkt_proto_trace_close();
+#endif
 	/* Do all the cleanup before deregistering the driver */
 	hdd_wlan_exit(hdd_ctx);
 	EXIT();
@@ -5449,9 +5456,13 @@ ftm_processing:
 	}
 
 	hif_enable_power_gating(hif_sc);
+
+	memdump_init();
+
 	hdd_ctx->isLoadInProgress = false;
 	cds_set_load_unload_in_progress(false);
 	complete(&wlan_start_comp);
+
 	goto success;
 
 err_nl_srv:
@@ -6378,18 +6389,6 @@ end:
 }
 #endif
 
-/**
- * hdd_wlan_get_wake_lock_ptr(): get HDD's wake lock pointer
- *
- * This function returns the wake lock pointer to the caller
- *
- * Return: cdf_wake_lock_t
- */
-cdf_wake_lock_t *hdd_wlan_get_wake_lock_ptr(void)
-{
-	return &wlan_wake_lock;
-}
-
 /**
  * hdd_get_fw_version() - Get FW version
  * @hdd_ctx:     pointer to HDD context.
@@ -6440,85 +6439,52 @@ const char *hdd_get_fwpath(void)
 	return fwpath.string;
 }
 
-/*
- * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
- * a time, and wait for the completion interrupt to start the next transfer.
- * During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS).
- * The delay incurred for resuming from IDLE/SA PS is huge during driver load.
- * So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency.
- */
-
-#ifdef CONFIG_CNSS
-static inline void hdd_request_pm_qos(int val)
-{
-	cnss_request_pm_qos(val);
-}
-
-static inline void hdd_remove_pm_qos(void)
-{
-	cnss_remove_pm_qos();
-}
-#else
-static inline void hdd_request_pm_qos(int val)
-{
-}
-
-static inline void hdd_remove_pm_qos(void)
-{
-}
-#endif
-
 /**
- * hdd_driver_init() - Core Driver Init Function
+ * hdd_init() - Initialize Driver
  *
- * This is the driver entry point - called in different timeline depending
- * on whether the driver is statically or dynamically linked
+ * This function initilizes CDS global context with the help of cds_init. This
+ * has to be the first function called after probe to get a valid global
+ * context.
  *
- * Return: 0 for success, non zero for failure
+ * Return: 0 for success, errno on failure
  */
-static int hdd_driver_init(void)
+int hdd_init(void)
 {
-	CDF_STATUS status;
 	v_CONTEXT_t p_cds_context = NULL;
-	int ret_status = 0;
-	unsigned long rc;
+	int ret = 0;
 
 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
 	wlan_logging_sock_init_svc();
 #endif
+	p_cds_context = cds_init();
 
-	ENTER();
-
-	cdf_wake_lock_init(&wlan_wake_lock, "wlan");
-	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
-	/*
-	* The Krait is going to Idle/Stand Alone Power Save
-	* more aggressively which is resulting in the longer driver load time.
-	* The Fix is to not allow Krait to enter Idle Power Save during driver
-	* load.
-	*/
-	hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL);
-	cds_ssr_protect_init();
-
-	pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
-		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
+	if (p_cds_context == NULL) {
+		hdd_alert("Failed to allocate CDS context");
+		ret = -ENOMEM;
+		goto err_out;
+	}
 
-	do {
-		cdf_mc_timer_manager_init();
-		cdf_mem_init();
-		/* Allocate CDS global context */
-		status = cds_alloc_global_context(&p_cds_context);
+	hdd_trace_init();
 
-		if (!CDF_IS_STATUS_SUCCESS(status)) {
-			hddLog(CDF_TRACE_LEVEL_FATAL,
-			       FL("Failed to preOpen CDS"));
-			ret_status = -1;
-			break;
-		}
+err_out:
+	return ret;
+}
 
-		hdd_trace_init();
+/**
+ * hdd_deinit() - Deinitialize Driver
+ *
+ * This function frees CDS global context with the help of cds_deinit. This
+ * has to be the last function call in remove callback to free the global
+ * context.
+ */
+void hdd_deinit(void)
+{
+	cds_deinit();
 
-		hdd_set_conparam((uint32_t) con_mode);
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+	wlan_logging_sock_deinit_svc();
+#endif
+}
 
 #ifdef QCA_WIFI_3_0_ADRASTEA
 #define HDD_WLAN_START_WAIT_TIME (3600 * 1000)
@@ -6526,54 +6492,64 @@ static int hdd_driver_init(void)
 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
 #endif
 
-		init_completion(&wlan_start_comp);
-		ret_status = wlan_hdd_register_driver();
-		if (!ret_status) {
-			rc = wait_for_completion_timeout(
-				&wlan_start_comp,
-				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
-			if (!rc) {
-				hddLog(LOGP,
-					FL("timed-out waiting for wlan_hdd_register_driver"));
-				ret_status = -1;
-			} else
-				ret_status = 0;
-		}
+/**
+ * __hdd_module_init - Module init helper
+ *
+ * Module init helper function used by both module and static driver.
+ *
+ * Return: 0 for success, errno on failure
+ */
+static int __hdd_module_init(void)
+{
+	int ret = 0;
+	unsigned long rc;
 
-		hdd_remove_pm_qos();
-		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+	pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
+		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
 
-		if (ret_status) {
-			hddLog(LOGP, FL("WLAN Driver Initialization failed"));
-			wlan_hdd_unregister_driver();
-			cds_free_global_context(&p_cds_context);
-			ret_status = -ENODEV;
-			break;
-		} else {
-			pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
-			memdump_init();
-			return 0;
-		}
+	cdf_wake_lock_init(&wlan_wake_lock, "wlan");
 
-	} while (0);
+	hdd_set_conparam((uint32_t) con_mode);
 
-	if (0 != ret_status) {
-		cdf_mc_timer_exit();
-		cdf_mem_exit();
-		cdf_wake_lock_destroy(&wlan_wake_lock);
+	init_completion(&wlan_start_comp);
 
-#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
-		wlan_logging_sock_deinit_svc();
-#endif
-		memdump_deinit();
+	ret = wlan_hdd_register_driver();
+	if (ret) {
 		pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
-	} else {
-		pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
+		goto out;
 	}
 
-	EXIT();
+	rc = wait_for_completion_timeout(&wlan_start_comp,
+			msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
+
+	if (!rc) {
+		hdd_alert("Timed-out waiting for wlan_hdd_register_driver");
+		goto out;
+	}
+
+	pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
+
+	return 0;
+out:
+	cdf_wake_lock_destroy(&wlan_wake_lock);
+	return ret;
+}
 
-	return ret_status;
+/**
+ * __hdd_module_exit - Module exit helper
+ *
+ * Module exit helper function used by both module and static driver.
+ */
+static void __hdd_module_exit(void)
+{
+	pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
+		QWLAN_VERSIONSTR);
+
+	wlan_hdd_unregister_driver();
+
+	cdf_wake_lock_destroy(&wlan_wake_lock);
+
+	return;
 }
 
 /**
@@ -6586,7 +6562,7 @@ static int hdd_driver_init(void)
 #ifdef MODULE
 static int __init hdd_module_init(void)
 {
-	return hdd_driver_init();
+	return __hdd_module_init();
 }
 #else /* #ifdef MODULE */
 static int __init hdd_module_init(void)
@@ -6596,60 +6572,6 @@ static int __init hdd_module_init(void)
 }
 #endif /* #ifdef MODULE */
 
-/**
- * hdd_driver_exit() - Exit function
- *
- * This is the driver exit point (invoked when module is unloaded using rmmod
- * or con_mode was changed by userspace)
- *
- * Return: None
- */
-static void hdd_driver_exit(void)
-{
-	hdd_context_t *hdd_ctx = NULL;
-	int retry = 0;
-
-	pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME,
-		QWLAN_VERSIONSTR);
-
-	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
-	if (!hdd_ctx) {
-		hddLog(CDF_TRACE_LEVEL_FATAL,
-		       FL("module exit called before probe"));
-	} else {
-		/* Check IPA HW Pipe shutdown */
-		hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
-#ifdef QCA_PKT_PROTO_TRACE
-		cds_pkt_proto_trace_close();
-#endif /* QCA_PKT_PROTO_TRACE */
-		while (hdd_ctx->isLogpInProgress ||
-		       cds_is_logp_in_progress()) {
-			hddLog(CDF_TRACE_LEVEL_FATAL,
-			       FL(
-				  "SSR in Progress; block rmmod for 1 second!!!"
-				  ));
-			msleep(1000);
-
-			if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
-				hddLog(CDF_TRACE_LEVEL_FATAL,
-				       FL("SSR never completed, fatal error"));
-				CDF_BUG(0);
-			}
-		}
-
-		rtnl_lock();
-		hdd_ctx->isUnloadInProgress = true;
-		cds_set_load_unload_in_progress(true);
-		rtnl_unlock();
-	}
-
-	cds_wait_for_work_thread_completion(__func__);
-	memdump_deinit();
-
-	wlan_hdd_unregister_driver();
-	return;
-}
-
 /**
  * hdd_module_exit() - Exit function
  *
@@ -6659,7 +6581,7 @@ static void hdd_driver_exit(void)
  */
 static void __exit hdd_module_exit(void)
 {
-	hdd_driver_exit();
+	__hdd_module_exit();
 }
 
 #ifdef MODULE
@@ -6668,6 +6590,7 @@ static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
 	return param_set_copystring(kmessage, kp);
 }
 #else /* #ifdef MODULE */
+
 /**
  * kickstart_driver() - driver entry point
  *
@@ -6681,21 +6604,24 @@ static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
  */
 static int kickstart_driver(void)
 {
-	int ret_status;
+	int ret = 0;
 
 	if (!wlan_hdd_inited) {
-		ret_status = hdd_driver_init();
-		wlan_hdd_inited = ret_status ? 0 : 1;
-		return ret_status;
+		ret = __hdd_module_init();
+		wlan_hdd_inited = ret ? 0 : 1;
+
+		return ret;
 	}
 
-	hdd_driver_exit();
+	__hdd_module_exit();
 
 	msleep(200);
 
-	ret_status = hdd_driver_init();
-	wlan_hdd_inited = ret_status ? 0 : 1;
-	return ret_status;
+	ret = __hdd_module_init();
+
+	wlan_hdd_inited = ret ? 0 : 1;
+
+	return ret;
 }
 
 /**

+ 1 - 0
core/utils/epping/src/epping_main.c

@@ -128,6 +128,7 @@ void epping_disable(void)
 	hif_reset_soc(cds_get_context(CDF_MODULE_ID_HIF));
 	htc_stop(cds_get_context(CDF_MODULE_ID_HTC));
 	epping_cookie_cleanup(pEpping_ctx);
+	htc_destroy(cds_get_context(CDF_MODULE_ID_HTC));
 }
 
 /**