Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5b9ca1d authored by Rakesh Pillai's avatar Rakesh Pillai Committed by Gerrit - the friendly Code Review server
Browse files

ath10k: Defer core register if fw not ready during init



During driver init, if fw ready indication is not received,
the driver init times out and returns failure.

Defer the core register and the wlan enable till we
receive the fw ready indication to mitigate the driver
init failure when fw ready is not received.

CRs-Fixed: 2166351
Change-Id: I16784e3db7a5ad9fa16eb90dcbbd3ebe51e7456e
Signed-off-by: default avatarRakesh Pillai <pillair@codeaurora.org>
parent c8cbce19
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ ath10k_snoc_service_notifier_notify(struct notifier_block *nb,
				   atomic_read(&qmi_cfg->server_connected)),
			msecs_to_jiffies(ATH10K_SNOC_WLAN_FW_READY_TIMEOUT));
		if (ret) {
			if (ar_snoc->drv_state != ATH10K_DRIVER_STATE_PROBED)
				queue_work(ar->workqueue, &ar->restart_work);
		} else {
			ath10k_err(ar, "restart failed, fw_ready timed out\n");
@@ -727,9 +728,21 @@ static int ath10k_snoc_driver_event_fw_ready_ind(struct ath10k *ar)
{
	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
	struct ath10k_snoc_qmi_config *qmi_cfg = &ar_snoc->qmi_cfg;
	int ret;

	ath10k_dbg(ar, ATH10K_DBG_SNOC, "FW Ready event received.\n");
	atomic_set(&qmi_cfg->fw_ready, 1);
	if (ar_snoc->drv_state == ATH10K_DRIVER_STATE_PROBED) {
		ret = ath10k_core_register(ar,
					   ar_snoc->target_info.soc_version);
		if (ret) {
			ath10k_err(ar,
				   "failed to register driver core: %d\n",
				   ret);
			return 0;
		}
		ar_snoc->drv_state = ATH10K_DRIVER_STATE_STARTED;
	}
	wake_up_all(&ath10k_fw_ready_wait_event);

	return 0;
@@ -862,17 +875,14 @@ int ath10k_snoc_start_qmi_service(struct ath10k *ar)
		goto out_destroy_wq;
	}

	if (!icnss_is_fw_ready()) {
		ath10k_err(ar, "failed to get fw ready indication\n");
		ret = -EFAULT;
		goto err_fw_ready;
	}

	if (icnss_is_fw_ready())
		atomic_set(&qmi_cfg->fw_ready, 1);
	else
		ath10k_err(ar, "FW ready indication not received yet\n");

	ath10k_dbg(ar, ATH10K_DBG_SNOC, "QMI service started successfully\n");
	return 0;

err_fw_ready:
	qmi_svc_event_notifier_unregister(WLFW_SERVICE_ID_V01,
					  WLFW_SERVICE_VERS_V01,
					  WLFW_SERVICE_INS_ID_V01,
+18 −20
Original line number Diff line number Diff line
@@ -1162,15 +1162,12 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar)
		atomic_set(&ar_snoc->pm_ops_inprogress, 0);
	}

	if ((ar->state == ATH10K_STATE_ON) ||
	    (ar->state == ATH10K_STATE_RESTARTING) ||
	    test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
	ret = ath10k_snoc_bus_configure(ar);
	if (ret) {
		ath10k_err(ar, "failed to configure bus: %d\n", ret);
		return ret;
	}
	}

	ret = ath10k_snoc_init_pipes(ar);
	if (ret) {
		ath10k_err(ar, "failed to initialize CE: %d\n", ret);
@@ -1643,9 +1640,9 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
	int ret;
	struct ath10k *ar;
	struct ath10k_snoc *ar_snoc;
	struct ath10k_snoc_qmi_config *qmi_cfg;
	enum ath10k_hw_rev hw_rev;
	struct device *dev;
	u32 chip_id;
	u32 i;

	dev = &pdev->dev;
@@ -1671,6 +1668,7 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
		goto err_core_destroy;
	}

	qmi_cfg = &ar_snoc->qmi_cfg;
	spin_lock_init(&ar_snoc->opaque_ctx.ce_lock);
	ar_snoc->opaque_ctx.bus_ops = &ath10k_snoc_bus_ops;
	ath10k_snoc_resource_init(ar);
@@ -1706,12 +1704,6 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
		goto err_hw_power_off;
	}

	ret = ath10k_snoc_bus_configure(ar);
	if (ret) {
		ath10k_err(ar, "failed to configure bus: %d\n", ret);
		goto err_hw_power_off;
	}

	ret = ath10k_snoc_alloc_pipes(ar);
	if (ret) {
		ath10k_err(ar, "failed to allocate copy engine pipes: %d\n",
@@ -1728,13 +1720,19 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
		goto err_free_pipes;
	}

	chip_id = ar_snoc->target_info.soc_version;
	ar_snoc->drv_state = ATH10K_DRIVER_STATE_PROBED;
	/* chip id needs to be retrieved from platform driver */
	ret = ath10k_core_register(ar, chip_id);
	if (atomic_read(&qmi_cfg->fw_ready)) {
		ret = ath10k_core_register(ar,
					   ar_snoc->target_info.soc_version);
		if (ret) {
		ath10k_err(ar, "failed to register driver core: %d\n", ret);
			ath10k_err(ar,
				   "failed to register driver core: %d\n",
				   ret);
			goto err_free_irq;
		}
		ar_snoc->drv_state = ATH10K_DRIVER_STATE_STARTED;
	}

	ath10k_snoc_modem_ssr_register_notifier(ar);
	ath10k_snoc_pd_restart_enable(ar);
+6 −0
Original line number Diff line number Diff line
@@ -145,6 +145,11 @@ static struct ath10k_wcn3990_clk_info clk_cfg[] = {

#define ATH10K_WCN3990_CLK_INFO_SIZE		ARRAY_SIZE(clk_cfg)

enum ath10k_driver_state {
	ATH10K_DRIVER_STATE_PROBED,
	ATH10K_DRIVER_STATE_STARTED,
};

/* struct ath10k_snoc: SNOC info struct
 * @dev: device structure
 * @ar:ath10k base structure
@@ -192,6 +197,7 @@ struct ath10k_snoc {
	struct ath10k_snoc_qmi_config qmi_cfg;
	struct ath10k_wcn3990_vreg_info vreg[ATH10K_WCN3990_VREG_INFO_SIZE];
	struct ath10k_wcn3990_clk_info clk[ATH10K_WCN3990_CLK_INFO_SIZE];
	enum ath10k_driver_state drv_state;
};

struct ath10k_event_pd_down_data {