Browse Source

icnss2: Handle AON ready event

During cold boot AON sends multiple DOWN and UP notifications
as part of its FW update. ICNSS driver should not initiate
any QMI handshakes and should wait till correct FW is flashed.

After successfully flashing correct FW, AON will send ready event.
Once AON ready event receives ICNSS driver sets AON ready bit and
proceeds with QMI handshakes.

Similarly in AON SSR, this change handles UP notification only if
AON ready bit is set.

Change-Id: I326d731cd3f619cef9fa8c072a1e898f4b21a6ce
CRs-Fixed: 3491699
Dundi Raviteja 1 year ago
parent
commit
de80f12c97
3 changed files with 60 additions and 2 deletions
  1. 3 0
      icnss2/debug.c
  2. 49 2
      icnss2/main.c
  3. 8 0
      icnss2/main.h

+ 3 - 0
icnss2/debug.c

@@ -423,6 +423,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
 		case ICNSS_SLATE_UP:
 			seq_puts(s, "ICNSS SLATE UP");
 			continue;
+		case ICNSS_SLATE_READY:
+			seq_puts(s, "ICNSS SLATE READY");
+			continue;
 		case ICNSS_LOW_POWER:
 			seq_puts(s, "ICNSS LOW POWER");
 		}

+ 49 - 2
icnss2/main.c

@@ -47,6 +47,8 @@
 #include <trace/hooks/remoteproc.h>
 #ifdef SLATE_MODULE_ENABLED
 #include <linux/soc/qcom/slatecom_interface.h>
+#include <linux/soc/qcom/slate_events_bridge_intf.h>
+#include <uapi/linux/slatecom_interface.h>
 #endif
 #include "main.h"
 #include "qmi.h"
@@ -2345,6 +2347,43 @@ static int icnss_wpss_ssr_register_notifier(struct icnss_priv *priv)
 }
 
 #ifdef SLATE_MODULE_ENABLED
+static int icnss_slate_event_notifier_nb(struct notifier_block *nb,
+					 unsigned long event, void *data)
+{
+	if (event == SLATE_STATUS) {
+		struct icnss_priv *priv = container_of(nb, struct icnss_priv,
+						       seb_nb);
+		enum boot_status status = *(enum boot_status *)data;
+
+		if (status == SLATE_READY) {
+			icnss_pr_dbg("Slate ready received, state: 0x%lx\n",
+				     priv->state);
+			set_bit(ICNSS_SLATE_READY, &priv->state);
+			set_bit(ICNSS_SLATE_UP, &priv->state);
+			complete(&priv->slate_boot_complete);
+		}
+	}
+
+	return NOTIFY_OK;
+}
+
+static int icnss_register_slate_event_notifier(struct icnss_priv *priv)
+{
+	int ret = 0;
+
+	priv->seb_nb.notifier_call = icnss_slate_event_notifier_nb;
+
+	priv->seb_handle = seb_register_for_slate_event(SLATE_STATUS,
+							&priv->seb_nb);
+	if (IS_ERR_OR_NULL(priv->seb_handle)) {
+		ret = priv->seb_handle ? PTR_ERR(priv->seb_handle) : -EINVAL;
+		icnss_pr_err("SLATE event register notifier failed: %d\n",
+			     ret);
+	}
+
+	return ret;
+}
+
 static int icnss_slate_notifier_nb(struct notifier_block *nb,
 				   unsigned long code,
 				   void *data)
@@ -2355,7 +2394,8 @@ static int icnss_slate_notifier_nb(struct notifier_block *nb,
 
 	icnss_pr_vdbg("Slate-subsys-notify: event %lu\n", code);
 
-	if (code == QCOM_SSR_AFTER_POWERUP) {
+	if (code == QCOM_SSR_AFTER_POWERUP &&
+	    test_bit(ICNSS_SLATE_READY, &priv->state)) {
 		set_bit(ICNSS_SLATE_UP, &priv->state);
 		complete(&priv->slate_boot_complete);
 		icnss_pr_dbg("Slate boot complete, state: 0x%lx\n",
@@ -2413,6 +2453,11 @@ static int icnss_slate_ssr_unregister_notifier(struct icnss_priv *priv)
 	return 0;
 }
 #else
+static int icnss_register_slate_event_notifier(struct icnss_priv *priv)
+{
+	return 0;
+}
+
 static int icnss_slate_ssr_register_notifier(struct icnss_priv *priv)
 {
 	return 0;
@@ -2756,8 +2801,10 @@ static int icnss_enable_recovery(struct icnss_priv *priv)
 
 	icnss_modem_ssr_register_notifier(priv);
 
-	if (priv->is_slate_rfa)
+	if (priv->is_slate_rfa) {
 		icnss_slate_ssr_register_notifier(priv);
+		icnss_register_slate_event_notifier(priv);
+	}
 
 	if (test_bit(SSR_ONLY, &priv->ctrl_params.quirks)) {
 		icnss_pr_dbg("PDR disabled through module parameter\n");

+ 8 - 0
icnss2/main.h

@@ -129,6 +129,7 @@ enum icnss_driver_state {
 	ICNSS_QMI_DMS_CONNECTED,
 	ICNSS_SLATE_SSR_REGISTERED,
 	ICNSS_SLATE_UP,
+	ICNSS_SLATE_READY,
 	ICNSS_LOW_POWER,
 };
 
@@ -368,6 +369,11 @@ struct icnss_ramdump_info {
 	struct device *dev;
 };
 
+#ifndef SLATE_MODULE_ENABLED
+struct seb_notif_info {
+};
+#endif
+
 struct icnss_priv {
 	uint32_t magic;
 	struct platform_device *pdev;
@@ -505,6 +511,8 @@ struct icnss_priv {
 	u32 rf_subtype;
 	u8 is_slate_rfa;
 	struct completion slate_boot_complete;
+	struct seb_notif_info *seb_handle;
+	struct notifier_block seb_nb;
 	struct timer_list recovery_timer;
 	struct timer_list wpss_ssr_timer;
 	bool wpss_self_recovery_enabled;