Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Arend van Spriel and committed by
Greg Kroah-Hartman
98210b7f 6df43c9b

+69 -1
+54
fs/debugfs/file.c
··· 22 22 #include <linux/io.h> 23 23 #include <linux/slab.h> 24 24 #include <linux/atomic.h> 25 + #include <linux/device.h> 25 26 26 27 static ssize_t default_read_file(struct file *file, char __user *buf, 27 28 size_t count, loff_t *ppos) ··· 762 761 EXPORT_SYMBOL_GPL(debugfs_create_regset32); 763 762 764 763 #endif /* CONFIG_HAS_IOMEM */ 764 + 765 + struct debugfs_devm_entry { 766 + int (*read)(struct seq_file *seq, void *data); 767 + struct device *dev; 768 + }; 769 + 770 + static int debugfs_devm_entry_open(struct inode *inode, struct file *f) 771 + { 772 + struct debugfs_devm_entry *entry = inode->i_private; 773 + 774 + return single_open(f, entry->read, entry->dev); 775 + } 776 + 777 + static const struct file_operations debugfs_devm_entry_ops = { 778 + .owner = THIS_MODULE, 779 + .open = debugfs_devm_entry_open, 780 + .release = single_release, 781 + .read = seq_read, 782 + .llseek = seq_lseek 783 + }; 784 + 785 + /** 786 + * debugfs_create_devm_seqfile - create a debugfs file that is bound to device. 787 + * 788 + * @dev: device related to this debugfs file. 789 + * @name: name of the debugfs file. 790 + * @parent: a pointer to the parent dentry for this file. This should be a 791 + * directory dentry if set. If this parameter is %NULL, then the 792 + * file will be created in the root of the debugfs filesystem. 793 + * @read_fn: function pointer called to print the seq_file content. 794 + */ 795 + struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name, 796 + struct dentry *parent, 797 + int (*read_fn)(struct seq_file *s, 798 + void *data)) 799 + { 800 + struct debugfs_devm_entry *entry; 801 + 802 + if (IS_ERR(parent)) 803 + return ERR_PTR(-ENOENT); 804 + 805 + entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL); 806 + if (!entry) 807 + return ERR_PTR(-ENOMEM); 808 + 809 + entry->read = read_fn; 810 + entry->dev = dev; 811 + 812 + return debugfs_create_file(name, S_IRUGO, parent, entry, 813 + &debugfs_devm_entry_ops); 814 + } 815 + EXPORT_SYMBOL_GPL(debugfs_create_devm_seqfile); 816 +
+15 -1
include/linux/debugfs.h
··· 99 99 struct dentry *parent, 100 100 u32 *array, u32 elements); 101 101 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 + 102 107 bool debugfs_initialized(void); 103 108 104 109 #else 105 110 106 111 #include <linux/err.h> 107 112 108 - /* 113 + /* 109 114 * We do not return NULL from these functions if CONFIG_DEBUG_FS is not enabled 110 115 * so users have a chance to detect if there was a real error or not. We don't 111 116 * want to duplicate the design decision mistakes of procfs and devfs again. ··· 252 247 static inline struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, 253 248 struct dentry *parent, 254 249 u32 *array, u32 elements) 250 + { 251 + return ERR_PTR(-ENODEV); 252 + } 253 + 254 + static inline struct dentry *debugfs_create_devm_seqfile(struct device *dev, 255 + const char *name, 256 + struct dentry *parent, 257 + int (*read_fn)(struct seq_file *s, 258 + void *data)) 255 259 { 256 260 return ERR_PTR(-ENODEV); 257 261 }