diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 16ab2400cd69..5b9281596c87 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -1763,11 +1763,29 @@ static void icnss_qmi_wlfw_clnt_notify(struct qmi_handle *handle, } } +static int icnss_call_driver_uevent(struct icnss_priv *priv, + enum icnss_uevent uevent, void *data) +{ + struct icnss_uevent_data uevent_data; + + if (!priv->ops || !priv->ops->uevent) + return 0; + + icnss_pr_dbg("Calling driver uevent state: 0x%lx, uevent: %d\n", + priv->state, uevent); + + uevent_data.uevent = uevent; + uevent_data.data = data; + + return priv->ops->uevent(&priv->pdev->dev, &uevent_data); +} + static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle, unsigned int msg_id, void *msg, unsigned int msg_len, void *ind_cb_priv) { struct icnss_event_pd_service_down_data *event_data; + struct icnss_uevent_fw_down_data fw_down_data; if (!penv) return; @@ -1799,6 +1817,9 @@ static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle, return; event_data->crashed = true; event_data->fw_rejuvenate = true; + fw_down_data.crashed = true; + icnss_call_driver_uevent(penv, ICNSS_UEVENT_FW_DOWN, + &fw_down_data); icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, 0, event_data); break; @@ -1912,23 +1933,6 @@ static int icnss_driver_event_server_exit(void *data) return 0; } -static int icnss_call_driver_uevent(struct icnss_priv *priv, - enum icnss_uevent uevent, void *data) -{ - struct icnss_uevent_data uevent_data; - - if (!priv->ops || !priv->ops->uevent) - return 0; - - icnss_pr_dbg("Calling driver uevent state: 0x%lx, uevent: %d\n", - priv->state, uevent); - - uevent_data.uevent = uevent; - uevent_data.data = data; - - return priv->ops->uevent(&priv->pdev->dev, &uevent_data); -} - static int icnss_call_driver_probe(struct icnss_priv *priv) { int ret; @@ -2308,6 +2312,7 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, struct notif_data *notif = data; struct icnss_priv *priv = container_of(nb, struct icnss_priv, modem_ssr_nb); + struct icnss_uevent_fw_down_data fw_down_data; icnss_pr_dbg("Modem-Notify: event %lu\n", code); @@ -2340,6 +2345,9 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, if (notif->crashed == CRASH_STATUS_WDOG_BITE) event_data->wdog_bite = true; + fw_down_data.crashed = !!notif->crashed; + icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN, &fw_down_data); + icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, ICNSS_EVENT_SYNC, event_data); @@ -2403,6 +2411,7 @@ static int icnss_service_notifier_notify(struct notifier_block *nb, service_notifier_nb); enum pd_subsys_state *state = data; struct icnss_event_pd_service_down_data *event_data; + struct icnss_uevent_fw_down_data fw_down_data; icnss_pr_dbg("PD service notification: 0x%lx state: 0x%lx\n", notification, priv->state); @@ -2438,6 +2447,8 @@ static int icnss_service_notifier_notify(struct notifier_block *nb, event_post: icnss_ignore_qmi_timeout(true); + fw_down_data.crashed = event_data->crashed; + icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN, &fw_down_data); icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, ICNSS_EVENT_SYNC, event_data); done: diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h index 731fa6970b95..7ef984afc442 100644 --- a/include/soc/qcom/icnss.h +++ b/include/soc/qcom/icnss.h @@ -20,6 +20,11 @@ enum icnss_uevent { ICNSS_UEVENT_FW_READY, ICNSS_UEVENT_FW_CRASHED, + ICNSS_UEVENT_FW_DOWN, +}; + +struct icnss_uevent_fw_down_data { + bool crashed; }; struct icnss_uevent_data {