diff options
| -rw-r--r-- | drivers/soc/qcom/icnss.c | 23 | ||||
| -rw-r--r-- | include/soc/qcom/icnss.h | 1 |
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); |
