wcnss: add subsystem failure reason for wcnss
Print a message to kernel log indicating the reason
for failure of wcnss subsystem. The failure reason
is provided by wcnss subsystem, when available.
Change-Id: Ifa86e207b8941d5b14cd7a8d04c4593bbb997d4c
Signed-off-by: Sunny Kapdi <sunnyk@codeaurora.org>
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 90948ea..266c8b4 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -28,6 +28,7 @@
#include "ramdump.h"
#define MODULE_NAME "wcnss_8960"
+#define MAX_BUF_SIZE 0x51
static void riva_smsm_cb_fn(struct work_struct *);
static DECLARE_WORK(riva_smsm_cb_work, riva_smsm_cb_fn);
@@ -52,12 +53,37 @@
static void smsm_state_cb_hdlr(void *data, uint32_t old_state,
uint32_t new_state)
{
+ char *smem_reset_reason;
+ char buffer[MAX_BUF_SIZE];
+ unsigned smem_reset_size;
+ unsigned size;
+
if (!(new_state & SMSM_RESET))
return;
riva_crash = true;
pr_err("%s: smsm state changed to smsm reset\n", MODULE_NAME);
+ smem_reset_reason = smem_get_entry(SMEM_SSR_REASON_WCNSS0,
+ &smem_reset_size);
+
+ if (!smem_reset_reason || !smem_reset_size) {
+ pr_err("%s: wcnss subsystem failure reason: %s\n", __func__,
+ "(unknown, smem_get_entry failed)");
+ } else if (!smem_reset_reason[0]) {
+ pr_err("%s: wcnss subsystem failure reason: %s\n", __func__,
+ "(unknown, init string found)");
+ } else {
+ size = smem_reset_size < MAX_BUF_SIZE ? smem_reset_size :
+ (MAX_BUF_SIZE - 1);
+ memcpy(buffer, smem_reset_reason, size);
+ buffer[size] = '\0';
+ pr_err("%s: wcnss subsystem failure reason: %s\n", __func__,
+ buffer);
+ memset(smem_reset_reason, 0, smem_reset_size);
+ wmb();
+ }
+
if (ss_restart_inprogress) {
pr_err("%s: Ignoring smsm reset req, restart in progress\n",
MODULE_NAME);