From bbba9176f8f3945ddb661ebb566db717e50dbd1b Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Wed, 4 Oct 2017 17:03:56 -0700 Subject: [PATCH] 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 --- hif/inc/hif.h | 12 ++++++++++++ hif/src/hif_main.c | 19 +++++++++++++++++++ hif/src/hif_main.h | 2 ++ htc/htc.c | 3 +++ 4 files changed, 36 insertions(+) diff --git a/hif/inc/hif.h b/hif/inc/hif.h index ccb83f0979..6821f9fe10 100644 --- a/hif/inc/hif.h +++ b/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_ */ diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c index 9a217ba2d3..84ffb702b2 100644 --- a/hif/src/hif_main.c +++ b/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; +} + diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index 54d5dd7526..f5be51b9b4 100644 --- a/hif/src/hif_main.h +++ b/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) diff --git a/htc/htc.c b/htc/htc.c index 84cb88baef..79e5da0348 100644 --- a/htc/htc.c +++ b/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);