|
@@ -99,7 +99,7 @@ enum cnss_recovery_type {
|
|
|
#ifdef CONFIG_CNSS_SUPPORT_DUAL_DEV
|
|
|
#define CNSS_MAX_DEV_NUM 2
|
|
|
static struct cnss_plat_data *plat_env[CNSS_MAX_DEV_NUM];
|
|
|
-static int plat_env_count;
|
|
|
+static atomic_t plat_env_count;
|
|
|
#else
|
|
|
static struct cnss_plat_data *plat_env;
|
|
|
#endif
|
|
@@ -131,14 +131,41 @@ bool cnss_check_driver_loading_allowed(void)
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_CNSS_SUPPORT_DUAL_DEV
|
|
|
+static void cnss_init_plat_env_count(void)
|
|
|
+{
|
|
|
+ atomic_set(&plat_env_count, 0);
|
|
|
+}
|
|
|
+
|
|
|
+static void cnss_inc_plat_env_count(void)
|
|
|
+{
|
|
|
+ atomic_inc(&plat_env_count);
|
|
|
+}
|
|
|
+
|
|
|
+static void cnss_dec_plat_env_count(void)
|
|
|
+{
|
|
|
+ atomic_dec(&plat_env_count);
|
|
|
+}
|
|
|
+
|
|
|
+static int cnss_get_plat_env_count(void)
|
|
|
+{
|
|
|
+ return atomic_read(&plat_env_count);
|
|
|
+}
|
|
|
+
|
|
|
+int cnss_get_max_plat_env_count(void)
|
|
|
+{
|
|
|
+ return CNSS_MAX_DEV_NUM;
|
|
|
+}
|
|
|
+
|
|
|
static void cnss_set_plat_priv(struct platform_device *plat_dev,
|
|
|
struct cnss_plat_data *plat_priv)
|
|
|
{
|
|
|
- cnss_pr_dbg("Set plat_priv at %d", plat_env_count);
|
|
|
+ int env_count = cnss_get_plat_env_count();
|
|
|
+
|
|
|
+ cnss_pr_dbg("Set plat_priv at %d", env_count);
|
|
|
if (plat_priv) {
|
|
|
- plat_priv->plat_idx = plat_env_count;
|
|
|
+ plat_priv->plat_idx = env_count;
|
|
|
plat_env[plat_priv->plat_idx] = plat_priv;
|
|
|
- plat_env_count++;
|
|
|
+ cnss_inc_plat_env_count();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -150,8 +177,8 @@ struct cnss_plat_data *cnss_get_plat_priv(struct platform_device
|
|
|
if (!plat_dev)
|
|
|
return NULL;
|
|
|
|
|
|
- for (i = 0; i < plat_env_count; i++) {
|
|
|
- if (plat_env[i]->plat_dev == plat_dev)
|
|
|
+ for (i = 0; i < CNSS_MAX_DEV_NUM; i++) {
|
|
|
+ if (plat_env[i] && plat_env[i]->plat_dev == plat_dev)
|
|
|
return plat_env[i];
|
|
|
}
|
|
|
return NULL;
|
|
@@ -163,7 +190,7 @@ struct cnss_plat_data *cnss_get_first_plat_priv(struct platform_device
|
|
|
int i;
|
|
|
|
|
|
if (!plat_dev) {
|
|
|
- for (i = 0; i < plat_env_count; i++) {
|
|
|
+ for (i = 0; i < CNSS_MAX_DEV_NUM; i++) {
|
|
|
if (plat_env[i])
|
|
|
return plat_env[i];
|
|
|
}
|
|
@@ -175,7 +202,7 @@ static void cnss_clear_plat_priv(struct cnss_plat_data *plat_priv)
|
|
|
{
|
|
|
cnss_pr_dbg("Clear plat_priv at %d", plat_priv->plat_idx);
|
|
|
plat_env[plat_priv->plat_idx] = NULL;
|
|
|
- plat_env_count--;
|
|
|
+ cnss_dec_plat_env_count();
|
|
|
}
|
|
|
|
|
|
static int cnss_set_device_name(struct cnss_plat_data *plat_priv)
|
|
@@ -189,19 +216,15 @@ static int cnss_set_device_name(struct cnss_plat_data *plat_priv)
|
|
|
static int cnss_plat_env_available(void)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
+ int env_count = cnss_get_plat_env_count();
|
|
|
|
|
|
- if (plat_env_count >= CNSS_MAX_DEV_NUM) {
|
|
|
+ if (env_count >= CNSS_MAX_DEV_NUM) {
|
|
|
cnss_pr_err("ERROR: No space to store plat_priv\n");
|
|
|
ret = -ENOMEM;
|
|
|
}
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-int cnss_get_plat_env_count(void)
|
|
|
-{
|
|
|
- return plat_env_count;
|
|
|
-}
|
|
|
-
|
|
|
struct cnss_plat_data *cnss_get_plat_env(int index)
|
|
|
{
|
|
|
return plat_env[index];
|
|
@@ -211,8 +234,8 @@ struct cnss_plat_data *cnss_get_plat_priv_by_rc_num(int rc_num)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
- for (i = 0; i < plat_env_count; i++) {
|
|
|
- if (plat_env[i]->rc_num == rc_num)
|
|
|
+ for (i = 0; i < CNSS_MAX_DEV_NUM; i++) {
|
|
|
+ if (plat_env[i] && plat_env[i]->rc_num == rc_num)
|
|
|
return plat_env[i];
|
|
|
}
|
|
|
return NULL;
|
|
@@ -251,6 +274,10 @@ cnss_get_pld_bus_ops_name(struct cnss_plat_data *plat_priv)
|
|
|
}
|
|
|
|
|
|
#else
|
|
|
+static void cnss_init_plat_env_count(void)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
static void cnss_set_plat_priv(struct platform_device *plat_dev,
|
|
|
struct cnss_plat_data *plat_priv)
|
|
|
{
|
|
@@ -2470,6 +2497,25 @@ int cnss_qmi_send(struct device *dev, int type, void *cmd,
|
|
|
}
|
|
|
EXPORT_SYMBOL(cnss_qmi_send);
|
|
|
|
|
|
+int cnss_register_driver_async_data_cb(struct device *dev, void *cb_ctx,
|
|
|
+ int (*cb)(void *ctx, uint16_t type,
|
|
|
+ void *event, int event_len))
|
|
|
+{
|
|
|
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
|
|
+
|
|
|
+ if (!plat_priv)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ if (!test_bit(CNSS_QMI_WLFW_CONNECTED, &plat_priv->driver_state))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ plat_priv->get_driver_async_data_cb = cb;
|
|
|
+ plat_priv->get_driver_async_data_ctx = cb_ctx;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(cnss_register_driver_async_data_cb);
|
|
|
+
|
|
|
static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
|
|
|
{
|
|
|
int ret = 0;
|
|
@@ -3072,6 +3118,10 @@ int cnss_do_ramdump(struct cnss_plat_data *plat_priv)
|
|
|
struct qcom_dump_segment segment;
|
|
|
struct list_head head;
|
|
|
|
|
|
+ if (!dump_enabled()) {
|
|
|
+ cnss_pr_info("Dump collection is not enabled\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
INIT_LIST_HEAD(&head);
|
|
|
memset(&segment, 0, sizeof(segment));
|
|
|
segment.va = ramdump_info->ramdump_va;
|
|
@@ -5676,6 +5726,7 @@ static int __init cnss_initialize(void)
|
|
|
if (ret < 0)
|
|
|
cnss_pr_err("CNSS genl init failed %d\n", ret);
|
|
|
|
|
|
+ cnss_init_plat_env_count();
|
|
|
return ret;
|
|
|
}
|
|
|
|