Bladeren bron

qcacmn: Add PMO runtime suspend and resume support

As part of UMAC componentization add support for PMO
runtime suspend and runtime resume.

Change-Id: Ibd3f640bbf32622f70997863df899d265295a5c6
CRs-Fixed: 2030168
Sravan Kumar Kairam 8 jaren geleden
bovenliggende
commit
cdc362d52f

+ 36 - 0
power_management_offloads/core/inc/wlan_pmo_main.h

@@ -363,6 +363,42 @@ void *pmo_core_psoc_get_htc_handle(struct wlan_objmgr_psoc *psoc)
 	return htc_hdl;
 }
 
+/**
+ * pmo_core_psoc_set_hif_handle() - update psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ * @hif_hdl: hif context handle
+ *
+ * Return: None
+ */
+void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_hdl);
+
+/**
+ * pmo_core_psoc_get_hif_handle() - Get psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: psoc hif layer handle
+ */
+void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_psoc_set_txrx_handle() - update psoc pdev txrx layer handle
+ * @psoc: objmgr psoc handle
+ * @txrx_hdl: pdev txrx context handle
+ *
+ * Return: None
+ */
+void pmo_core_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				   void *txrx_hdl);
+
+/**
+ * pmo_core_psoc_get_txrx_handle() - Get psoc pdev txrx handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: pdev txrx handle
+ */
+void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc);
+
 /**
  * pmo_is_vdev_up() - API to check whether vdev is UP
  * @vdev: objmgr vdev handle

+ 26 - 0
power_management_offloads/core/inc/wlan_pmo_suspend_resume.h

@@ -97,6 +97,32 @@ QDF_STATUS pmo_core_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
 		enum qdf_suspend_type type,
 		struct pmo_wow_enable_params *wow_params);
 
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * pmo_core_psoc_bus_runtime_suspend(): handles bus runtime suspend
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to do link auto suspend
+ *
+ * Suspend the wlan bus without apps suspend.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb);
+
+/**
+ * pmo_core_psoc_bus_runtime_resume(): handles bus runtime resume
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to do link auto resume
+ *
+ * Resume the wlan bus from runtime suspend.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_resume_cb pld_cb);
+#endif
+
 /**
  * pmo_core_psoc_suspend_target() -Send suspend target command
  * @psoc: objmgr psoc handle

+ 55 - 0
power_management_offloads/core/src/wlan_pmo_main.c

@@ -265,3 +265,58 @@ out:
 	return status;
 }
 
+void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_hdl)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
+	if (!psoc_ctx)
+		return;
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->hif_hdl = hif_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc)
+{
+	void *hif_hdl;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
+	if (!psoc_ctx)
+		return NULL;
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	hif_hdl = psoc_ctx->hif_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return hif_hdl;
+}
+
+void pmo_core_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				   void *txrx_hdl)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
+	if (!psoc_ctx)
+		return;
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->txrx_hdl = txrx_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc)
+{
+	void *txrx_hdl;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
+	if (!psoc_ctx)
+		return NULL;
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	txrx_hdl = psoc_ctx->txrx_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return txrx_hdl;
+}

+ 268 - 38
power_management_offloads/core/src/wlan_pmo_suspend_resume.c

@@ -26,7 +26,9 @@
 #include "wlan_pmo_lphb.h"
 #include "wlan_pmo_suspend_resume.h"
 #include "cdp_txrx_ops.h"
+#include "cdp_txrx_misc.h"
 #include "cdp_txrx_flow_ctrl_legacy.h"
+#include "hif.h"
 #include "htc_api.h"
 #include "wlan_pmo_obj_mgmt_api.h"
 #include <wlan_scan_ucfg_api.h>
@@ -251,51 +253,75 @@ void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc)
 	}
 }
 
-QDF_STATUS pmo_core_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
-		enum qdf_suspend_type type)
+/**
+ * pmo_core_psoc_configure_suspend(): configure suspend req events
+ * @psoc: objmgr psoc
+ *
+ * Responsibility of the caller to take the psoc reference.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS pmo_core_psoc_configure_suspend(struct wlan_objmgr_psoc *psoc)
 {
 	struct pmo_psoc_priv_obj *psoc_ctx;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	PMO_ENTER();
 
-	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_PMO_ID);
-	if (status != QDF_STATUS_SUCCESS) {
-		pmo_err("pmo cannot get the reference out of psoc");
-		goto out;
-	}
-
 	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
 	if (!psoc_ctx) {
 		pmo_err("pmo psoc ctx is null");
 		status = QDF_STATUS_E_NULL_VALUE;
-		goto dec_psoc_ref;
-	}
-
-	/* Suspend all components before sending target suspend command */
-	status = pmo_suspend_all_components(psoc, type);
-	if (status != QDF_STATUS_SUCCESS) {
-		pmo_err("Failed to suspend all component");
-		goto dec_psoc_ref;
+		goto out;
 	}
 
 	if (pmo_core_is_wow_applicable(psoc)) {
 		pmo_info("WOW Suspend");
 		pmo_core_apply_lphb(psoc);
-
 		pmo_core_configure_dynamic_wake_events(psoc);
 		pmo_core_update_wow_enable(psoc_ctx, true);
 		pmo_core_update_wow_enable_cmd_sent(psoc_ctx, false);
 	}
 
-	/* Set the Suspend DTIM Parameters */
 	pmo_core_set_suspend_dtim(psoc);
 
 	/*
-	 * To handle race between hif_pci_suspend and
-	 * unpause/pause tx handler
+	 * To handle race between hif_pci_suspend and unpause/pause tx handler.
+	 * This happens when host sending WMI_WOW_ENABLE_CMDID to FW and receive
+	 * WMI_TX_PAUSE_EVENT with ACTON_UNPAUSE almost at same time.
 	 */
 	pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, true);
+
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_PMO_ID);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	/* Suspend all components before sending target suspend command */
+	status = pmo_suspend_all_components(psoc, type);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to suspend all component");
+		goto dec_psoc_ref;
+	}
+
+	status = pmo_core_psoc_configure_suspend(psoc);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to configure suspend");
+
 dec_psoc_ref:
 	wlan_objmgr_psoc_release_ref(psoc, WLAN_PMO_ID);
 out:
@@ -456,10 +482,41 @@ static void pmo_unpause_all_vdev(struct wlan_objmgr_psoc *psoc,
 	}
 }
 
+/**
+ * pmo_core_psoc_configure_resume(): configure events after bus resume
+ * @psoc: objmgr psoc
+ *
+ * Responsibility of the caller to take the psoc reference.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS pmo_core_psoc_configure_resume(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+
+	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
+	if (!psoc_ctx) {
+		pmo_err("pmo psoc ctx is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	pmo_core_set_resume_dtim(psoc);
+	pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, false);
+	pmo_unpause_all_vdev(psoc, psoc_ctx);
+
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
 QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
 		enum qdf_suspend_type type)
 {
-	struct pmo_psoc_priv_obj *psoc_ctx;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	PMO_ENTER();
@@ -470,13 +527,6 @@ QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
 		goto out;
 	}
 
-	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
-	if (!psoc_ctx) {
-		pmo_err("pmo psoc ctx is null");
-		status = QDF_STATUS_E_NULL_VALUE;
-		goto dec_psoc_ref;
-	}
-
 	/* Resume all components */
 	status = pmo_resume_all_components(psoc, type);
 	if (status != QDF_STATUS_SUCCESS) {
@@ -484,12 +534,9 @@ QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
 		goto dec_psoc_ref;
 	}
 
-	/* Reset the DTIM Parameters */
-	pmo_core_set_resume_dtim(psoc);
-	/* need to reset if hif_pci_suspend_fails */
-	pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, false);
-	/* unpause the vdev if left paused and hif_pci_suspend fails */
-	pmo_unpause_all_vdev(psoc, psoc_ctx);
+	status = pmo_core_psoc_configure_resume(psoc);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to configure resume");
 
 dec_psoc_ref:
 	wlan_objmgr_psoc_release_ref(psoc, WLAN_PMO_ID);
@@ -695,10 +742,8 @@ QDF_STATUS pmo_core_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
 	}
 */
 
-	if (type == QDF_SYSTEM_SUSPEND) {
-		wow_mode_selected = pmo_core_is_wow_enabled(psoc_ctx);
-		pmo_info("wow mode selected %d", wow_mode_selected);
-	}
+	wow_mode_selected = pmo_core_is_wow_enabled(psoc_ctx);
+	pmo_info("wow mode selected %d", wow_mode_selected);
 
 	if (wow_mode_selected)
 		status = pmo_core_enable_wow_in_fw(psoc, psoc_ctx, wow_params);
@@ -712,6 +757,191 @@ out:
 	return status;
 }
 
+#ifdef FEATURE_RUNTIME_PM
+QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	void *hif_ctx;
+	void *dp_soc;
+	void *txrx_pdev;
+	void *htc_ctx;
+	QDF_STATUS status;
+	struct pmo_wow_enable_params wow_params = {0};
+
+	PMO_ENTER();
+
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_PMO_ID);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
+	if (!psoc_ctx) {
+		pmo_err("psoc_ctx is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto dec_psoc_ref;
+	}
+
+	hif_ctx = pmo_core_psoc_get_hif_handle(psoc);
+	dp_soc = pmo_core_psoc_get_dp_handle(psoc);
+	txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc);
+	htc_ctx = pmo_core_psoc_get_htc_handle(psoc);
+	if (!hif_ctx || !dp_soc || !txrx_pdev || !htc_ctx) {
+		pmo_err("Invalid hif: %p, dp: %p, txrx: %p, htc: %p",
+			hif_ctx, dp_soc, txrx_pdev, htc_ctx);
+		status = QDF_STATUS_E_INVAL;
+		goto dec_psoc_ref;
+	}
+
+	if (hif_pre_runtime_suspend(hif_ctx))
+		goto runtime_failure;
+
+	status = cdp_runtime_suspend(dp_soc, txrx_pdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto runtime_failure;
+
+	if (htc_runtime_suspend(htc_ctx))
+		goto cdp_runtime_resume;
+
+	status = pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, true);
+	if (status != QDF_STATUS_SUCCESS)
+		goto resume_htc;
+
+	status = pmo_core_psoc_configure_suspend(psoc);
+	if (status != QDF_STATUS_SUCCESS)
+		goto resume_htc;
+
+	status = pmo_core_psoc_bus_suspend_req(psoc, QDF_RUNTIME_SUSPEND,
+					       &wow_params);
+	if (status != QDF_STATUS_SUCCESS)
+		goto pmo_resume_configure;
+
+	if (hif_runtime_suspend(hif_ctx))
+		goto pmo_bus_resume;
+
+	if (pld_cb && pld_cb())
+		goto resume_hif;
+
+	hif_process_runtime_suspend_success(hif_ctx);
+
+	goto dec_psoc_ref;
+
+resume_hif:
+	QDF_BUG(!hif_runtime_resume(hif_ctx));
+
+pmo_bus_resume:
+	QDF_BUG(QDF_STATUS_SUCCESS ==
+		pmo_core_psoc_bus_resume_req(psoc, QDF_RUNTIME_SUSPEND));
+
+pmo_resume_configure:
+	QDF_BUG(QDF_STATUS_SUCCESS ==
+		pmo_core_psoc_configure_resume(psoc));
+
+resume_htc:
+	QDF_BUG(QDF_STATUS_SUCCESS ==
+		pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, false));
+
+	QDF_BUG(!htc_runtime_resume(htc_ctx));
+
+cdp_runtime_resume:
+	QDF_BUG(QDF_STATUS_SUCCESS ==
+		cdp_runtime_resume(dp_soc, txrx_pdev));
+
+runtime_failure:
+	hif_process_runtime_suspend_failure(hif_ctx);
+
+dec_psoc_ref:
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_PMO_ID);
+
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					    pmo_pld_auto_resume_cb pld_cb)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	void *hif_ctx;
+	void *dp_soc;
+	void *txrx_pdev;
+	void *htc_ctx;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_PMO_ID);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
+	if (!psoc_ctx) {
+		pmo_err("pmo psoc ctx is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto dec_psoc_ref;
+	}
+
+	hif_ctx = pmo_core_psoc_get_hif_handle(psoc);
+	dp_soc = pmo_core_psoc_get_dp_handle(psoc);
+	txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc);
+	htc_ctx = pmo_core_psoc_get_htc_handle(psoc);
+	if (!hif_ctx || !dp_soc || !txrx_pdev || !htc_ctx) {
+		pmo_err("Invalid hif: %p, dp: %p, txrx: %p, htc: %p",
+			hif_ctx, dp_soc, txrx_pdev, htc_ctx);
+		status = QDF_STATUS_E_INVAL;
+		goto dec_psoc_ref;
+	}
+
+	hif_pre_runtime_resume(hif_ctx);
+
+	if (pld_cb)
+		QDF_BUG(!pld_cb());
+
+	QDF_BUG(!hif_runtime_resume(hif_ctx));
+
+	status = pmo_core_psoc_bus_resume_req(psoc, QDF_RUNTIME_SUSPEND);
+	QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+	status = pmo_core_psoc_configure_resume(psoc);
+	QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+	status = pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, false);
+	QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+	QDF_BUG(!htc_runtime_resume(htc_ctx));
+
+	status = cdp_runtime_resume(dp_soc, txrx_pdev);
+	QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+	hif_process_runtime_resume_success(hif_ctx);
+
+dec_psoc_ref:
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_PMO_ID);
+
+out:
+	PMO_EXIT();
+
+	return status;
+}
+#endif
+
 /**
  * pmo_core_psoc_send_host_wakeup_ind_to_fw() - send wakeup ind to fw
  * @psoc: objmgr psoc handle

+ 15 - 0
power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h

@@ -50,6 +50,8 @@ typedef  uint16_t(*pmo_get_pause_bitmap)(uint8_t vdev_id);
  * @wow: wow configuration
  * @dp_hdl: psoc data path handle
  * @htc_hdl: htc layer handle
+ * @hif_hdl: hif layer handle
+ * @txrx_hdl: txrx pdev handle
  * @pause_bitmap_notifier: registered callback to update pause bitmap value
  * @pmo_get_pause_bitmap: registered callback to get pause bitmap value
  * @lock: spin lock for pmo psoc
@@ -59,6 +61,8 @@ struct pmo_psoc_priv_obj {
 	struct pmo_wow wow;
 	void *dp_hdl;
 	void *htc_hdl;
+	void *hif_hdl;
+	void *txrx_hdl;
 	pmo_notify_pause_bitmap pause_bitmap_notifier;
 	pmo_get_pause_bitmap get_pause_bitmap;
 	qdf_spinlock_t lock;
@@ -132,4 +136,15 @@ struct pmo_vdev_priv_obj {
 	qdf_spinlock_t pmo_vdev_lock;
 };
 
+/*
+ * typedef for pld auto suspend callback during runtime suspend
+ */
+typedef
+int (*pmo_pld_auto_suspend_cb)(void);
+
+/*
+ * typedef for pld auto resume callback during runtime resume
+ */
+typedef
+int (*pmo_pld_auto_resume_cb)(void);
 #endif /* end  of _WLAN_PMO_OBJ_MGMT_PUBLIC_STRUCT_H_ */

+ 10 - 0
power_management_offloads/dispatcher/inc/wlan_pmo_tgt_api.h

@@ -345,6 +345,16 @@ QDF_STATUS pmo_tgt_psoc_send_wow_enable_req(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS pmo_tgt_psoc_send_supend_req(struct wlan_objmgr_psoc *psoc,
 		struct pmo_suspend_params *param);
 
+/**
+ * pmo_tgt_psoc_set_runtime_pm_inprogress() -set runtime status
+ * @psoc: objmgr psoc
+ * @value: set runtime pm in progress true or false
+ *
+ * Return: none
+ */
+QDF_STATUS pmo_tgt_psoc_set_runtime_pm_inprogress(struct wlan_objmgr_psoc *psoc,
+						  bool value);
+
 /**
  * pmo_tgt_psoc_get_runtime_pm_in_progress() -get runtime status
  * @psoc: objmgr psoc

+ 42 - 0
power_management_offloads/dispatcher/inc/wlan_pmo_ucfg_api.h

@@ -395,6 +395,26 @@ void pmo_ucfg_vdev_update_dp_handle(struct wlan_objmgr_vdev *vdev,
 void pmo_ucfg_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
 		void *htc_handle);
 
+/**
+ * pmo_ucfg_psoc_set_hif_handle() - Set psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ * @hif_handle: hif context handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_handle);
+
+/**
+ * pmo_ucfg_psoc_set_txrx_handle() - Set psoc pdev txrx layer handle
+ * @psoc: objmgr psoc handle
+ * @txrx_handle: pdev txrx context handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				   void *txrx_handle);
+
 /**
  * pmo_ucfg_psoc_user_space_suspend_req() -  Handles user space suspend req
  * @psoc: objmgr psoc handle
@@ -434,6 +454,28 @@ QDF_STATUS pmo_ucfg_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
 		enum qdf_suspend_type type,
 		struct pmo_wow_enable_params *wow_params);
 
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * pmo_ucfg_psoc_bus_runtime_suspend(): handles bus runtime suspend for psoc
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to call link auto suspend
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb);
+
+/**
+ * pmo_ucfg_psoc_bus_runtime_resume(): handles bus runtime resume for psoc
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to call link auto resume
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					    pmo_pld_auto_resume_cb pld_cb);
+#endif
+
 /**
  * pmo_ucfg_psoc_suspend_target() -Send suspend target command
  * @psoc: objmgr psoc handle

+ 16 - 0
power_management_offloads/dispatcher/src/wlan_pmo_tgt_suspend_resume.c

@@ -167,6 +167,22 @@ QDF_STATUS pmo_tgt_psoc_send_supend_req(struct wlan_objmgr_psoc *psoc,
 	return pmo_tx_ops.psoc_send_supend_req(psoc, param);
 }
 
+QDF_STATUS pmo_tgt_psoc_set_runtime_pm_inprogress(struct wlan_objmgr_psoc *psoc,
+						  bool value)
+{
+	struct wlan_lmac_if_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_set_runtime_pm_in_progress) {
+		pmo_err("pmo ops is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	pmo_tx_ops.psoc_set_runtime_pm_in_progress(psoc, value);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 bool pmo_tgt_psoc_get_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_lmac_if_pmo_tx_ops pmo_tx_ops;

+ 26 - 0
power_management_offloads/dispatcher/src/wlan_pmo_ucfg_api.c

@@ -237,6 +237,18 @@ void pmo_ucfg_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
 	pmo_core_psoc_update_htc_handle(psoc, htc_handle);
 }
 
+void pmo_ucfg_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+		void *hif_handle)
+{
+	pmo_core_psoc_set_hif_handle(psoc, hif_handle);
+}
+
+void pmo_ucfg_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+		void *txrx_handle)
+{
+	pmo_core_psoc_set_txrx_handle(psoc, txrx_handle);
+}
+
 void pmo_ucfg_psoc_handle_initial_wake_up(void *cb_ctx)
 {
 	return pmo_core_psoc_handle_initial_wake_up(cb_ctx);
@@ -262,6 +274,20 @@ QDF_STATUS pmo_ucfg_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
 	return pmo_core_psoc_bus_suspend_req(psoc, type, wow_params);
 }
 
+#ifdef FEATURE_RUNTIME_PM
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb)
+{
+	return pmo_core_psoc_bus_runtime_suspend(psoc, pld_cb);
+}
+
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					    pmo_pld_auto_suspend_cb pld_cb)
+{
+	return pmo_core_psoc_bus_runtime_resume(psoc, pld_cb);
+}
+#endif
+
 QDF_STATUS pmo_ucfg_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
 		int disable_target_intr)
 {