* [RFC PATCH] debugfs: add tools to printk 32-bit registers
@ 2011-11-15 13:02 Alessandro Rubini
2011-11-15 21:20 ` Greg KH
0 siblings, 1 reply; 8+ messages in thread
From: Alessandro Rubini @ 2011-11-15 13:02 UTC (permalink / raw)
To: gregkh, linux-kernel; +Cc: giancarlo.asnaghi
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.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Acked-by: Giancarlo Asnaghi <giancarlo.asnaghi@st.com>
---
I'm using this code internally to clean up some heavy bricks of code I
received. For submission, I tried to use the new functions in the file
drivers/video/mbx/mbxdebugfs.c , but I found it is not compiling for a
number of not-really-trivial reasons, so I left it alone -- maybe it
should be removed altogether (it's associated driver compiles fine,
it's only the register dumps that don't).
fs/debugfs/file.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/debugfs.h | 26 +++++++++++++
2 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 90f7657..f31a27c 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/seq_file.h>
#include <linux/pagemap.h>
#include <linux/namei.h>
#include <linux/debugfs.h>
@@ -525,3 +526,92 @@ struct dentry *debugfs_create_blob(const char *name, mode_t mode,
return debugfs_create_file(name, mode, parent, blob, &fops_blob);
}
EXPORT_SYMBOL_GPL(debugfs_create_blob);
+
+/*
+ * The regset32 stuff is used to print 32-bit registers using the
+ * seq_file utilities. We offer printing a register set in an already-opened
+ * sequential file or create a debugfs file that only prints a regset32.
+ */
+
+/**
+ * debugfs_print_regs32 - use seq_print to describe a set of registers
+ * @s: the seq_file structure being used to generate output
+ * @regs: an array if struct debugfs_reg32 structures
+ * @mregs: the length of the above array
+ * @base: the base address to be used in reading the registers
+ * @prefix: a string to be prefixed to every output line
+ *
+ * This function outputs a text block describing the current values of
+ * some 32-bit hardware registers. It is meant to be used within debugfs
+ * files based on seq_file that need to show registers, intermixed with other
+ * information. The prefix argument may be used to specify a leading string,
+ * 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 nregs, void __iomem *base, char *prefix)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < nregs; i++, regs++) {
+ if (prefix)
+ ret += seq_printf(s, "%s", prefix);
+ ret += seq_printf(s, "%s = 0x%08x\n", regs->name,
+ readl((void *)(base + regs->offset)));
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(debugfs_print_regs32);
+
+static int debugfs_show_regset32(struct seq_file *s, void *data)
+{
+ struct debugfs_regset32 *regset = s->private;
+
+ debugfs_print_regs32(s, regset->regs, regset->nregs, regset->base, "");
+ return 0;
+}
+
+static int debugfs_open_regset32(struct inode *inode, struct file *file)
+{
+ return single_open(file, debugfs_show_regset32, inode->i_private);
+}
+
+static const struct file_operations fops_regset32 = {
+ .open = debugfs_open_regset32,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/**
+ * debugfs_create_regset32 - create a debugfs file that returns register values
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is %NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @regset: a pointer to a struct debugfs_regset32, which contains a pointer
+ * to an array of register definitions, the array size and the base
+ * address where the register bank is to be found.
+ *
+ * This function creates a file in debugfs with the given name that reports
+ * the names and values of a set of 32-bit registers. If the @mode variable
+ * is so set it can be read from. Writing is not supported.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, %NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_regset32(const char *name, mode_t mode,
+ struct dentry *parent,
+ struct debugfs_regset32 *regset)
+{
+ return debugfs_create_file(name, mode, parent, regset, &fops_regset32);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_regset32);
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index e7d9b20..5e6b01f 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -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;
--
1.5.6.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [RFC PATCH] debugfs: add tools to printk 32-bit registers
2011-11-15 13:02 [RFC PATCH] debugfs: add tools to printk 32-bit registers Alessandro Rubini
@ 2011-11-15 21:20 ` Greg KH
2011-11-15 21:37 ` Alessandro Rubini
2011-11-16 11:31 ` Mark Brown
0 siblings, 2 replies; 8+ messages in thread
From: Greg KH @ 2011-11-15 21:20 UTC (permalink / raw)
To: Alessandro Rubini; +Cc: linux-kernel, giancarlo.asnaghi
On Tue, Nov 15, 2011 at 02:02:30PM +0100, Alessandro Rubini wrote:
> 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.
Nice, but a few minor questions:
> +/*
> + * The regset32 stuff is used to print 32-bit registers using the
> + * seq_file utilities. We offer printing a register set in an already-opened
> + * sequential file or create a debugfs file that only prints a regset32.
> + */
Can this be part of the kerneldoc below somehow so that people are more
aware of it?
> +
> +/**
> + * debugfs_print_regs32 - use seq_print to describe a set of registers
> + * @s: the seq_file structure being used to generate output
> + * @regs: an array if struct debugfs_reg32 structures
> + * @mregs: the length of the above array
> + * @base: the base address to be used in reading the registers
> + * @prefix: a string to be prefixed to every output line
> + *
> + * This function outputs a text block describing the current values of
> + * some 32-bit hardware registers. It is meant to be used within debugfs
> + * files based on seq_file that need to show registers, intermixed with other
> + * information. The prefix argument may be used to specify a leading string,
> + * 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 nregs, void __iomem *base, char *prefix)
> +{
> + int i, ret = 0;
> +
> + for (i = 0; i < nregs; i++, regs++) {
> + if (prefix)
> + ret += seq_printf(s, "%s", prefix);
> + ret += seq_printf(s, "%s = 0x%08x\n", regs->name,
> + readl((void *)(base + regs->offset)));
> + }
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(debugfs_print_regs32);
This function also needs to be part of debugfs.h in the "debugfs is not
enabled" section of the file, right?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH] debugfs: add tools to printk 32-bit registers
2011-11-15 21:20 ` Greg KH
@ 2011-11-15 21:37 ` Alessandro Rubini
2011-11-15 22:04 ` Felipe Balbi
2011-11-15 22:09 ` Greg KH
2011-11-16 11:31 ` Mark Brown
1 sibling, 2 replies; 8+ messages in thread
From: Alessandro Rubini @ 2011-11-15 21:37 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, giancarlo.asnaghi
Hi Greg. Thanks for looking.
>> +/*
>> + * The regset32 stuff is used to print 32-bit registers using the
>> + * seq_file utilities. We offer printing a register set in an already-opened
>> + * sequential file or create a debugfs file that only prints a regset32.
>> + */
>
> Can this be part of the kerneldoc below somehow so that people are more
> aware of it?
Ok. There's also a file by Jon in Documentation that needs updating, as it
has all the other debugfs file types.
> +int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
>> + int nregs, void __iomem *base, char *prefix)
> This function also needs to be part of debugfs.h in the "debugfs is not
> enabled" section of the file, right?
Not really. The other one makes a regiters-only file, and it's good
to register it withouth ifdef.
This one is used to embed a register block in a file with more
stuff, so it shouldn't be used if debugfs is not selected (btw,
I compiled my internal stuff with and without CONFIG_DEBUG_FS
before rebasing to next).
Example:
static int pl08x_debugfs_show(struct seq_file *s, void *data)
{
[...]
list_for_each_entry(chan, &pl08x->slave.channels, chan.device_node) {
seq_printf(s, "%s\t\t%s\n", chan->name,
pl08x_state_str(chan->state));
}
/* dump registers */
seq_printf(s, "\nPL08x registers\n");
debugfs_print_regs32(s, pl08x_regs, ARRAY_SIZE(pl08x_regs),
pl08x->base, "");
seq_printf(s, "\nPL08x registers channel\n");
for (i = 0; i < pl08x->vd->channels; i++) {
[...]
}
So, I'll post a V2 shortly, unless you refuse it in reply to this.
thanks
/alessandro
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH] debugfs: add tools to printk 32-bit registers
2011-11-15 21:37 ` Alessandro Rubini
@ 2011-11-15 22:04 ` Felipe Balbi
2011-11-15 22:21 ` Alessandro Rubini
2011-11-15 22:09 ` Greg KH
1 sibling, 1 reply; 8+ messages in thread
From: Felipe Balbi @ 2011-11-15 22:04 UTC (permalink / raw)
To: Alessandro Rubini; +Cc: gregkh, linux-kernel, giancarlo.asnaghi
[-- Attachment #1: Type: text/plain, Size: 2685 bytes --]
Hi,
On Tue, Nov 15, 2011 at 10:37:34PM +0100, Alessandro Rubini wrote:
> Hi Greg. Thanks for looking.
>
> >> +/*
> >> + * The regset32 stuff is used to print 32-bit registers using the
> >> + * seq_file utilities. We offer printing a register set in an already-opened
> >> + * sequential file or create a debugfs file that only prints a regset32.
> >> + */
> >
> > Can this be part of the kerneldoc below somehow so that people are more
> > aware of it?
>
> Ok. There's also a file by Jon in Documentation that needs updating, as it
> has all the other debugfs file types.
>
> > +int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
> >> + int nregs, void __iomem *base, char *prefix)
>
> > This function also needs to be part of debugfs.h in the "debugfs is not
> > enabled" section of the file, right?
>
> Not really. The other one makes a regiters-only file, and it's good
> to register it withouth ifdef.
>
> This one is used to embed a register block in a file with more
> stuff, so it shouldn't be used if debugfs is not selected (btw,
> I compiled my internal stuff with and without CONFIG_DEBUG_FS
> before rebasing to next).
>
> Example:
>
> static int pl08x_debugfs_show(struct seq_file *s, void *data)
> {
> [...]
> list_for_each_entry(chan, &pl08x->slave.channels, chan.device_node) {
> seq_printf(s, "%s\t\t%s\n", chan->name,
> pl08x_state_str(chan->state));
> }
>
> /* dump registers */
> seq_printf(s, "\nPL08x registers\n");
> debugfs_print_regs32(s, pl08x_regs, ARRAY_SIZE(pl08x_regs),
> pl08x->base, "");
>
> seq_printf(s, "\nPL08x registers channel\n");
> for (i = 0; i < pl08x->vd->channels; i++) {
> [...]
> }
>
> So, I'll post a V2 shortly, unless you refuse it in reply to this.
this will be useful to dwc3 too, we currently have:
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[] = {
dump_register(GSBUSCFG0),
dump_register(GSBUSCFG1),
dump_register(GTXTHRCFG),
...
};
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");
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));
}
return 0;
}
...
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH] debugfs: add tools to printk 32-bit registers
2011-11-15 21:37 ` Alessandro Rubini
2011-11-15 22:04 ` Felipe Balbi
@ 2011-11-15 22:09 ` Greg KH
1 sibling, 0 replies; 8+ messages in thread
From: Greg KH @ 2011-11-15 22:09 UTC (permalink / raw)
To: Alessandro Rubini; +Cc: linux-kernel, giancarlo.asnaghi
On Tue, Nov 15, 2011 at 10:37:34PM +0100, Alessandro Rubini wrote:
> Hi Greg. Thanks for looking.
>
> >> +/*
> >> + * The regset32 stuff is used to print 32-bit registers using the
> >> + * seq_file utilities. We offer printing a register set in an already-opened
> >> + * sequential file or create a debugfs file that only prints a regset32.
> >> + */
> >
> > Can this be part of the kerneldoc below somehow so that people are more
> > aware of it?
>
> Ok. There's also a file by Jon in Documentation that needs updating, as it
> has all the other debugfs file types.
Ah, yes, that would be good.
> > +int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
> >> + int nregs, void __iomem *base, char *prefix)
>
> > This function also needs to be part of debugfs.h in the "debugfs is not
> > enabled" section of the file, right?
>
> Not really. The other one makes a regiters-only file, and it's good
> to register it withouth ifdef.
>
> This one is used to embed a register block in a file with more
> stuff, so it shouldn't be used if debugfs is not selected (btw,
> I compiled my internal stuff with and without CONFIG_DEBUG_FS
> before rebasing to next).
That makes sense, thanks.
> So, I'll post a V2 shortly, unless you refuse it in reply to this.
Nope, a v2 would be great, thanks.
greg k-h
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH] debugfs: add tools to printk 32-bit registers
2011-11-15 22:04 ` Felipe Balbi
@ 2011-11-15 22:21 ` Alessandro Rubini
2011-11-16 11:14 ` Felipe Balbi
0 siblings, 1 reply; 8+ messages in thread
From: Alessandro Rubini @ 2011-11-15 22:21 UTC (permalink / raw)
To: balbi; +Cc: gregkh, linux-kernel, giancarlo.asnaghi
> this will be useful to dwc3 too, we currently have:
> [...]
Yes, this is similar, just factorized for everybody to use. I looked
for files that may use it (besides stuff I received internally) by
counting the %08x.
So in V2, tomorrow, I'll port your file to use the centralized code
tool, as a separate patch.
thank your for your interest
/alessandro
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH] debugfs: add tools to printk 32-bit registers
2011-11-15 22:21 ` Alessandro Rubini
@ 2011-11-16 11:14 ` Felipe Balbi
0 siblings, 0 replies; 8+ messages in thread
From: Felipe Balbi @ 2011-11-16 11:14 UTC (permalink / raw)
To: Alessandro Rubini; +Cc: balbi, gregkh, linux-kernel, giancarlo.asnaghi
[-- Attachment #1: Type: text/plain, Size: 481 bytes --]
On Tue, Nov 15, 2011 at 11:21:19PM +0100, Alessandro Rubini wrote:
> > this will be useful to dwc3 too, we currently have:
> > [...]
>
> Yes, this is similar, just factorized for everybody to use. I looked
> for files that may use it (besides stuff I received internally) by
> counting the %08x.
>
> So in V2, tomorrow, I'll port your file to use the centralized code
> tool, as a separate patch.
that would be great. I'll make sure to test it out :-)
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH] debugfs: add tools to printk 32-bit registers
2011-11-15 21:20 ` Greg KH
2011-11-15 21:37 ` Alessandro Rubini
@ 2011-11-16 11:31 ` Mark Brown
1 sibling, 0 replies; 8+ messages in thread
From: Mark Brown @ 2011-11-16 11:31 UTC (permalink / raw)
To: Greg KH; +Cc: Alessandro Rubini, linux-kernel, giancarlo.asnaghi
On Tue, Nov 15, 2011 at 01:20:12PM -0800, Greg KH wrote:
> On Tue, Nov 15, 2011 at 02:02:30PM +0100, Alessandro Rubini wrote:
> > 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.
> Nice, but a few minor questions:
Hrm, we have something similar in regmap but in the form
number: value
Might be worth looking at that for the seeking implementation, or to
suggest improvements to the regmap one.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2011-11-16 11:31 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-15 13:02 [RFC PATCH] debugfs: add tools to printk 32-bit registers Alessandro Rubini
2011-11-15 21:20 ` Greg KH
2011-11-15 21:37 ` Alessandro Rubini
2011-11-15 22:04 ` Felipe Balbi
2011-11-15 22:21 ` Alessandro Rubini
2011-11-16 11:14 ` Felipe Balbi
2011-11-15 22:09 ` Greg KH
2011-11-16 11:31 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox