diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/soc/qcom/icnss.c | 23 |
1 files changed, 21 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); |
