ソースを参照

qcacmn: Set the initial wake flag on MSI resume

When the wlan driver is suspending, the last thing it does is check to
see if the firmware has indicated a wakeup during the suspend process.
This is done by checking the initial wakeup flag, which is set when a
specific copy engine payload is received from firmware. For the new
dedicated wake MSI, only the wake signal is received, no payload. When
the wake MSI is toggled, set the initial wakeup flag to prevent race
conditions during the suspend process.

Change-Id: Id53cc7884431a437136d8dca068449bc5a25b87c
CRs-Fixed: 2133469
Dustin Brown 7 年 前
コミット
bbba9176f8
4 ファイル変更36 行追加0 行削除
  1. 12 0
      hif/inc/hif.h
  2. 19 0
      hif/src/hif_main.c
  3. 2 0
      hif/src/hif_main.h
  4. 3 0
      htc/htc.c

+ 12 - 0
hif/inc/hif.h

@@ -922,4 +922,16 @@ void hif_print_napi_stats(struct hif_opaque_softc *hif_ctx);
 
 void *hif_get_dev_ba(struct hif_opaque_softc *hif_handle);
 
+/**
+ * hif_set_initial_wakeup_cb() - set the initial wakeup event handler function
+ * @hif_ctx - the HIF context to assign the callback to
+ * @callback - the callback to assign
+ * @priv - the private data to pass to the callback when invoked
+ *
+ * Return: None
+ */
+void hif_set_initial_wakeup_cb(struct hif_opaque_softc *hif_ctx,
+			       void (*callback)(void *),
+			       void *priv);
+
 #endif /* _HIF_H_ */

+ 19 - 0
hif/src/hif_main.c

@@ -1217,6 +1217,9 @@ irqreturn_t hif_wake_interrupt_handler(int irq, void *context)
 
 	HIF_INFO("wake interrupt received on irq %d", irq);
 
+	if (scn->initial_wakeup_cb)
+		scn->initial_wakeup_cb(scn->initial_wakeup_priv);
+
 	if (hif_is_ut_suspended(scn))
 		hif_ut_fw_resume(scn);
 
@@ -1225,8 +1228,24 @@ irqreturn_t hif_wake_interrupt_handler(int irq, void *context)
 #else /* WLAN_SUSPEND_RESUME_TEST */
 irqreturn_t hif_wake_interrupt_handler(int irq, void *context)
 {
+	struct hif_softc *scn = context;
+
 	HIF_INFO("wake interrupt received on irq %d", irq);
 
+	if (scn->initial_wakeup_cb)
+		scn->initial_wakeup_cb(scn->initial_wakeup_priv);
+
 	return IRQ_HANDLED;
 }
 #endif /* WLAN_SUSPEND_RESUME_TEST */
+
+void hif_set_initial_wakeup_cb(struct hif_opaque_softc *hif_ctx,
+			       void (*callback)(void *),
+			       void *priv)
+{
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+
+	scn->initial_wakeup_cb = callback;
+	scn->initial_wakeup_priv = priv;
+}
+

+ 2 - 0
hif/src/hif_main.h

@@ -169,6 +169,8 @@ struct hif_softc {
 	struct hif_ut_suspend_context ut_suspend_ctx;
 	uint32_t hif_attribute;
 	int wake_irq;
+	void (*initial_wakeup_cb)(void *);
+	void *initial_wakeup_priv;
 };
 
 static inline void *hif_get_hal_handle(void *hif_hdl)

+ 3 - 0
htc/htc.c

@@ -317,6 +317,9 @@ HTC_HANDLE htc_create(void *ol_sc, struct htc_init_info *pInfo,
 		hif_post_init(target->hif_dev, target, &htcCallbacks);
 		hif_get_default_pipe(target->hif_dev, &pEndpoint->UL_PipeID,
 				     &pEndpoint->DL_PipeID);
+		hif_set_initial_wakeup_cb(target->hif_dev,
+					  pInfo->target_initial_wakeup_cb,
+					  pInfo->target_psoc);
 
 	} while (false);