[PATCH 7/7] v4l: vsp1: debugfs: Add DLM directory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Provide the ability to output a display list in use over debugfs.

In the event that the hardware has hung, it should be possible to
identify the current/most recent display list written to hardware by
viewing the DLM->active file:

 cat /debugfs/fe9a0000.vsp/DLM/active

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@xxxxxxxxxxxxxxxx>

--
2021-05-05:
 - Don't store dentry pointers which are not used

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@xxxxxxxxxxxxxxxx>
---
 drivers/media/platform/renesas/vsp1/vsp1_dl.c | 107 ++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/drivers/media/platform/renesas/vsp1/vsp1_dl.c b/drivers/media/platform/renesas/vsp1/vsp1_dl.c
index ad3fa1c9cc73..f75ecc5b485e 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_dl.c
@@ -17,6 +17,8 @@
 #include "vsp1.h"
 #include "vsp1_dl.h"
 
+#include "vsp1_debugfs.h"
+
 #define VSP1_DL_NUM_ENTRIES		256
 
 #define VSP1_DLH_INT_ENABLE		(1 << 1)
@@ -226,6 +228,8 @@ struct vsp1_dl_manager {
 
 	struct vsp1_dl_body_pool *pool;
 	struct vsp1_dl_cmd_pool *cmdpool;
+
+	struct dentry *dbgroot;
 };
 
 /* -----------------------------------------------------------------------------
@@ -1086,6 +1090,105 @@ struct vsp1_dl_body *vsp1_dlm_dl_body_get(struct vsp1_dl_manager *dlm)
 	return vsp1_dl_body_get(dlm->pool);
 }
 
+/* -----------------------------------------------------------------------------
+ * Debugfs internal views
+ */
+
+static void seq_print_list_body(struct seq_file *s, struct vsp1_dl_body *dlb)
+{
+	int i;
+
+	for (i = 0; i < dlb->num_entries; i++) {
+		struct vsp1_dl_entry *e = &dlb->entries[i];
+
+		seq_printf(s, "0x%08x -> %s\n", e->data,
+			   vsp1_reg_to_name(e->addr));
+	}
+}
+
+static void seq_printf_dl(struct seq_file *s, struct vsp1_dl_list *dl)
+{
+	struct vsp1_dl_body *dlb;
+	struct vsp1_dl_list *child;
+
+	if (!dl)
+		return;
+
+	seq_print_list_body(s, dl->body0);
+
+	list_for_each_entry(dlb, &dl->bodies, list)
+		seq_print_list_body(s, dlb);
+
+	if (dl->has_chain)
+		list_for_each_entry(child, &dl->chain, chain)
+			seq_print_list_body(s, child->body0);
+}
+
+static int vsp1_debugfs_dlm_active(struct seq_file *s, void *p)
+{
+	struct vsp1_dl_manager *dlm = s->private;
+
+	seq_printf_dl(s, dlm->active);
+
+	return 0;
+}
+
+DEBUGFS_RO_ATTR(vsp1_debugfs_dlm_active);
+
+static int vsp1_debugfs_dlm_pending(struct seq_file *s, void *p)
+{
+	struct vsp1_dl_manager *dlm = s->private;
+
+	seq_printf_dl(s, dlm->pending);
+
+	return 0;
+}
+
+DEBUGFS_RO_ATTR(vsp1_debugfs_dlm_pending);
+
+static int vsp1_debugfs_dlm_queued(struct seq_file *s, void *p)
+{
+	struct vsp1_dl_manager *dlm = s->private;
+
+	seq_printf_dl(s, dlm->queued);
+
+	return 0;
+}
+
+DEBUGFS_RO_ATTR(vsp1_debugfs_dlm_queued);
+
+/* Debugfs initialised after entities are created */
+static int vsp1_debugfs_init_dlm(struct vsp1_dl_manager *dlm)
+{
+	struct vsp1_device *vsp1 = dlm->vsp1;
+
+	dlm->dbgroot = debugfs_create_dir("DLM", vsp1->dbgroot);
+	if (!dlm->dbgroot)
+		return -ENOMEM;
+
+	/* dentry pointers discarded */
+	debugfs_create_file("active", 0444, dlm->dbgroot, dlm,
+			    &vsp1_debugfs_dlm_active_fops);
+
+	debugfs_create_file("pending", 0444, dlm->dbgroot, dlm,
+			    &vsp1_debugfs_dlm_pending_fops);
+
+	debugfs_create_file("queued", 0444, dlm->dbgroot, dlm,
+			    &vsp1_debugfs_dlm_queued_fops);
+
+	return 0;
+}
+
+static void vsp1_debugfs_destroy_dlm(struct vsp1_dl_manager *dlm)
+{
+	debugfs_remove(dlm->dbgroot);
+	dlm->dbgroot = NULL;
+}
+
+/* -----------------------------------------------------------------------------
+ * Object creation and destruction
+ */
+
 struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 					unsigned int index,
 					unsigned int prealloc)
@@ -1149,6 +1252,8 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 		}
 	}
 
+	vsp1_debugfs_init_dlm(dlm);
+
 	return dlm;
 }
 
@@ -1159,6 +1264,8 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
 	if (!dlm)
 		return;
 
+	vsp1_debugfs_destroy_dlm(dlm);
+
 	list_for_each_entry_safe(dl, next, &dlm->free, list) {
 		list_del(&dl->list);
 		vsp1_dl_list_free(dl);
-- 
2.34.1




[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux