From f967e48d1d573d2c50b1c5c17d2831bd032c37cd Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 20 Sep 2018 16:29:04 -0700 Subject: [PATCH] qcacld-3.0: Integrate DSC (psoc ssr) The Driver Synchronization Core (DSC) is a set of synchronization primitives for use by the driver's orchestration layer. It provides APIs for ensuring safe state transitions (including bring up and tear down) of major driver objects: a single driver, associated psocs, and their associated vdevs. As part of integrating the DSC APIs into HDD, protect psoc sub-system recovery (SSR). Change-Id: I0374cdb22259763b0f61a4bea89fdb4ffc2c215c CRs-Fixed: 2348567 --- core/hdd/src/wlan_hdd_driver_ops.c | 47 ++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 535a3cc6cb8b..20cdc5fad217 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -540,10 +540,15 @@ static int hdd_soc_recovery_reinit(struct device *dev, const struct hif_bus_id *bid, enum qdf_bus_type bus_type) { + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc; int errno; hdd_info("re-probing driver"); + /* SSR transition is initiated at the beginning of soc shutdown */ + dsc_psoc_assert_trans_protected(hdd_psoc->dsc_psoc); + hdd_soc_load_lock(dev, eHDD_DRV_OP_REINIT); cds_set_driver_in_bad_state(false); @@ -562,6 +567,8 @@ static int hdd_soc_recovery_reinit(struct device *dev, hdd_soc_load_unlock(dev); + dsc_psoc_trans_stop(hdd_psoc->dsc_psoc); + return 0; assert_fail_count: @@ -714,6 +721,8 @@ static void hdd_psoc_shutdown_notify(struct hdd_context *hdd_ctx) static void hdd_soc_recovery_shutdown(void) { struct hdd_context *hdd_ctx; + struct hdd_psoc *hdd_psoc; + QDF_STATUS status; void *hif_ctx; /* recovery starts via firmware down indication; ensure we got one */ @@ -728,21 +737,34 @@ static void hdd_soc_recovery_shutdown(void) /* cancel/flush any pending/active idle shutdown work */ hdd_psoc_idle_timer_stop(hdd_ctx); + hdd_psoc = hdd_ctx->hdd_psoc; + status = dsc_psoc_trans_start_wait(hdd_psoc->dsc_psoc, "ssr"); + if (QDF_IS_STATUS_ERROR(status)) { + /* If SSR races with e.g. Remove, aborting SSR is expected */ + hdd_info("Aborting SSR; status:%u", status); + return; + } + + dsc_psoc_wait_for_ops(hdd_psoc->dsc_psoc); + + mutex_lock(&hdd_init_deinit_lock); + hdd_start_driver_ops_timer(eHDD_DRV_OP_SHUTDOWN); + /* nothing to do if the soc is already unloaded */ if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { hdd_info("Driver modules are already closed"); - return; + goto unlock; } if (cds_is_load_or_unload_in_progress()) { hdd_info("Load/unload in progress, ignore SSR shutdown"); - return; + goto unlock; } hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); if (!hif_ctx) { hdd_err("Failed to get HIF context, ignore SSR shutdown"); - return; + goto unlock; } /* mask the host controller interrupts */ @@ -760,6 +782,19 @@ static void hdd_soc_recovery_shutdown(void) hif_disable_isr(hif_ctx); hdd_wlan_shutdown(); } + + hdd_stop_driver_ops_timer(); + mutex_unlock(&hdd_init_deinit_lock); + + /* SSR transition is concluded at the end of soc re-init */ + + return; + +unlock: + hdd_stop_driver_ops_timer(); + mutex_unlock(&hdd_init_deinit_lock); + + dsc_psoc_trans_stop(hdd_psoc->dsc_psoc); } /** @@ -1470,14 +1505,8 @@ static void wlan_hdd_pld_shutdown(struct device *dev, { hdd_enter(); - mutex_lock(&hdd_init_deinit_lock); - hdd_start_driver_ops_timer(eHDD_DRV_OP_SHUTDOWN); - hdd_soc_recovery_shutdown(); - hdd_stop_driver_ops_timer(); - mutex_unlock(&hdd_init_deinit_lock); - hdd_exit(); }