From 766debf6bbc3aa6aab8cea8f7383dacc59e1f55d Mon Sep 17 00:00:00 2001 From: Naman Padhiar Date: Wed, 11 May 2022 16:42:15 +0530 Subject: [PATCH] icnss: Add ASSERT if fw ready got timed out Add ASSERT when FW READY got timed out to debug why FW READY indication is not come. Change-Id: I0def3d0bd945f1cfe25c8c5fa48b593bb0556b03 Signed-off-by: Naman Padhiar --- drivers/soc/qcom/icnss2/main.c | 21 +++++++++++++++++++++ drivers/soc/qcom/icnss2/main.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/drivers/soc/qcom/icnss2/main.c b/drivers/soc/qcom/icnss2/main.c index 462d4bb807d7..ac5b2ae64099 100644 --- a/drivers/soc/qcom/icnss2/main.c +++ b/drivers/soc/qcom/icnss2/main.c @@ -82,6 +82,8 @@ module_param(qmi_timeout, ulong, 0600); #define WLFW_TIMEOUT msecs_to_jiffies(3000) #endif +#define ICNSS_RECOVERY_TIMEOUT 60000 + static struct icnss_priv *penv; static struct work_struct wpss_loader; uint64_t dynamic_feature_mask = ICNSS_DEFAULT_FEATURE_MASK; @@ -869,6 +871,9 @@ static int icnss_driver_event_fw_ready_ind(struct icnss_priv *priv, void *data) if (!priv) return -ENODEV; + if (priv->device_id == ADRASTEA_DEVICE_ID) + del_timer(&priv->recovery_timer); + set_bit(ICNSS_FW_READY, &priv->state); clear_bit(ICNSS_MODE_ON, &priv->state); atomic_set(&priv->soc_wake_ref_count, 0); @@ -1854,6 +1859,9 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, } icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, ICNSS_EVENT_SYNC, event_data); + + mod_timer(&priv->recovery_timer, + jiffies + msecs_to_jiffies(ICNSS_RECOVERY_TIMEOUT)); out: icnss_pr_vdbg("Exit %s,state: 0x%lx\n", __func__, priv->state); return NOTIFY_OK; @@ -2022,6 +2030,9 @@ event_post: clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state); icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, ICNSS_EVENT_SYNC, event_data); + + mod_timer(&priv->recovery_timer, + jiffies + msecs_to_jiffies(ICNSS_RECOVERY_TIMEOUT)); done: if (notification == SERVREG_NOTIF_SERVICE_STATE_UP_V01) clear_bit(ICNSS_FW_DOWN, &priv->state); @@ -4107,6 +4118,9 @@ static int icnss_probe(struct platform_device *pdev) #ifdef CONFIG_ICNSS2_RESTART_LEVEL_NOTIF register_trace_pil_restart_level(pil_restart_level_notifier, NULL); #endif + } else { + timer_setup(&priv->recovery_timer, + icnss_recovery_timeout_hdlr, 0); } INIT_LIST_HEAD(&priv->icnss_tcdev_list); @@ -4183,6 +4197,13 @@ static int icnss_remove(struct platform_device *pdev) return 0; } +void icnss_recovery_timeout_hdlr(struct timer_list *t) +{ + struct icnss_priv *priv = from_timer(priv, t, recovery_timer); + + icnss_pr_err("Timeout waiting for FW Ready 0x%lx\n", priv->state); + ICNSS_ASSERT(0); +} #ifdef CONFIG_PM_SLEEP static int icnss_pm_suspend(struct device *dev) { diff --git a/drivers/soc/qcom/icnss2/main.h b/drivers/soc/qcom/icnss2/main.h index 8ff61897b8a9..2c13b3b442a4 100644 --- a/drivers/soc/qcom/icnss2/main.h +++ b/drivers/soc/qcom/icnss2/main.h @@ -18,6 +18,7 @@ #include #include #include "wlan_firmware_service_v01.h" +#include #define WCN6750_DEVICE_ID 0x6750 #define ADRASTEA_DEVICE_ID 0xabcd @@ -466,6 +467,7 @@ struct icnss_priv { u8 use_nv_mac; u32 wlan_en_delay_ms; unsigned long device_config; + struct timer_list recovery_timer; }; struct icnss_reg_info { @@ -493,5 +495,6 @@ int icnss_get_cpr_info(struct icnss_priv *priv); int icnss_update_cpr_info(struct icnss_priv *priv); void icnss_add_fw_prefix_name(struct icnss_priv *priv, char *prefix_name, char *name); +void icnss_recovery_timeout_hdlr(struct timer_list *t); #endif