ASoC: wcd934x: WDSP debug enhancement

Add interface to trigger WDSP dumps for debug use.
Important register dump and WDSP ramdump are both collected when
DEBUG_DUMP string is sent from userspace via WDSP misc node or
when WDSP boot timeout happens.

CRs-Fixed: 2117755
Change-Id: I8b91a8939201a54512a5e3557ce771b4ff2ff075
Signed-off-by: Walter Yang <yandongy@codeaurora.org>
diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c
index 6cc9f8c..9bcb635 100644
--- a/asoc/codecs/wcd-dsp-mgr.c
+++ b/asoc/codecs/wcd-dsp-mgr.c
@@ -838,6 +838,45 @@
 	return 0;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg)
+{
+	struct wdsp_err_signal_arg *err_data;
+	int ret = 0;
+
+	WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex);
+	/* If there is no SSR, set the SSR type to collect ramdumps */
+	if (wdsp->ssr_type == WDSP_SSR_TYPE_NO_SSR) {
+		wdsp->ssr_type = WDSP_SSR_TYPE_WDSP_DOWN;
+	} else {
+		WDSP_DBG(wdsp, "SSR handling is running, skip debug ramdump");
+		ret = 0;
+		WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
+		goto done;
+	}
+	if (arg) {
+		err_data = (struct wdsp_err_signal_arg *) arg;
+		memcpy(&wdsp->dump_data.err_data, err_data,
+		       sizeof(*err_data));
+	} else {
+		WDSP_DBG(wdsp, "Invalid input, arg is NULL");
+		ret = -EINVAL;
+		WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
+		goto done;
+	}
+	wdsp_collect_ramdumps(wdsp);
+	wdsp->ssr_type = WDSP_SSR_TYPE_NO_SSR;
+	WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
+done:
+	return ret;
+}
+#else
+static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg)
+{
+	return 0;
+}
+#endif
+
 static int wdsp_signal_handler(struct device *wdsp_dev,
 			       enum wdsp_signal signal, void *arg)
 {
@@ -866,6 +905,9 @@
 	case WDSP_CDC_UP_SIGNAL:
 		ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_UP);
 		break;
+	case WDSP_DEBUG_DUMP:
+		ret = wdsp_debug_dump_handler(wdsp, arg);
+		break;
 	default:
 		ret = -EINVAL;
 		break;