From 4aa291d159bc73e0336587428ac97937c857f9cf Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Fri, 4 Sep 2020 16:23:46 +0530 Subject: [PATCH] qcacmn: Do explicit system wakeup for group intr in D0-WoW In P2P GO mode, on system suspend to s2idle state, bus is suspended and D0-WoW is enabled. Ping requests from P2P client cause the REO interrupt to fire but since system is in s2idle state, system is not woken-up. This results in destination unreachability or large rtt for ping on P2P client. Fix is to do explicit system wakeup when group interrupts fire after system is in suspend state. Change-Id: Ic6f51c3fc8bad6da29adf58972890677a81f2064 CRs-Fixed: 2765037 --- hif/src/hif_exec.c | 20 ++++++++++++++++++++ hif/src/hif_main.h | 2 ++ hif/src/ipcie/if_ipci.c | 11 ++++++++++- hif/src/pcie/if_pci.c | 4 ++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/hif/src/hif_exec.c b/hif/src/hif_exec.c index cd999970146c..361f7f14e9ec 100644 --- a/hif/src/hif_exec.c +++ b/hif/src/hif_exec.c @@ -861,6 +861,23 @@ static inline void hif_check_and_trigger_ut_resume(struct hif_softc *scn) } #endif +/** + * hif_check_and_trigger_sys_resume() - Check for bus suspend and + * trigger system resume + * @scn: hif context + * @irq: irq number + * + * Return: None + */ +static inline void +hif_check_and_trigger_sys_resume(struct hif_softc *scn, int irq) +{ + if (scn->bus_suspended && scn->linkstate_vote) { + hif_info_rl("interrupt rcvd:%d trigger sys resume", irq); + qdf_pm_system_wakeup(); + } +} + /** * hif_ext_group_interrupt_handler() - handler for related interrupts * @irq: irq number of the interrupt @@ -895,6 +912,9 @@ irqreturn_t hif_ext_group_interrupt_handler(int irq, void *context) * in reality APSS didn't really suspend. */ hif_check_and_trigger_ut_resume(scn); + + hif_check_and_trigger_sys_resume(scn, irq); + qdf_atomic_inc(&scn->active_grp_tasklet_cnt); hif_ext_group->sched_ops->schedule(hif_ext_group); diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index 4b6bd70f64fe..e062a3fb8a39 100644 --- a/hif/src/hif_main.h +++ b/hif/src/hif_main.h @@ -257,6 +257,8 @@ struct hif_softc { #endif uint32_t irq_unlazy_disable; /* Should the unlzay support for interrupt delivery be disabled */ + /* Flag to indicate whether bus is suspended */ + bool bus_suspended; }; static inline diff --git a/hif/src/ipcie/if_ipci.c b/hif/src/ipcie/if_ipci.c index 2e81aa54c0ed..a82d89debf0c 100644 --- a/hif/src/ipcie/if_ipci.c +++ b/hif/src/ipcie/if_ipci.c @@ -311,11 +311,20 @@ void hif_ipci_prevent_linkdown(struct hif_softc *scn, bool flag) int hif_ipci_bus_suspend(struct hif_softc *scn) { - return hif_apps_enable_irq_wake(GET_HIF_OPAQUE_HDL(scn)); + int ret; + + ret = hif_apps_enable_irq_wake(GET_HIF_OPAQUE_HDL(scn)); + + if (!ret) + scn->bus_suspended = true; + + return ret; } int hif_ipci_bus_resume(struct hif_softc *scn) { + scn->bus_suspended = false; + return hif_apps_disable_irq_wake(GET_HIF_OPAQUE_HDL(scn)); } diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c index c343f050b69a..57b2bf2302f9 100644 --- a/hif/src/pcie/if_pci.c +++ b/hif/src/pcie/if_pci.c @@ -2320,6 +2320,8 @@ int hif_pci_bus_suspend(struct hif_softc *scn) /* Stop the HIF Sleep Timer */ hif_cancel_deferred_target_sleep(scn); + scn->bus_suspended = true; + return 0; } @@ -2371,6 +2373,8 @@ int hif_pci_bus_resume(struct hif_softc *scn) { int errno; + scn->bus_suspended = false; + errno = __hif_check_link_status(scn); if (errno) return errno;