Skip to content

Commit 98210b7

Browse files
Arend van Sprielgregkh
authored andcommitted
debugfs: add helper function to create device related seq_file
This patch adds a helper function that simplifies adding a so-called single_open sequence file for device drivers. The calling device driver needs to provide a read function and a device pointer. The field struct seq_file::private will reference the device pointer upon call to the read function so the driver can obtain his data from it and do its task of providing the file content using seq_printf() calls and alike. Using this helper function also gets rid of the need to specify file operations per debugfs file. Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 6df43c9 commit 98210b7

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

fs/debugfs/file.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/io.h>
2323
#include <linux/slab.h>
2424
#include <linux/atomic.h>
25+
#include <linux/device.h>
2526

2627
static ssize_t default_read_file(struct file *file, char __user *buf,
2728
size_t count, loff_t *ppos)
@@ -761,3 +762,56 @@ struct dentry *debugfs_create_regset32(const char *name, umode_t mode,
761762
EXPORT_SYMBOL_GPL(debugfs_create_regset32);
762763

763764
#endif /* CONFIG_HAS_IOMEM */
765+
766+
struct debugfs_devm_entry {
767+
int (*read)(struct seq_file *seq, void *data);
768+
struct device *dev;
769+
};
770+
771+
static int debugfs_devm_entry_open(struct inode *inode, struct file *f)
772+
{
773+
struct debugfs_devm_entry *entry = inode->i_private;
774+
775+
return single_open(f, entry->read, entry->dev);
776+
}
777+
778+
static const struct file_operations debugfs_devm_entry_ops = {
779+
.owner = THIS_MODULE,
780+
.open = debugfs_devm_entry_open,
781+
.release = single_release,
782+
.read = seq_read,
783+
.llseek = seq_lseek
784+
};
785+
786+
/**
787+
* debugfs_create_devm_seqfile - create a debugfs file that is bound to device.
788+
*
789+
* @dev: device related to this debugfs file.
790+
* @name: name of the debugfs file.
791+
* @parent: a pointer to the parent dentry for this file. This should be a
792+
* directory dentry if set. If this parameter is %NULL, then the
793+
* file will be created in the root of the debugfs filesystem.
794+
* @read_fn: function pointer called to print the seq_file content.
795+
*/
796+
struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,
797+
struct dentry *parent,
798+
int (*read_fn)(struct seq_file *s,
799+
void *data))
800+
{
801+
struct debugfs_devm_entry *entry;
802+
803+
if (IS_ERR(parent))
804+
return ERR_PTR(-ENOENT);
805+
806+
entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL);
807+
if (!entry)
808+
return ERR_PTR(-ENOMEM);
809+
810+
entry->read = read_fn;
811+
entry->dev = dev;
812+
813+
return debugfs_create_file(name, S_IRUGO, parent, entry,
814+
&debugfs_devm_entry_ops);
815+
}
816+
EXPORT_SYMBOL_GPL(debugfs_create_devm_seqfile);
817+

include/linux/debugfs.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,18 @@ struct dentry *debugfs_create_u32_array(const char *name, umode_t mode,
9999
struct dentry *parent,
100100
u32 *array, u32 elements);
101101

102+
struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,
103+
struct dentry *parent,
104+
int (*read_fn)(struct seq_file *s,
105+
void *data));
106+
102107
bool debugfs_initialized(void);
103108

104109
#else
105110

106111
#include <linux/err.h>
107112

108-
/*
113+
/*
109114
* We do not return NULL from these functions if CONFIG_DEBUG_FS is not enabled
110115
* so users have a chance to detect if there was a real error or not. We don't
111116
* want to duplicate the design decision mistakes of procfs and devfs again.
@@ -251,6 +256,15 @@ static inline struct dentry *debugfs_create_u32_array(const char *name, umode_t
251256
return ERR_PTR(-ENODEV);
252257
}
253258

259+
static inline struct dentry *debugfs_create_devm_seqfile(struct device *dev,
260+
const char *name,
261+
struct dentry *parent,
262+
int (*read_fn)(struct seq_file *s,
263+
void *data))
264+
{
265+
return ERR_PTR(-ENODEV);
266+
}
267+
254268
#endif
255269

256270
#endif

0 commit comments

Comments
 (0)