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

Commit 41e978d6 authored by Yue Ma's avatar Yue Ma
Browse files

cnss2: Wait for calibration to complete before registering driver



WLAN host driver may register to CNSS driver while device calibration
is going on. Registering driver shall wait for calibration to complete
for a certain time. Also prevent calibration started from driver side
if device is already active.

Change-Id: I7d5697fef007572fe15bfa0170555f5f83c44012
Signed-off-by: default avatarYue Ma <yuem@codeaurora.org>
parent 55d2d6f0
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -1039,19 +1039,34 @@ static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
{
	int ret = 0;

	if (test_bit(CNSS_FW_READY, &plat_priv->driver_state) ||
	    test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
	    test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
		cnss_pr_dbg("Device is already active, ignore calibration\n");
		goto out;
	}

	set_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
	reinit_completion(&plat_priv->cal_complete);
	ret = cnss_bus_dev_powerup(plat_priv);
	if (ret)
	if (ret) {
		complete(&plat_priv->cal_complete);
		clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
	}

out:
	return ret;
}

static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv)
{
	if (!test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
		return 0;

	plat_priv->cal_done = true;
	cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
	cnss_bus_dev_shutdown(plat_priv);
	complete(&plat_priv->cal_complete);
	clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);

	return 0;
@@ -1641,6 +1656,7 @@ static int cnss_probe(struct platform_device *plat_dev)
			    ret);

	init_completion(&plat_priv->power_up_complete);
	init_completion(&plat_priv->cal_complete);
	mutex_init(&plat_priv->dev_lock);

	cnss_pr_info("Platform driver probed successfully.\n");
@@ -1676,6 +1692,7 @@ static int cnss_remove(struct platform_device *plat_dev)
{
	struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev);

	complete_all(&plat_priv->cal_complete);
	complete_all(&plat_priv->power_up_complete);
	device_init_wakeup(&plat_dev->dev, false);
	unregister_pm_notifier(&cnss_pm_notifier);
+1 −0
Original line number Diff line number Diff line
@@ -243,6 +243,7 @@ struct cnss_plat_data {
	atomic_t pm_count;
	struct timer_list fw_boot_timer;
	struct completion power_up_complete;
	struct completion cal_complete;
	struct mutex dev_lock; /* mutex for register access through debugfs */
	u32 diag_reg_read_addr;
	u32 diag_reg_read_mem_type;
+18 −0
Original line number Diff line number Diff line
@@ -693,6 +693,7 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
	int ret = 0;
	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
	struct cnss_pci_data *pci_priv;
	unsigned int timeout;

	if (!plat_priv) {
		cnss_pr_err("plat_priv is NULL\n");
@@ -710,10 +711,27 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
		return -EEXIST;
	}

	if (!test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
		goto register_driver;

	cnss_pr_dbg("Start to wait for calibration to complete\n");

	timeout = cnss_get_boot_timeout(&pci_priv->pci_dev->dev);
	ret = wait_for_completion_timeout(&plat_priv->cal_complete,
					  msecs_to_jiffies(timeout) << 2);
	if (!ret) {
		cnss_pr_err("Timeout waiting for calibration to complete\n");
		ret = -EAGAIN;
		goto out;
	}

register_driver:
	ret = cnss_driver_event_post(plat_priv,
				     CNSS_DRIVER_EVENT_REGISTER_DRIVER,
				     CNSS_EVENT_SYNC_UNINTERRUPTIBLE,
				     driver_ops);

out:
	return ret;
}
EXPORT_SYMBOL(cnss_wlan_register_driver);