From 21d31ab5eb49c24cd1fe2265f8652cf4973e4044 Mon Sep 17 00:00:00 2001
From: Anurag Chouhan <achouhan@codeaurora.org>
Date: Mon, 7 Aug 2017 15:12:49 +0530
Subject: [PATCH] icnss: Delay Shutdown/reinit sequence for all cases

PD down notifications reaches APPS only after WLAN HW is
reset. Because of this, there is a small window of time
in which APPS may try to access WLAN HW Copy Engine
registers and get into exception. To avoid this, FW has
implemented 2 stage reset sequence in which first HW is
halted rather than reset and then when FW PD is started
again, reset sequence is executed. Because of the 2
stage reset sequence, WLAN shutdown call back also needs
to be delayed as there may be some buffers submitted to
hardware and if they are freed then again HW exception
may be seen. Delay the shutdown call back till FW ready
happens at this time HW should be reset and clean state.

CRs-fixed: 2056443
Change-Id: Ie587f98d574f7c0a49a8480449fed44c1f4ab816
Signed-off-by: Anurag Chouhan <achouhan@codeaurora.org>
---
 drivers/soc/qcom/icnss.c | 25 ++-----------------------
 1 file changed, 2 insertions(+), 23 deletions(-)

diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index bf815cb68f90..39e76072f596 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -266,7 +266,6 @@ struct icnss_msa_perm_list_t msa_perm_list[ICNSS_MSA_PERM_MAX] = {
 struct icnss_event_pd_service_down_data {
 	bool crashed;
 	bool fw_rejuvenate;
-	bool wdog_bite;
 };
 
 struct icnss_driver_event {
@@ -291,7 +290,6 @@ enum icnss_driver_state {
 	ICNSS_PD_RESTART,
 	ICNSS_MSA0_ASSIGNED,
 	ICNSS_WLFW_EXISTS,
-	ICNSS_WDOG_BITE,
 	ICNSS_SHUTDOWN_DONE,
 	ICNSS_HOST_TRIGGERED_PDR,
 };
@@ -2149,10 +2147,7 @@ static int icnss_pd_restart_complete(struct icnss_priv *priv)
 
 	icnss_pm_relax(priv);
 
-	if (test_bit(ICNSS_WDOG_BITE, &priv->state)) {
-		icnss_call_driver_shutdown(priv);
-		clear_bit(ICNSS_WDOG_BITE, &priv->state);
-	}
+	icnss_call_driver_shutdown(priv);
 
 	clear_bit(ICNSS_PD_RESTART, &priv->state);
 
@@ -2302,8 +2297,7 @@ static int icnss_call_driver_remove(struct icnss_priv *priv)
 static int icnss_fw_crashed(struct icnss_priv *priv,
 			    struct icnss_event_pd_service_down_data *event_data)
 {
-	icnss_pr_dbg("FW crashed, state: 0x%lx, wdog_bite: %d\n",
-		     priv->state, event_data->wdog_bite);
+	icnss_pr_dbg("FW crashed, state: 0x%lx\n", priv->state);
 
 	set_bit(ICNSS_PD_RESTART, &priv->state);
 	clear_bit(ICNSS_FW_READY, &priv->state);
@@ -2313,17 +2307,9 @@ static int icnss_fw_crashed(struct icnss_priv *priv,
 	if (test_bit(ICNSS_DRIVER_PROBED, &priv->state))
 		icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_CRASHED, NULL);
 
-	if (event_data->wdog_bite) {
-		set_bit(ICNSS_WDOG_BITE, &priv->state);
-		goto out;
-	}
-
-	icnss_call_driver_shutdown(priv);
-
 	if (event_data->fw_rejuvenate)
 		wlfw_rejuvenate_ack_send_sync_msg(priv);
 
-out:
 	return 0;
 }
 
@@ -2520,9 +2506,6 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
 
 	event_data->crashed = notif->crashed;
 
-	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);
 
@@ -2612,7 +2595,6 @@ static int icnss_service_notifier_notify(struct notifier_block *nb,
 
 	switch (*state) {
 	case ROOT_PD_WDOG_BITE:
-		event_data->wdog_bite = true;
 		priv->stats.recovery.root_pd_crash++;
 		break;
 	case ROOT_PD_SHUTDOWN:
@@ -3832,9 +3814,6 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
 		case ICNSS_WLFW_EXISTS:
 			seq_puts(s, "WLAN FW EXISTS");
 			continue;
-		case ICNSS_WDOG_BITE:
-			seq_puts(s, "MODEM WDOG BITE");
-			continue;
 		case ICNSS_SHUTDOWN_DONE:
 			seq_puts(s, "SHUTDOWN DONE");
 			continue;