summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/soc/qcom/icnss.c23
-rw-r--r--include/soc/qcom/icnss.h1
2 files changed, 22 insertions, 2 deletions
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 1935f18c72f8..4ec3b6762cfd 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -297,6 +297,7 @@ enum icnss_driver_state {
ICNSS_SHUTDOWN_DONE,
ICNSS_HOST_TRIGGERED_PDR,
ICNSS_FW_DOWN,
+ ICNSS_DRIVER_UNLOADING,
};
struct ce_irq_list {
@@ -1167,6 +1168,16 @@ bool icnss_is_fw_ready(void)
}
EXPORT_SYMBOL(icnss_is_fw_ready);
+bool icnss_is_fw_down(void)
+{
+ if (!penv)
+ return false;
+ else
+ return test_bit(ICNSS_FW_DOWN, &penv->state);
+}
+EXPORT_SYMBOL(icnss_is_fw_down);
+
+
int icnss_power_off(struct device *dev)
{
struct icnss_priv *priv = dev_get_drvdata(dev);
@@ -2297,9 +2308,11 @@ static int icnss_driver_event_unregister_driver(void *data)
goto out;
}
+ set_bit(ICNSS_DRIVER_UNLOADING, &penv->state);
if (penv->ops)
penv->ops->remove(&penv->pdev->dev);
+ clear_bit(ICNSS_DRIVER_UNLOADING, &penv->state);
clear_bit(ICNSS_DRIVER_PROBED, &penv->state);
penv->ops = NULL;
@@ -2322,8 +2335,10 @@ static int icnss_call_driver_remove(struct icnss_priv *priv)
if (!priv->ops || !priv->ops->remove)
return 0;
+ set_bit(ICNSS_DRIVER_UNLOADING, &penv->state);
penv->ops->remove(&priv->pdev->dev);
+ clear_bit(ICNSS_DRIVER_UNLOADING, &penv->state);
clear_bit(ICNSS_DRIVER_PROBED, &priv->state);
icnss_hw_power_off(penv);
@@ -2529,7 +2544,8 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
icnss_ignore_qmi_timeout(true);
fw_down_data.crashed = !!notif->crashed;
- if (test_bit(ICNSS_FW_READY, &priv->state))
+ if (test_bit(ICNSS_FW_READY, &priv->state) &&
+ !test_bit(ICNSS_DRIVER_UNLOADING, &priv->state))
icnss_call_driver_uevent(priv,
ICNSS_UEVENT_FW_DOWN,
&fw_down_data);
@@ -2673,7 +2689,8 @@ event_post:
icnss_ignore_qmi_timeout(true);
fw_down_data.crashed = event_data->crashed;
- if (test_bit(ICNSS_FW_READY, &priv->state))
+ if (test_bit(ICNSS_FW_READY, &priv->state) &&
+ !test_bit(ICNSS_DRIVER_UNLOADING, &priv->state))
icnss_call_driver_uevent(priv,
ICNSS_UEVENT_FW_DOWN,
&fw_down_data);
@@ -3891,6 +3908,8 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
case ICNSS_FW_DOWN:
seq_puts(s, "FW DOWN");
continue;
+ case ICNSS_DRIVER_UNLOADING:
+ seq_puts(s, "DRIVER UNLOADING");
}
seq_printf(s, "UNKNOWN-%d", i);
diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h
index 7915841b17ea..4fff429dc0b2 100644
--- a/include/soc/qcom/icnss.h
+++ b/include/soc/qcom/icnss.h
@@ -153,6 +153,7 @@ extern int icnss_wlan_set_dfs_nol(const void *info, u16 info_len);
extern int icnss_wlan_get_dfs_nol(void *info, u16 info_len);
extern bool icnss_is_qmi_disable(struct device *dev);
extern bool icnss_is_fw_ready(void);
+extern bool icnss_is_fw_down(void);
extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len);
extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num);
extern int icnss_trigger_recovery(struct device *dev);