qcacld-3.0: Migrate psoc transitions to hdd_psoc_sync

With the recent addition of hdd_psoc_sync APIs, DSC use is abstracted
behind a common interface for PSOCs. Begin migrating HDD to the new
interface by updating PSOC transitions to use the new APIs.

Change-Id: Ia9102d906dc0c699719a05726b47def7a00e925c
CRs-Fixed: 2392091
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index c38011a..7ced6de 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1598,25 +1598,6 @@
 
 struct hdd_driver *hdd_driver_get(void);
 
-enum hdd_psoc_state {
-	psoc_state_uninit,
-	psoc_state_deinit,
-	psoc_state_active, /* historically "ENABLED" */
-	psoc_state_idle, /* historically "CLOSED" */
-};
-
-/**
- * struct hdd_psoc - HDD psoc-level context information
- * @hdd_driver: pointer to parent HDD driver context
- * @dsc_psoc: driver synchronization psoc context handle
- * @state: the current stable state of the psoc
- */
-struct hdd_psoc {
-	struct hdd_driver *hdd_driver;
-	struct dsc_psoc *dsc_psoc;
-	enum hdd_psoc_state state;
-};
-
 /**
  * struct hdd_dynamic_mac - hdd structure to handle dynamic mac address changes
  * @dynamic_mac: Dynamicaly configured mac, this contains the mac on which
@@ -1635,7 +1616,6 @@
 
 /**
  * struct hdd_context - hdd shared driver and psoc/device context
- * @hdd_psoc: hdd psoc context
  * @psoc: object manager psoc context
  * @pdev: object manager pdev context
  * @g_event_flags: a bitmap of hdd_driver_flags
@@ -1643,7 +1623,6 @@
  * @dynamic_nss_chains_support: Per vdev dynamic nss chains update capability
  */
 struct hdd_context {
-	struct hdd_psoc *hdd_psoc;
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_objmgr_pdev *pdev;
 	mac_handle_t mac_handle;
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index a187ba5..f1bc796 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -26,6 +26,7 @@
 #include "hif.h"
 #include "htc.h"
 #include "epping_main.h"
+#include "wlan_hdd_dsc.h"
 #include "wlan_hdd_main.h"
 #include "wlan_hdd_power.h"
 #include "wlan_logging_sock_svc.h"
@@ -356,56 +357,6 @@
 }
 #endif
 
-static QDF_STATUS hdd_psoc_ctx_create(struct hdd_psoc **out_hdd_psoc)
-{
-	QDF_STATUS status;
-	struct hdd_driver *hdd_driver = hdd_driver_get();
-	struct hdd_psoc *hdd_psoc;
-
-	QDF_BUG(out_hdd_psoc);
-	if (!out_hdd_psoc)
-		return QDF_STATUS_E_INVAL;
-
-	hdd_psoc = qdf_mem_malloc(sizeof(*hdd_psoc));
-	if (!hdd_psoc)
-		return QDF_STATUS_E_NOMEM;
-
-	hdd_psoc->hdd_driver = hdd_driver;
-	hdd_psoc->state = psoc_state_uninit;
-
-	status = dsc_psoc_create(hdd_driver->dsc_driver, &hdd_psoc->dsc_psoc);
-	if (QDF_IS_STATUS_ERROR(status))
-		goto free_ctx;
-
-	*out_hdd_psoc = hdd_psoc;
-
-	return QDF_STATUS_SUCCESS;
-
-free_ctx:
-	qdf_mem_free(hdd_psoc);
-
-	return status;
-}
-
-static void hdd_psoc_ctx_destroy(struct hdd_psoc **out_hdd_psoc)
-{
-	struct hdd_psoc *hdd_psoc;
-
-	QDF_BUG(out_hdd_psoc);
-	if (!out_hdd_psoc)
-		return;
-
-	hdd_psoc = *out_hdd_psoc;
-	QDF_BUG(hdd_psoc);
-	if (!hdd_psoc)
-		return;
-
-	*out_hdd_psoc = NULL;
-
-	dsc_psoc_destroy(&hdd_psoc->dsc_psoc);
-	qdf_mem_free(hdd_psoc);
-}
-
 static void hdd_soc_load_lock(struct device *dev, int load_op)
 {
 	mutex_lock(&hdd_init_deinit_lock);
@@ -422,6 +373,69 @@
 	mutex_unlock(&hdd_init_deinit_lock);
 }
 
+static int __hdd_soc_probe(struct device *dev,
+			   void *bdev,
+			   const struct hif_bus_id *bid,
+			   enum qdf_bus_type bus_type)
+{
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	int errno;
+
+	hdd_info("probing driver");
+
+	hdd_soc_load_lock(dev, HDD_DRV_OP_PROBE);
+	cds_set_load_in_progress(true);
+	cds_set_driver_in_bad_state(false);
+	cds_set_recovery_in_progress(false);
+
+	errno = hdd_init_qdf_ctx(dev, bdev, bus_type, bid);
+	if (errno)
+		goto unlock;
+
+	hdd_ctx = hdd_context_create(dev);
+	if (IS_ERR(hdd_ctx)) {
+		errno = PTR_ERR(hdd_ctx);
+		goto assert_fail_count;
+	}
+
+	errno = hdd_wlan_startup(hdd_ctx);
+	if (errno)
+		goto hdd_context_destroy;
+
+	status = hdd_psoc_create_vdevs(hdd_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errno = qdf_status_to_os_return(status);
+		goto wlan_exit;
+	}
+
+	probe_fail_cnt = 0;
+	cds_set_driver_loaded(true);
+	cds_set_load_in_progress(false);
+	hdd_start_complete(0);
+
+	hdd_soc_load_unlock(dev);
+
+	return 0;
+
+wlan_exit:
+	hdd_wlan_exit(hdd_ctx);
+
+hdd_context_destroy:
+	hdd_context_destroy(hdd_ctx);
+
+assert_fail_count:
+	probe_fail_cnt++;
+	hdd_err("consecutive probe failures:%u", probe_fail_cnt);
+	QDF_BUG(probe_fail_cnt < SSR_MAX_FAIL_CNT);
+
+unlock:
+	cds_set_load_in_progress(false);
+	hdd_soc_load_unlock(dev);
+
+	return check_for_probe_defer(errno);
+}
+
 /**
  * hdd_soc_probe() - perform SoC probe
  * @dev: kernel device being probed
@@ -439,88 +453,72 @@
 			 const struct hif_bus_id *bid,
 			 enum qdf_bus_type bus_type)
 {
-	struct hdd_context *hdd_ctx;
-	struct hdd_psoc *hdd_psoc;
-	QDF_STATUS status;
+	struct dsc_driver *dsc_driver = hdd_driver_get()->dsc_driver;
+	struct hdd_psoc_sync *psoc_sync;
 	int errno;
 
 	hdd_info("probing driver");
 
-	status = hdd_psoc_ctx_create(&hdd_psoc);
-	if (QDF_IS_STATUS_ERROR(status))
-		return qdf_status_to_os_return(status);
+	errno = hdd_psoc_sync_create_with_trans(dsc_driver, &psoc_sync);
+	if (errno)
+		return errno;
 
-	status = dsc_psoc_trans_start(hdd_psoc->dsc_psoc, "probe");
-	if (QDF_IS_STATUS_ERROR(status)) {
-		hdd_err("Failed to start transition; probe, status:%u", status);
-		errno = qdf_status_to_os_return(status);
-		goto free_psoc;
-	}
+	hdd_psoc_sync_register(dev, psoc_sync);
+	errno = __hdd_soc_probe(dev, bdev, bid, bus_type);
+	if (errno)
+		goto destroy_sync;
 
-	hdd_soc_load_lock(dev, HDD_DRV_OP_PROBE);
-	cds_set_load_in_progress(true);
+	hdd_psoc_sync_trans_stop(psoc_sync);
+
+	return 0;
+
+destroy_sync:
+	hdd_psoc_sync_unregister(dev);
+	hdd_psoc_sync_wait_for_ops(psoc_sync);
+
+	hdd_psoc_sync_trans_stop(psoc_sync);
+	hdd_psoc_sync_destroy(psoc_sync);
+
+	return errno;
+}
+
+static int __hdd_soc_recovery_reinit(struct device *dev,
+				     void *bdev,
+				     const struct hif_bus_id *bid,
+				     enum qdf_bus_type bus_type)
+{
+	int errno;
+
+	hdd_info("re-probing driver");
+
+	hdd_soc_load_lock(dev, HDD_DRV_OP_REINIT);
 	cds_set_driver_in_bad_state(false);
 
-	/*
-	 * Set Recovery in progress flag to flase
-	 * as probe is started which ensures that FW is ready
-	 */
-	cds_set_recovery_in_progress(false);
-
 	errno = hdd_init_qdf_ctx(dev, bdev, bus_type, bid);
 	if (errno)
 		goto unlock;
 
-	hdd_ctx = hdd_context_create(dev);
-	if (IS_ERR(hdd_ctx)) {
-		errno = PTR_ERR(hdd_ctx);
+	errno = hdd_wlan_re_init();
+	if (errno) {
+		re_init_fail_cnt++;
 		goto assert_fail_count;
 	}
 
-	hdd_ctx->hdd_psoc = hdd_psoc;
-
-	errno = hdd_wlan_startup(hdd_ctx);
-	if (errno)
-		goto hdd_context_destroy;
-
-	status = hdd_psoc_create_vdevs(hdd_ctx);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		errno = qdf_status_to_os_return(status);
-		goto wlan_exit;
-	}
-
-	probe_fail_cnt = 0;
-	cds_set_driver_loaded(true);
-	cds_set_load_in_progress(false);
-	hdd_start_complete(0);
+	re_init_fail_cnt = 0;
+	cds_set_recovery_in_progress(false);
 
 	hdd_soc_load_unlock(dev);
 
-	hdd_psoc->state = psoc_state_active;
-	dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
-
 	return 0;
 
-wlan_exit:
-	hdd_wlan_exit(hdd_ctx);
-
-hdd_context_destroy:
-	hdd_context_destroy(hdd_ctx);
-
 assert_fail_count:
-	probe_fail_cnt++;
-	hdd_err("consecutive probe failures:%u", probe_fail_cnt);
-	QDF_BUG(probe_fail_cnt < SSR_MAX_FAIL_CNT);
+	hdd_err("consecutive reinit failures:%u", re_init_fail_cnt);
+	QDF_BUG(re_init_fail_cnt < SSR_MAX_FAIL_CNT);
 
 unlock:
-	cds_set_load_in_progress(false);
+	cds_set_driver_in_bad_state(true);
 	hdd_soc_load_unlock(dev);
 
-	dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
-
-free_psoc:
-	hdd_psoc_ctx_destroy(&hdd_psoc);
-
 	return check_for_probe_defer(errno);
 }
 
@@ -546,81 +544,35 @@
 				   const struct hif_bus_id *bid,
 				   enum qdf_bus_type bus_type)
 {
-	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
-	struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
+	struct hdd_psoc_sync *psoc_sync;
 	int errno;
 
-	hdd_info("re-probing driver");
-
 	/* SSR transition is initiated at the beginning of soc shutdown */
-	dsc_psoc_assert_trans_protected(hdd_psoc->dsc_psoc);
-
-	hdd_soc_load_lock(dev, HDD_DRV_OP_REINIT);
-	cds_set_driver_in_bad_state(false);
-
-	errno = hdd_init_qdf_ctx(dev, bdev, bus_type, bid);
+	errno = hdd_psoc_sync_trans_resume(dev, &psoc_sync);
+	QDF_BUG(!errno);
 	if (errno)
-		goto unlock;
+		return errno;
 
-	errno = hdd_wlan_re_init();
-	if (errno) {
-		re_init_fail_cnt++;
-		goto assert_fail_count;
-	}
+	errno = __hdd_soc_recovery_reinit(dev, bdev, bid, bus_type);
+	if (errno)
+		return errno;
 
-	re_init_fail_cnt = 0;
-	cds_set_recovery_in_progress(false);
-
-	hdd_soc_load_unlock(dev);
-
-	dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
+	hdd_psoc_sync_trans_stop(psoc_sync);
 
 	return 0;
-
-assert_fail_count:
-	hdd_err("consecutive reinit failures:%u", re_init_fail_cnt);
-	QDF_BUG(re_init_fail_cnt < SSR_MAX_FAIL_CNT);
-
-unlock:
-	cds_set_driver_in_bad_state(true);
-	hdd_soc_load_unlock(dev);
-
-	return check_for_probe_defer(errno);
 }
 
-/**
- * hdd_soc_remove() - perform SoC remove
- * @dev: the kernel device being removed
- *
- * A SoC remove indicates the attached SoC hardware is about to go away and
- * needs to be cleaned up.
- *
- * Return: void
- */
-static void hdd_soc_remove(struct device *dev)
+static void __hdd_soc_remove(struct device *dev)
 {
 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
-	struct hdd_psoc *hdd_psoc;
-	QDF_STATUS status;
 
-	if (!hdd_ctx) {
-		hdd_warn_rl("previous probe was not successful");
+	QDF_BUG(hdd_ctx);
+	if (!hdd_ctx)
 		return;
-	}
 
 	pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME,
 		QWLAN_VERSIONSTR);
 
-	hdd_psoc = hdd_ctx->hdd_psoc;
-	status = dsc_psoc_trans_start_wait(hdd_psoc->dsc_psoc, "remove");
-	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
-	if (QDF_IS_STATUS_ERROR(status)) {
-		hdd_err("Failed to remove WLAN SoC; status:%d", status);
-		return;
-	}
-
-	dsc_psoc_wait_for_ops(hdd_psoc->dsc_psoc);
-
 	cds_set_driver_loaded(false);
 	cds_set_unload_in_progress(true);
 
@@ -645,14 +597,37 @@
 	cds_set_driver_in_bad_state(false);
 	cds_set_unload_in_progress(false);
 
-	hdd_psoc->state = psoc_state_deinit;
-	dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
-
-	hdd_psoc_ctx_destroy(&hdd_psoc);
-
 	pr_info("%s: Driver De-initialized\n", WLAN_MODULE_NAME);
 }
 
+/**
+ * hdd_soc_remove() - perform SoC remove
+ * @dev: the kernel device being removed
+ *
+ * A SoC remove indicates the attached SoC hardware is about to go away and
+ * needs to be cleaned up.
+ *
+ * Return: void
+ */
+static void hdd_soc_remove(struct device *dev)
+{
+	struct hdd_psoc_sync *psoc_sync;
+	int errno;
+
+	/* by design, this will fail to lookup if we never probed the SoC */
+	errno = hdd_psoc_sync_trans_start_wait(dev, &psoc_sync);
+	if (errno)
+		return;
+
+	hdd_psoc_sync_unregister(dev);
+	hdd_psoc_sync_wait_for_ops(psoc_sync);
+
+	__hdd_soc_remove(dev);
+
+	hdd_psoc_sync_trans_stop(psoc_sync);
+	hdd_psoc_sync_destroy(psoc_sync);
+}
+
 #ifdef FEATURE_WLAN_DIAG_SUPPORT
 /**
  * hdd_wlan_ssr_shutdown_event()- send ssr shutdown state
@@ -723,24 +698,9 @@
 	hdd_send_hang_reason();
 }
 
-/**
- * hdd_soc_recovery_shutdown() - perform PDR/SSR SoC shutdown
- *
- * When communication with firmware breaks down, a SoC recovery process kicks in
- * with two phases: shutdown and reinit.
- *
- * SSR shutdown is similar to a 'remove' but without communication with
- * firmware. The idea is to retain as much SoC configuration as possible, so it
- * can be re-initialized to the same state after a reset. This is completely
- * transparent from a userspace point of view.
- *
- * Return: void
- */
-static void hdd_soc_recovery_shutdown(void)
+static void __hdd_soc_recovery_shutdown(void)
 {
 	struct hdd_context *hdd_ctx;
-	struct hdd_psoc *hdd_psoc;
-	QDF_STATUS status;
 	void *hif_ctx;
 
 	/* recovery starts via firmware down indication; ensure we got one */
@@ -755,16 +715,6 @@
 	/* cancel/flush any pending/active idle shutdown work */
 	hdd_psoc_idle_timer_stop(hdd_ctx);
 
-	hdd_psoc = hdd_ctx->hdd_psoc;
-	status = dsc_psoc_trans_start_wait(hdd_psoc->dsc_psoc, "ssr");
-	if (QDF_IS_STATUS_ERROR(status)) {
-		/* If SSR races with e.g. Remove, aborting SSR is expected */
-		hdd_info("Aborting SSR; status:%u", status);
-		return;
-	}
-
-	dsc_psoc_wait_for_ops(hdd_psoc->dsc_psoc);
-
 	mutex_lock(&hdd_init_deinit_lock);
 	hdd_start_driver_ops_timer(HDD_DRV_OP_SHUTDOWN);
 
@@ -804,13 +754,40 @@
 	hdd_stop_driver_ops_timer();
 	mutex_unlock(&hdd_init_deinit_lock);
 
-	/* SSR transition is concluded at the end of soc re-init */
-
 	return;
 
 unlock:
 	hdd_stop_driver_ops_timer();
 	mutex_unlock(&hdd_init_deinit_lock);
+}
+
+/**
+ * hdd_soc_recovery_shutdown() - perform PDR/SSR SoC shutdown
+ * @dev: the device to shutdown
+ *
+ * When communication with firmware breaks down, a SoC recovery process kicks in
+ * with two phases: shutdown and reinit.
+ *
+ * SSR shutdown is similar to a 'remove' but without communication with
+ * firmware. The idea is to retain as much SoC configuration as possible, so it
+ * can be re-initialized to the same state after a reset. This is completely
+ * transparent from a userspace point of view.
+ *
+ * Return: void
+ */
+static void hdd_soc_recovery_shutdown(struct device *dev)
+{
+	struct hdd_psoc_sync *psoc_sync;
+	int errno;
+
+	errno = hdd_psoc_sync_trans_start_wait(dev, &psoc_sync);
+	QDF_BUG(!errno);
+	if (errno)
+		return;
+
+	hdd_psoc_sync_wait_for_ops(psoc_sync);
+
+	__hdd_soc_recovery_shutdown();
 
 	/* SSR transition is concluded at the end of soc re-init */
 }
@@ -1523,7 +1500,7 @@
 {
 	hdd_enter();
 
-	hdd_soc_recovery_shutdown();
+	hdd_soc_recovery_shutdown(dev);
 
 	hdd_exit();
 }
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 51cd2f0..2459acb 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -9268,37 +9268,32 @@
  */
 static void hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
 {
-	struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
-	QDF_STATUS status;
+	struct hdd_psoc_sync *psoc_sync;
+	int errno;
 
 	hdd_enter();
 
-	status = dsc_psoc_trans_start(hdd_psoc->dsc_psoc, "idle shutdown");
-	if (QDF_IS_STATUS_ERROR(status)) {
-		hdd_info("psoc busy, abort idle shutdown; status:%u", status);
-		return;
+	errno = hdd_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync);
+	if (errno) {
+		hdd_info("psoc busy, abort idle shutdown; errno:%d", errno);
+		goto exit;
 	}
 
+	hdd_psoc_sync_wait_for_ops(psoc_sync);
+
 	QDF_BUG(!hdd_wlan_stop_modules(hdd_ctx, false));
 
-	hdd_psoc->state = psoc_state_idle;
-	dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
+	hdd_psoc_sync_trans_stop(psoc_sync);
 
+exit:
 	hdd_exit();
 }
 
 int hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
 {
-	struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
-	int errno;
-
 	QDF_BUG(rtnl_is_locked());
 
-	errno = hdd_wlan_start_modules(hdd_ctx, false);
-	if (!errno)
-		hdd_psoc->state = psoc_state_active;
-
-	return errno;
+	return hdd_wlan_start_modules(hdd_ctx, false);
 }
 
 /**
@@ -11645,7 +11640,6 @@
 	int errno;
 
 	QDF_BUG(rtnl_is_locked());
-	dsc_psoc_assert_trans_protected(hdd_ctx->hdd_psoc->dsc_psoc);
 
 	errno = hdd_vdev_sync_create(hdd_ctx->wiphy, &vdev_sync);
 	if (errno)