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

Commit 85f610cb authored by Yue Ma's avatar Yue Ma
Browse files

cnss2: Add mutex protection between unregister driver and idle restart



Since idle restart is a multiple stages power up sequence, there will be
race conditions when idle restart and unregister driver (which is power
down sequence) come at the same time. Add mutex protection for them so
that they can be serialized completely.

Change-Id: Icc28b5f759cd690cb505b16ab70eaa4abaf2e4cc
Signed-off-by: default avatarYue Ma <yuem@codeaurora.org>
parent e117350b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -665,6 +665,8 @@ int cnss_idle_restart(struct device *dev)
		return -ENODEV;
	}

	mutex_lock(&plat_priv->driver_ops_lock);

	cnss_pr_dbg("Doing idle restart\n");

	reinit_completion(&plat_priv->power_up_complete);
@@ -703,9 +705,11 @@ int cnss_idle_restart(struct device *dev)
		goto out;
	}

	mutex_unlock(&plat_priv->driver_ops_lock);
	return 0;

out:
	mutex_unlock(&plat_priv->driver_ops_lock);
	return ret;
}
EXPORT_SYMBOL(cnss_idle_restart);
@@ -2154,6 +2158,7 @@ static int cnss_misc_init(struct cnss_plat_data *plat_priv)
	init_completion(&plat_priv->rddm_complete);
	init_completion(&plat_priv->recovery_complete);
	mutex_init(&plat_priv->dev_lock);
	mutex_init(&plat_priv->driver_ops_lock);

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -361,6 +361,7 @@ struct cnss_plat_data {
	struct completion power_up_complete;
	struct completion cal_complete;
	struct mutex dev_lock; /* mutex for register access through debugfs */
	struct mutex driver_ops_lock; /* mutex for external driver ops */
	u32 device_freq_hz;
	u32 diag_reg_read_addr;
	u32 diag_reg_read_mem_type;
+5 −3
Original line number Diff line number Diff line
@@ -2126,9 +2126,9 @@ void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver_ops)
		return;
	}

	if (plat_priv->device_id == QCA6174_DEVICE_ID ||
	    !(test_bit(CNSS_DRIVER_IDLE_RESTART, &plat_priv->driver_state) ||
	      test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)))
	mutex_lock(&plat_priv->driver_ops_lock);

	if (plat_priv->device_id == QCA6174_DEVICE_ID)
		goto skip_wait_power_up;

	timeout = cnss_get_qmi_timeout(plat_priv);
@@ -2157,6 +2157,8 @@ void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver_ops)
	cnss_driver_event_post(plat_priv,
			       CNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
			       CNSS_EVENT_SYNC_UNKILLABLE, NULL);

	mutex_unlock(&plat_priv->driver_ops_lock);
}
EXPORT_SYMBOL(cnss_wlan_unregister_driver);