From 10d83a14412eedcfa84edd83ff29d23d8abb2454 Mon Sep 17 00:00:00 2001 From: Mohit Khanna Date: Sun, 8 Nov 2020 21:50:05 -0800 Subject: [PATCH] qcacmn: Flush reg write work before bus suspend Delayed register write work needs to be flushed before bus suspend to make sure there are on pending writes after driver's bus suspend routine exits. In case delayed work context is not able to finish before the bus (PCI) is suspended (DRV), it may lead to a NOC error. Change-Id: I40cbcec5d23ddd75ec87aed69ac45d95510fa880 CRs-Fixed: 2813733 --- dp/wifi3.0/dp_main.c | 2 ++ hal/wifi3.0/hal_api.h | 12 ++++++++++++ hal/wifi3.0/hal_srng.c | 14 ++++++-------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 81310be01636..e640a09d185d 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -11520,6 +11520,8 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) dp_service_mon_rings(soc, DP_MON_REAP_BUDGET); } + hal_flush_reg_write_work(soc->hal_soc); + return QDF_STATUS_SUCCESS; } diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index cb5f82a851ff..9b9e8159405e 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -2611,4 +2611,16 @@ static inline QDF_STATUS hal_construct_shadow_regs(void *hal_soc) return QDF_STATUS_SUCCESS; } #endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ + +#ifdef FEATURE_HAL_DELAYED_REG_WRITE +/** + * hal_flush_reg_write_work() - flush all writes from register write queue + * @arg: hal_soc pointer + * + * Return: None + */ +void hal_flush_reg_write_work(hal_soc_handle_t hal_handle); +#else +static inline void hal_flush_reg_write_work(hal_soc_handle_t hal_handle) { } +#endif #endif /* _HAL_APIH_ */ diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index d25fb85ef172..d2b45e041265 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -593,19 +593,17 @@ static void hal_reg_write_work(void *arg) hif_allow_link_low_power_states(hal->hif_handle); } -/** - * hal_flush_reg_write_work() - flush all writes from regiter write queue - * @arg: hal_soc pointer - * - * Return: None - */ -static inline void hal_flush_reg_write_work(struct hal_soc *hal) +static void __hal_flush_reg_write_work(struct hal_soc *hal) { qdf_cancel_work(&hal->reg_write_work); qdf_flush_work(&hal->reg_write_work); qdf_flush_workqueue(0, hal->reg_write_wq); } +void hal_flush_reg_write_work(hal_soc_handle_t hal_handle) +{ __hal_flush_reg_write_work((struct hal_soc *)hal_handle); +} + /** * hal_reg_write_enqueue() - enqueue register writes into kworker * @hal_soc: hal_soc pointer @@ -739,7 +737,7 @@ static QDF_STATUS hal_delayed_reg_write_init(struct hal_soc *hal) */ static void hal_delayed_reg_write_deinit(struct hal_soc *hal) { - hal_flush_reg_write_work(hal); + __hal_flush_reg_write_work(hal); qdf_destroy_workqueue(0, hal->reg_write_wq); qdf_mem_free(hal->reg_write_queue); }