Skip to contentSkip to conversation

debugfs: a tool to print 32-bit registers

PATCH Applied Alessandro Rubini 4 participants 11 messages Nov 18, 2011 – Nov 22, 2011

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

v2 cover debugfs: a tool to print 32-bit registers

This is V2 of what I posted a few days ago. I also updates the file in Documentation. I Cc:d people who gave feedback.

Patch 2 uses the new tool for an existing file I didn't initially notice (I had a victim file, but it's seriously failing compilation). Code removal there is almost zero because Felipe Balbi already did stuff in the way I do.

Mark Brown suggested to look at drivers/base/regmap, and actually this may be duplicating what is already being worked on in a more general way. My code base is earlier than regmap so I didn't notice. Unfortunately I have no resources left to study regmap as it deserves.

Mark, if you say this is not useful at this point, I'm fine with it; I may return with some regbase-aware code when time permits if it's not already there.

/alessandro

Alessandro Rubini (2):
debugfs: add tools to printk 32-bit registers
usb: dwc3: use debugfs_print_regs32()

 Documentation/filesystems/debugfs.txt |   32 +++++++++++-
 drivers/usb/dwc3/debugfs.c            |   15 +----
 fs/debugfs/file.c                     |   90 +++++++++++++++++++++++++++++++++
 include/linux/debugfs.h               |   26 +++++++++
 4 files changed, 150 insertions(+), 13 deletions(-)
#1 lore raw
Quoted 14 lines · Alessandro Rubini

This is V2 of what I posted a few days ago. I also updates the file in Documentation. I Cc:d people who gave feedback.

Patch 2 uses the new tool for an existing file I didn't initially notice (I had a victim file, but it's seriously failing compilation). Code removal there is almost zero because Felipe Balbi already did stuff in the way I do.

Mark Brown suggested to look at drivers/base/regmap, and actually this may be duplicating what is already being worked on in a more general way. My code base is earlier than regmap so I didn't notice. Unfortunately I have no resources left to study regmap as it deserves.

Quoted 3 lines

Mark, if you say this is not useful at this point, I'm fine with it; I may return with some regbase-aware code when time permits if it's not already there.

-ENOPATCH ?? I didn't receive any replies to this mail with the patch. Is my mailer screwed up ?

Signature · 1 line
balbi
#2 lore raw
Quoted 1 line

-ENOPATCH ?? I didn't receive any replies to this mail with the patch.

You are right. Thanks and apologies. I mistyped Giancarlo Asnaghi's alias in all three, and the sending was interrupted. I resent now.

thanks
/alessandro

#3 lore raw

PATCH v2 1/2 debugfs: add tools to printk 32-bit registers

In reply to Alessandro Rubini

Some debugfs file I deal with are mostly blocks of registers, i.e. lines of the form "<name> = 0x<value>". Some files are only registers, some include registers blocks among other material. This patch introduces data structures and functions to deal with both cases. I expect more users of this over time.

---
 Documentation/filesystems/debugfs.txt |   32 +++++++++++-
 fs/debugfs/file.c                     |   90 +++++++++++++++++++++++++++++++++
 include/linux/debugfs.h               |   26 +++++++++
 3 files changed, 147 insertions(+), 1 deletions(-)
Documentation/filesystems/debugfs.txt +31 -1
index 742cc06..f04066a 100644
@@ -97,7 +97,8 @@ A read on the resulting file will yield either Y (for non-zero values) or
 N, followed by a newline.  If written to, it will accept either upper- or
 lower-case values, or 1 or 0.  Any other input will be silently ignored.
 
-Finally, a block of arbitrary binary data can be exported with:
+Another option is exporting a block of arbitrary binary data, with
+this structure and function:
 
     struct debugfs_blob_wrapper {
 	void *data;
@@ -115,6 +116,35 @@ can be used to export binary information, but there does not appear to be
 any code which does so in the mainline.  Note that all files created with
 debugfs_create_blob() are read-only.
 
+If you want to dump a block of registers (something that happens quite
+often during development, even if little such code reaches mainline.
+Debugfs offers two functions: one to make a registers-only file, and
+another to insert a register block in the middle of another sequential
+file.
+
+    struct debugfs_reg32 {
+	char *name;
+	unsigned long offset;
+    };
+
+    struct debugfs_regset32 {
+	struct debugfs_reg32 *regs;
+	int nregs;
+	void __iomem *base;
+    };
+
+    struct dentry *debugfs_create_regset32(const char *name, mode_t mode,
+				     struct dentry *parent,
+				     struct debugfs_regset32 *regset);
+
+    int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
+			 int nregs, void __iomem *base, char *prefix);
+
+The "base" argument may be 0, but you may want to build the reg32 array
+using __stringify, and a number of register names (macros) are actually
+byte offsets over a base for the register block.
+
+
 There are a couple of other directory-oriented helper functions:
 
     struct dentry *debugfs_rename(struct dentry *old_dir, 
fs/debugfs/file.c +90 -0

99 lines not on this page · raw message

include/linux/debugfs.h +26 -0
index e7d9b20..5e6b01f 100644
@@ -16,6 +16,7 @@
 #define _DEBUGFS_H_
 
 #include <linux/fs.h>
+#include <linux/seq_file.h>
 
 #include <linux/types.h>
 
@@ -26,6 +27,17 @@ struct debugfs_blob_wrapper {
 	unsigned long size;
 };
 
+struct debugfs_reg32 {
+	char *name;
+	unsigned long offset;
+};
+
+struct debugfs_regset32 {
+	struct debugfs_reg32 *regs;
+	int nregs;
+	void __iomem *base;
+};
+
 extern struct dentry *arch_debugfs_dir;
 
 #if defined(CONFIG_DEBUG_FS)
@@ -74,6 +86,13 @@ struct dentry *debugfs_create_blob(const char *name, mode_t mode,
 				  struct dentry *parent,
 				  struct debugfs_blob_wrapper *blob);
 
+struct dentry *debugfs_create_regset32(const char *name, mode_t mode,
+				     struct dentry *parent,
+				     struct debugfs_regset32 *regset);
+
+int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
+			 int nregs, void __iomem *base, char *prefix);
+
 bool debugfs_initialized(void);
 
 #else
@@ -188,6 +207,13 @@ static inline struct dentry *debugfs_create_blob(const char *name, mode_t mode,
 	return ERR_PTR(-ENODEV);
 }
 
+static inline struct dentry *debugfs_create_regset32(const char *name,
+				   mode_t mode, struct dentry *parent,
+				   struct debugfs_regset32 *regset)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline bool debugfs_initialized(void)
 {
 	return false;
Signature · 1 line
1.6.0.2
#4 lore raw

PATCH v2 2/2 usb: dwc3: use debugfs_print_regs32()

In reply to Alessandro Rubini

This a use example of the regs32 utilities in debugfs, although this fuse use ":" as separator between name and value, and debugs uses "=" (as it looked to me a more common practice).

---
 drivers/usb/dwc3/debugfs.c |   15 +++------------
 1 files changed, 3 insertions(+), 12 deletions(-)
drivers/usb/dwc3/debugfs.c +3 -12
index da1ad77..d9e7a26 100644
@@ -51,18 +51,13 @@
 #include "gadget.h"
 #include "io.h"
 
-struct dwc3_register {
-	const char	*name;
-	u32		offset;
-};
-
 #define dump_register(nm)				\
 {							\
 	.name	= __stringify(nm),			\
 	.offset	= DWC3_ ##nm,				\
 }
 
-static const struct dwc3_register dwc3_regs[] = {
+static const struct debugfs_reg32 dwc3_regs[] = {
 	dump_register(GSBUSCFG0),
 	dump_register(GSBUSCFG1),
 	dump_register(GTXTHRCFG),
@@ -385,12 +380,8 @@ static int dwc3_regdump_show(struct seq_file *s, void *unused)
 	int			i;
 
 	seq_printf(s, "DesignWare USB3 Core Register Dump\n");
-
-	for (i = 0; i < ARRAY_SIZE(dwc3_regs); i++) {
-		seq_printf(s, "%-20s :    %08x\n", dwc3_regs[i].name,
-				dwc3_readl(dwc->regs, dwc3_regs[i].offset));
-	}
-
+	debugfs_print_regs32(s, dwc3_regs, ARRAY_SIZE(dwc3_regs),
+			     dwc->regs, "");
 	return 0;
 }
 
Signature · 1 line
1.6.0.2
#5 lore raw

Re: [PATCH V2 2/2] usb: dwc3: use debugfs_print_regs32()

Quoted 6 lines · Alessandro Rubini

This a use example of the regs32 utilities in debugfs, although this fuse use ":" as separator between name and value, and debugs uses "=" (as it looked to me a more common practice).

Felipe, any objection to me applying this patch?

thanks,

greg k-h

Acked-by
#6 lore raw

Re: [PATCH V2 2/2] usb: dwc3: use debugfs_print_regs32()

Quoted 9 lines · Greg KH
Quoted 6 lines · Alessandro Rubini

This a use example of the regs32 utilities in debugfs, although this fuse use ":" as separator between name and value, and debugs uses "=" (as it looked to me a more common practice).

Felipe, any objection to me applying this patch?

none whatsoever:

Signature · 1 line
balbi
Applied
#7 lore raw

Re: [PATCH V2 2/2] usb: dwc3: use debugfs_print_regs32()

In reply to Alessandro Rubini
Quoted 6 lines · Alessandro Rubini

This a use example of the regs32 utilities in debugfs, although this fuse use ":" as separator between name and value, and debugs uses "=" (as it looked to me a more common practice).

I've applied this, but it causes the following complier warnings to be spit out:

drivers/usb/dwc3/debugfs.c: In function ‘dwc3_regdump_show’:
drivers/usb/dwc3/debugfs.c:384:9: warning: passing argument 2 of ‘debugfs_print_regs32’ discards ‘const’ qualifier from pointer target type [enabled by default] include/linux/debugfs.h:93:5: note: expected ‘struct debugfs_reg32 *’ but argument is of type ‘const struct debugfs_reg32 *’ drivers/usb/dwc3/debugfs.c:380:8: warning: unused variable ‘i’ [-Wunused-variable]

Alessandro, care to send me a follow-on patch to fix this up?

thanks,

greg k-h

#8 lore raw

PATCH 1/1 usb: dwc3: fix a warning

The previous patch left an unused variable, I apologize.

---
 drivers/usb/dwc3/debugfs.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/usb/dwc3/debugfs.c +0 -1
index d9e7a26..fcfa915 100644
@@ -377,7 +377,6 @@ static const struct debugfs_reg32 dwc3_regs[] = {
 static int dwc3_regdump_show(struct seq_file *s, void *unused)
 {
 	struct dwc3		*dwc = s->private;
-	int			i;
 
 	seq_printf(s, "DesignWare USB3 Core Register Dump\n");
 	debugfs_print_regs32(s, dwc3_regs, ARRAY_SIZE(dwc3_regs),
Signature · 1 line
1.5.6.5
#9 lore raw

PATCH 1/1 debugfs: print_regs32: make regs array a const pointer

In reply to Greg KH
---
 fs/debugfs/file.c       |    2 +-
 include/linux/debugfs.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
fs/debugfs/file.c +1 -1
index f31a27c..fc98ec9 100644
@@ -548,7 +548,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_blob);
  * because some peripherals have several blocks of identical registers,
  * for example configuration of dma channels
  */
-int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
+int debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs,
 			   int nregs, void __iomem *base, char *prefix)
 {
 	int i, ret = 0;
include/linux/debugfs.h +1 -1
index 5e6b01f..e8c3abc 100644
@@ -90,7 +90,7 @@ struct dentry *debugfs_create_regset32(const char *name, mode_t mode,
 				     struct dentry *parent,
 				     struct debugfs_regset32 *regset);
 
-int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
+int debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs,
 			 int nregs, void __iomem *base, char *prefix);
 
 bool debugfs_initialized(void);
Signature · 1 line
1.5.6.5
#10 lore raw
In reply to Alessandro Rubini
Quoted 3 lines · Alessandro Rubini

Mark, if you say this is not useful at this point, I'm fine with it; I may return with some regbase-aware code when time permits if it's not already there.

We definitely can't just use this directly with regmap as regmap is for non memory mapped devices and makes some assumptions in that regard. I was mostly just suggesting that we try to keep the file formats similar to make life easier for userspace.