Browse Source

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
Dustin Brown 6 years ago
parent
commit
f967e48d1d
1 changed files with 38 additions and 9 deletions
  1. 38 9
      core/hdd/src/wlan_hdd_driver_ops.c

+ 38 - 9
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();
 }