diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 79fd31716b..25885f7146 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -864,6 +864,10 @@ int hif_pm_runtime_allow_suspend(struct hif_opaque_softc *ol_sc, struct hif_pm_runtime_lock *lock); int hif_pm_runtime_prevent_suspend_timeout(struct hif_opaque_softc *ol_sc, struct hif_pm_runtime_lock *lock, unsigned int delay); +bool hif_pm_runtime_is_suspended(struct hif_opaque_softc *hif_ctx); +int hif_pm_runtime_get_monitor_wake_intr(struct hif_opaque_softc *hif_ctx); +void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, + int val); #else struct hif_pm_runtime_lock { const char *name; @@ -898,6 +902,14 @@ static inline int hif_pm_runtime_prevent_suspend_timeout(struct hif_opaque_softc *ol_sc, struct hif_pm_runtime_lock *lock, unsigned int delay) { return 0; } +static inline bool hif_pm_runtime_is_suspended(struct hif_opaque_softc *hif_ctx) +{ return false; } +static inline int +hif_pm_runtime_get_monitor_wake_intr(struct hif_opaque_softc *hif_ctx) +{ return 0; } +static inline void +hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, int val) +{ return; } #endif void hif_enable_power_management(struct hif_opaque_softc *hif_ctx, diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c index 20fa5e09ef..305da8981b 100644 --- a/hif/src/hif_main.c +++ b/hif/src/hif_main.c @@ -1275,7 +1275,11 @@ irqreturn_t hif_wake_interrupt_handler(int irq, void *context) if (scn->initial_wakeup_cb) scn->initial_wakeup_cb(scn->initial_wakeup_priv); - hif_pm_runtime_request_resume(hif_ctx); + if (hif_pm_runtime_get_monitor_wake_intr(hif_ctx) && + hif_pm_runtime_is_suspended(hif_ctx)) { + hif_pm_runtime_set_monitor_wake_intr(hif_ctx, 0); + hif_pm_runtime_request_resume(hif_ctx); + } return IRQ_HANDLED; } diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c index 43ef8e2fb1..b762cfe281 100644 --- a/hif/src/pcie/if_pci.c +++ b/hif/src/pcie/if_pci.c @@ -2799,6 +2799,7 @@ void hif_process_runtime_suspend_success(struct hif_opaque_softc *hif_ctx) struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); hif_runtime_pm_set_state_suspended(scn); + hif_pm_runtime_set_monitor_wake_intr(hif_ctx, 1); hif_log_runtime_suspend_success(scn); } @@ -2811,6 +2812,7 @@ void hif_pre_runtime_resume(struct hif_opaque_softc *hif_ctx) { struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + hif_pm_runtime_set_monitor_wake_intr(hif_ctx, 0); hif_runtime_pm_set_state_inprogress(scn); } @@ -4358,6 +4360,54 @@ void hif_runtime_lock_deinit(struct hif_opaque_softc *hif_ctx, qdf_mem_free(context); } + +/** + * hif_pm_runtime_is_suspended() - API to check if driver has runtime suspended + * @hif_ctx: HIF context + * + * Return: true for runtime suspended, otherwise false + */ +bool hif_pm_runtime_is_suspended(struct hif_opaque_softc *hif_ctx) +{ + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); + + return qdf_atomic_read(&sc->pm_state) == + HIF_PM_RUNTIME_STATE_SUSPENDED; +} + +/** + * hif_pm_runtime_get_monitor_wake_intr() - API to get monitor_wake_intr + * @hif_ctx: HIF context + * + * monitor_wake_intr variable can be used to indicate if driver expects wake + * MSI for runtime PM + * + * Return: monitor_wake_intr variable + */ +int hif_pm_runtime_get_monitor_wake_intr(struct hif_opaque_softc *hif_ctx) +{ + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); + + return qdf_atomic_read(&sc->monitor_wake_intr); +} + +/** + * hif_pm_runtime_set_monitor_wake_intr() - API to set monitor_wake_intr + * @hif_ctx: HIF context + * @val: value to set + * + * monitor_wake_intr variable can be used to indicate if driver expects wake + * MSI for runtime PM + * + * Return: void + */ +void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, + int val) +{ + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); + + qdf_atomic_set(&sc->monitor_wake_intr, val); +} #endif /* FEATURE_RUNTIME_PM */ int hif_pci_legacy_map_ce_to_irq(struct hif_softc *scn, int ce_id) diff --git a/hif/src/pcie/if_pci.h b/hif/src/pcie/if_pci.h index 19cc5036c1..6dbb9d2e96 100644 --- a/hif/src/pcie/if_pci.h +++ b/hif/src/pcie/if_pci.h @@ -130,6 +130,7 @@ struct hif_pci_softc { uint32_t lcr_val; #ifdef FEATURE_RUNTIME_PM atomic_t pm_state; + atomic_t monitor_wake_intr; uint32_t prevent_suspend_cnt; struct hif_pci_pm_stats pm_stats; struct work_struct pm_work;