summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhalchandra Gajare <gajare@codeaurora.org>2017-04-05 18:24:23 -0700
committerBhalchandra Gajare <gajare@codeaurora.org>2017-04-18 14:47:43 -0700
commitb121d52808308e7834c48db048f5e7160a5f6430 (patch)
treeb8382c6c4beb5f49bc5cadde24f2aa8d89ddec8e
parent1c450066c7c30a84ab95adc8674833508418e4a3 (diff)
ASoC: wcd-dsp-mgr: force crash upon collecting ramdumps
In case of WDSP fatal errors, subsystem restart is done to reset the WDSP. Currently, the driver performs subsystem restart silently and does not cause devie crash. Add debugfs property 'panic_on_error' to indicate the driver to induce BUG_ON to aid debugging. The BUG_ON is done only when the debugfs property is explicity set through debugfs. If not set, the driver will continue without crashing. The below command can be used to set the debugfs property. echo Y > /sys/kernel/debug/wdsp_mgr/panic_on_error CRs-fixed: 2029058 Change-Id: I1442cc59e1819c3b0abd4c4776f4b32ba63d59e2 Signed-off-by: Bhalchandra Gajare <gajare@codeaurora.org>
-rw-r--r--sound/soc/codecs/wcd-dsp-mgr.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c
index 71a2052f1089..9b1c8c98946c 100644
--- a/sound/soc/codecs/wcd-dsp-mgr.c
+++ b/sound/soc/codecs/wcd-dsp-mgr.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/stringify.h>
#include <linux/of.h>
+#include <linux/debugfs.h>
#include <linux/component.h>
#include <linux/dma-mapping.h>
#include <soc/qcom/ramdump.h>
@@ -181,6 +182,10 @@ struct wdsp_mgr_priv {
struct work_struct ssr_work;
u16 ready_status;
struct completion ready_compl;
+
+ /* Debugfs related */
+ struct dentry *entry;
+ bool panic_on_error;
};
static char *wdsp_get_ssr_type_string(enum wdsp_ssr_type type)
@@ -655,6 +660,12 @@ static void wdsp_collect_ramdumps(struct wdsp_mgr_priv *wdsp)
goto err_read_dumps;
}
+ /*
+ * If panic_on_error flag is explicitly set through the debugfs,
+ * then cause a BUG here to aid debugging.
+ */
+ BUG_ON(wdsp->panic_on_error);
+
rd_seg.address = (unsigned long) wdsp->dump_data.rd_v_addr;
rd_seg.size = img_section.size;
rd_seg.v_address = wdsp->dump_data.rd_v_addr;
@@ -948,6 +959,22 @@ static int wdsp_mgr_compare_of(struct device *dev, void *data)
!strcmp(dev_name(dev), cmpnt->cdev_name)));
}
+static void wdsp_mgr_debugfs_init(struct wdsp_mgr_priv *wdsp)
+{
+ wdsp->entry = debugfs_create_dir("wdsp_mgr", NULL);
+ if (IS_ERR_OR_NULL(wdsp->entry))
+ return;
+
+ debugfs_create_bool("panic_on_error", S_IRUGO | S_IWUSR,
+ wdsp->entry, &wdsp->panic_on_error);
+}
+
+static void wdsp_mgr_debugfs_remove(struct wdsp_mgr_priv *wdsp)
+{
+ debugfs_remove_recursive(wdsp->entry);
+ wdsp->entry = NULL;
+}
+
static int wdsp_mgr_bind(struct device *dev)
{
struct wdsp_mgr_priv *wdsp = dev_get_drvdata(dev);
@@ -977,6 +1004,8 @@ static int wdsp_mgr_bind(struct device *dev)
}
}
+ wdsp_mgr_debugfs_init(wdsp);
+
/* Schedule the work to download image if binding was successful. */
if (!ret)
schedule_work(&wdsp->load_fw_work);
@@ -992,6 +1021,8 @@ static void wdsp_mgr_unbind(struct device *dev)
component_unbind_all(dev, wdsp->ops);
+ wdsp_mgr_debugfs_remove(wdsp);
+
if (wdsp->dump_data.rd_dev) {
destroy_ramdump_device(wdsp->dump_data.rd_dev);
wdsp->dump_data.rd_dev = NULL;