xref: /linux-6.15/fs/debugfs/file.c (revision 9fd4dcec)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *  file.c - part of debugfs, a tiny little debug file system
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *  Copyright (C) 2004 Greg Kroah-Hartman <[email protected]>
51da177e4SLinus Torvalds  *  Copyright (C) 2004 IBM Inc.
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  *	This program is free software; you can redistribute it and/or
81da177e4SLinus Torvalds  *	modify it under the terms of the GNU General Public License version
91da177e4SLinus Torvalds  *	2 as published by the Free Software Foundation.
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  *  debugfs is for people to use instead of /proc or /sys.
12883ce42eSRobert P. J. Day  *  See Documentation/DocBook/filesystems for more details.
131da177e4SLinus Torvalds  *
141da177e4SLinus Torvalds  */
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #include <linux/module.h>
171da177e4SLinus Torvalds #include <linux/fs.h>
181a087c6aSAlessandro Rubini #include <linux/seq_file.h>
191da177e4SLinus Torvalds #include <linux/pagemap.h>
201da177e4SLinus Torvalds #include <linux/debugfs.h>
2103e099fbSAlessandro Rubini #include <linux/io.h>
229fe2a701SSrivatsa Vaddagiri #include <linux/slab.h>
233a76e5e0SSeth Jennings #include <linux/atomic.h>
2498210b7fSArend van Spriel #include <linux/device.h>
25*9fd4dcecSNicolai Stange #include <linux/srcu.h>
26*9fd4dcecSNicolai Stange 
27*9fd4dcecSNicolai Stange #include "internal.h"
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds static ssize_t default_read_file(struct file *file, char __user *buf,
301da177e4SLinus Torvalds 				 size_t count, loff_t *ppos)
311da177e4SLinus Torvalds {
321da177e4SLinus Torvalds 	return 0;
331da177e4SLinus Torvalds }
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds static ssize_t default_write_file(struct file *file, const char __user *buf,
361da177e4SLinus Torvalds 				   size_t count, loff_t *ppos)
371da177e4SLinus Torvalds {
381da177e4SLinus Torvalds 	return count;
391da177e4SLinus Torvalds }
401da177e4SLinus Torvalds 
41*9fd4dcecSNicolai Stange const struct file_operations debugfs_noop_file_operations = {
421da177e4SLinus Torvalds 	.read =		default_read_file,
431da177e4SLinus Torvalds 	.write =	default_write_file,
44234e3405SStephen Boyd 	.open =		simple_open,
456038f373SArnd Bergmann 	.llseek =	noop_llseek,
461da177e4SLinus Torvalds };
471da177e4SLinus Torvalds 
48*9fd4dcecSNicolai Stange /**
49*9fd4dcecSNicolai Stange  * debugfs_use_file_start - mark the beginning of file data access
50*9fd4dcecSNicolai Stange  * @dentry: the dentry object whose data is being accessed.
51*9fd4dcecSNicolai Stange  * @srcu_idx: a pointer to some memory to store a SRCU index in.
52*9fd4dcecSNicolai Stange  *
53*9fd4dcecSNicolai Stange  * Up to a matching call to debugfs_use_file_finish(), any
54*9fd4dcecSNicolai Stange  * successive call into the file removing functions debugfs_remove()
55*9fd4dcecSNicolai Stange  * and debugfs_remove_recursive() will block. Since associated private
56*9fd4dcecSNicolai Stange  * file data may only get freed after a successful return of any of
57*9fd4dcecSNicolai Stange  * the removal functions, you may safely access it after a successful
58*9fd4dcecSNicolai Stange  * call to debugfs_use_file_start() without worrying about
59*9fd4dcecSNicolai Stange  * lifetime issues.
60*9fd4dcecSNicolai Stange  *
61*9fd4dcecSNicolai Stange  * If -%EIO is returned, the file has already been removed and thus,
62*9fd4dcecSNicolai Stange  * it is not safe to access any of its data. If, on the other hand,
63*9fd4dcecSNicolai Stange  * it is allowed to access the file data, zero is returned.
64*9fd4dcecSNicolai Stange  *
65*9fd4dcecSNicolai Stange  * Regardless of the return code, any call to
66*9fd4dcecSNicolai Stange  * debugfs_use_file_start() must be followed by a matching call
67*9fd4dcecSNicolai Stange  * to debugfs_use_file_finish().
68*9fd4dcecSNicolai Stange  */
69*9fd4dcecSNicolai Stange static int debugfs_use_file_start(const struct dentry *dentry, int *srcu_idx)
70*9fd4dcecSNicolai Stange 	__acquires(&debugfs_srcu)
71*9fd4dcecSNicolai Stange {
72*9fd4dcecSNicolai Stange 	*srcu_idx = srcu_read_lock(&debugfs_srcu);
73*9fd4dcecSNicolai Stange 	barrier();
74*9fd4dcecSNicolai Stange 	if (d_unlinked(dentry))
75*9fd4dcecSNicolai Stange 		return -EIO;
76*9fd4dcecSNicolai Stange 	return 0;
77*9fd4dcecSNicolai Stange }
78*9fd4dcecSNicolai Stange 
79*9fd4dcecSNicolai Stange /**
80*9fd4dcecSNicolai Stange  * debugfs_use_file_finish - mark the end of file data access
81*9fd4dcecSNicolai Stange  * @srcu_idx: the SRCU index "created" by a former call to
82*9fd4dcecSNicolai Stange  *            debugfs_use_file_start().
83*9fd4dcecSNicolai Stange  *
84*9fd4dcecSNicolai Stange  * Allow any ongoing concurrent call into debugfs_remove() or
85*9fd4dcecSNicolai Stange  * debugfs_remove_recursive() blocked by a former call to
86*9fd4dcecSNicolai Stange  * debugfs_use_file_start() to proceed and return to its caller.
87*9fd4dcecSNicolai Stange  */
88*9fd4dcecSNicolai Stange static void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu)
89*9fd4dcecSNicolai Stange {
90*9fd4dcecSNicolai Stange 	srcu_read_unlock(&debugfs_srcu, srcu_idx);
91*9fd4dcecSNicolai Stange }
92*9fd4dcecSNicolai Stange 
93*9fd4dcecSNicolai Stange #define F_DENTRY(filp) ((filp)->f_path.dentry)
94*9fd4dcecSNicolai Stange 
95*9fd4dcecSNicolai Stange #define REAL_FOPS_DEREF(dentry)					\
96*9fd4dcecSNicolai Stange 	((const struct file_operations *)(dentry)->d_fsdata)
97*9fd4dcecSNicolai Stange 
98*9fd4dcecSNicolai Stange static int open_proxy_open(struct inode *inode, struct file *filp)
99*9fd4dcecSNicolai Stange {
100*9fd4dcecSNicolai Stange 	const struct dentry *dentry = F_DENTRY(filp);
101*9fd4dcecSNicolai Stange 	const struct file_operations *real_fops = NULL;
102*9fd4dcecSNicolai Stange 	int srcu_idx, r;
103*9fd4dcecSNicolai Stange 
104*9fd4dcecSNicolai Stange 	r = debugfs_use_file_start(dentry, &srcu_idx);
105*9fd4dcecSNicolai Stange 	if (r) {
106*9fd4dcecSNicolai Stange 		r = -ENOENT;
107*9fd4dcecSNicolai Stange 		goto out;
108*9fd4dcecSNicolai Stange 	}
109*9fd4dcecSNicolai Stange 
110*9fd4dcecSNicolai Stange 	real_fops = REAL_FOPS_DEREF(dentry);
111*9fd4dcecSNicolai Stange 	real_fops = fops_get(real_fops);
112*9fd4dcecSNicolai Stange 	if (!real_fops) {
113*9fd4dcecSNicolai Stange 		/* Huh? Module did not clean up after itself at exit? */
114*9fd4dcecSNicolai Stange 		WARN(1, "debugfs file owner did not clean up at exit: %pd",
115*9fd4dcecSNicolai Stange 			dentry);
116*9fd4dcecSNicolai Stange 		r = -ENXIO;
117*9fd4dcecSNicolai Stange 		goto out;
118*9fd4dcecSNicolai Stange 	}
119*9fd4dcecSNicolai Stange 	replace_fops(filp, real_fops);
120*9fd4dcecSNicolai Stange 
121*9fd4dcecSNicolai Stange 	if (real_fops->open)
122*9fd4dcecSNicolai Stange 		r = real_fops->open(inode, filp);
123*9fd4dcecSNicolai Stange 
124*9fd4dcecSNicolai Stange out:
125*9fd4dcecSNicolai Stange 	fops_put(real_fops);
126*9fd4dcecSNicolai Stange 	debugfs_use_file_finish(srcu_idx);
127*9fd4dcecSNicolai Stange 	return r;
128*9fd4dcecSNicolai Stange }
129*9fd4dcecSNicolai Stange 
130*9fd4dcecSNicolai Stange const struct file_operations debugfs_open_proxy_file_operations = {
131*9fd4dcecSNicolai Stange 	.open = open_proxy_open,
132*9fd4dcecSNicolai Stange };
133*9fd4dcecSNicolai Stange 
134b97f6799SStephen Boyd static struct dentry *debugfs_create_mode(const char *name, umode_t mode,
135b97f6799SStephen Boyd 					  struct dentry *parent, void *value,
136b97f6799SStephen Boyd 				          const struct file_operations *fops,
137b97f6799SStephen Boyd 				          const struct file_operations *fops_ro,
138b97f6799SStephen Boyd 				          const struct file_operations *fops_wo)
139b97f6799SStephen Boyd {
140b97f6799SStephen Boyd 	/* if there are no write bits set, make read only */
141b97f6799SStephen Boyd 	if (!(mode & S_IWUGO))
142b97f6799SStephen Boyd 		return debugfs_create_file(name, mode, parent, value, fops_ro);
143b97f6799SStephen Boyd 	/* if there are no read bits set, make write only */
144b97f6799SStephen Boyd 	if (!(mode & S_IRUGO))
145b97f6799SStephen Boyd 		return debugfs_create_file(name, mode, parent, value, fops_wo);
146b97f6799SStephen Boyd 
147b97f6799SStephen Boyd 	return debugfs_create_file(name, mode, parent, value, fops);
148b97f6799SStephen Boyd }
149b97f6799SStephen Boyd 
1508b88b099SChristoph Hellwig static int debugfs_u8_set(void *data, u64 val)
151acaefc25SArnd Bergmann {
152acaefc25SArnd Bergmann 	*(u8 *)data = val;
1538b88b099SChristoph Hellwig 	return 0;
154acaefc25SArnd Bergmann }
1558b88b099SChristoph Hellwig static int debugfs_u8_get(void *data, u64 *val)
156acaefc25SArnd Bergmann {
1578b88b099SChristoph Hellwig 	*val = *(u8 *)data;
1588b88b099SChristoph Hellwig 	return 0;
159acaefc25SArnd Bergmann }
160acaefc25SArnd Bergmann DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
161e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_u8_ro, debugfs_u8_get, NULL, "%llu\n");
162e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%llu\n");
1631da177e4SLinus Torvalds 
1641da177e4SLinus Torvalds /**
1656468b3afSRandy Dunlap  * debugfs_create_u8 - create a debugfs file that is used to read and write an unsigned 8-bit value
1661da177e4SLinus Torvalds  * @name: a pointer to a string containing the name of the file to create.
1671da177e4SLinus Torvalds  * @mode: the permission that the file should have
1681da177e4SLinus Torvalds  * @parent: a pointer to the parent dentry for this file.  This should be a
1696468b3afSRandy Dunlap  *          directory dentry if set.  If this parameter is %NULL, then the
1701da177e4SLinus Torvalds  *          file will be created in the root of the debugfs filesystem.
1711da177e4SLinus Torvalds  * @value: a pointer to the variable that the file should read to and write
1721da177e4SLinus Torvalds  *         from.
1731da177e4SLinus Torvalds  *
1741da177e4SLinus Torvalds  * This function creates a file in debugfs with the given name that
1751da177e4SLinus Torvalds  * contains the value of the variable @value.  If the @mode variable is so
1761da177e4SLinus Torvalds  * set, it can be read from, and written to.
1771da177e4SLinus Torvalds  *
1781da177e4SLinus Torvalds  * This function will return a pointer to a dentry if it succeeds.  This
1791da177e4SLinus Torvalds  * pointer must be passed to the debugfs_remove() function when the file is
1801da177e4SLinus Torvalds  * to be removed (no automatic cleanup happens if your module is unloaded,
1816468b3afSRandy Dunlap  * you are responsible here.)  If an error occurs, %NULL will be returned.
1821da177e4SLinus Torvalds  *
1836468b3afSRandy Dunlap  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
1841da177e4SLinus Torvalds  * returned.  It is not wise to check for this value, but rather, check for
1856468b3afSRandy Dunlap  * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
1861da177e4SLinus Torvalds  * code.
1871da177e4SLinus Torvalds  */
188f4ae40a6SAl Viro struct dentry *debugfs_create_u8(const char *name, umode_t mode,
1891da177e4SLinus Torvalds 				 struct dentry *parent, u8 *value)
1901da177e4SLinus Torvalds {
191b97f6799SStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_u8,
192b97f6799SStephen Boyd 				   &fops_u8_ro, &fops_u8_wo);
1931da177e4SLinus Torvalds }
1941da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(debugfs_create_u8);
1951da177e4SLinus Torvalds 
1968b88b099SChristoph Hellwig static int debugfs_u16_set(void *data, u64 val)
197acaefc25SArnd Bergmann {
198acaefc25SArnd Bergmann 	*(u16 *)data = val;
1998b88b099SChristoph Hellwig 	return 0;
200acaefc25SArnd Bergmann }
2018b88b099SChristoph Hellwig static int debugfs_u16_get(void *data, u64 *val)
202acaefc25SArnd Bergmann {
2038b88b099SChristoph Hellwig 	*val = *(u16 *)data;
2048b88b099SChristoph Hellwig 	return 0;
205acaefc25SArnd Bergmann }
206acaefc25SArnd Bergmann DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
207e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_u16_ro, debugfs_u16_get, NULL, "%llu\n");
208e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%llu\n");
209acaefc25SArnd Bergmann 
2101da177e4SLinus Torvalds /**
2116468b3afSRandy Dunlap  * debugfs_create_u16 - create a debugfs file that is used to read and write an unsigned 16-bit value
2121da177e4SLinus Torvalds  * @name: a pointer to a string containing the name of the file to create.
2131da177e4SLinus Torvalds  * @mode: the permission that the file should have
2141da177e4SLinus Torvalds  * @parent: a pointer to the parent dentry for this file.  This should be a
2156468b3afSRandy Dunlap  *          directory dentry if set.  If this parameter is %NULL, then the
2161da177e4SLinus Torvalds  *          file will be created in the root of the debugfs filesystem.
2171da177e4SLinus Torvalds  * @value: a pointer to the variable that the file should read to and write
2181da177e4SLinus Torvalds  *         from.
2191da177e4SLinus Torvalds  *
2201da177e4SLinus Torvalds  * This function creates a file in debugfs with the given name that
2211da177e4SLinus Torvalds  * contains the value of the variable @value.  If the @mode variable is so
2221da177e4SLinus Torvalds  * set, it can be read from, and written to.
2231da177e4SLinus Torvalds  *
2241da177e4SLinus Torvalds  * This function will return a pointer to a dentry if it succeeds.  This
2251da177e4SLinus Torvalds  * pointer must be passed to the debugfs_remove() function when the file is
2261da177e4SLinus Torvalds  * to be removed (no automatic cleanup happens if your module is unloaded,
2276468b3afSRandy Dunlap  * you are responsible here.)  If an error occurs, %NULL will be returned.
2281da177e4SLinus Torvalds  *
2296468b3afSRandy Dunlap  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
2301da177e4SLinus Torvalds  * returned.  It is not wise to check for this value, but rather, check for
2316468b3afSRandy Dunlap  * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
2321da177e4SLinus Torvalds  * code.
2331da177e4SLinus Torvalds  */
234f4ae40a6SAl Viro struct dentry *debugfs_create_u16(const char *name, umode_t mode,
2351da177e4SLinus Torvalds 				  struct dentry *parent, u16 *value)
2361da177e4SLinus Torvalds {
237b97f6799SStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_u16,
238b97f6799SStephen Boyd 				   &fops_u16_ro, &fops_u16_wo);
2391da177e4SLinus Torvalds }
2401da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(debugfs_create_u16);
2411da177e4SLinus Torvalds 
2428b88b099SChristoph Hellwig static int debugfs_u32_set(void *data, u64 val)
243acaefc25SArnd Bergmann {
244acaefc25SArnd Bergmann 	*(u32 *)data = val;
2458b88b099SChristoph Hellwig 	return 0;
246acaefc25SArnd Bergmann }
2478b88b099SChristoph Hellwig static int debugfs_u32_get(void *data, u64 *val)
248acaefc25SArnd Bergmann {
2498b88b099SChristoph Hellwig 	*val = *(u32 *)data;
2508b88b099SChristoph Hellwig 	return 0;
251acaefc25SArnd Bergmann }
252acaefc25SArnd Bergmann DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
253e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_u32_ro, debugfs_u32_get, NULL, "%llu\n");
254e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n");
255acaefc25SArnd Bergmann 
2561da177e4SLinus Torvalds /**
2576468b3afSRandy Dunlap  * debugfs_create_u32 - create a debugfs file that is used to read and write an unsigned 32-bit value
2581da177e4SLinus Torvalds  * @name: a pointer to a string containing the name of the file to create.
2591da177e4SLinus Torvalds  * @mode: the permission that the file should have
2601da177e4SLinus Torvalds  * @parent: a pointer to the parent dentry for this file.  This should be a
2616468b3afSRandy Dunlap  *          directory dentry if set.  If this parameter is %NULL, then the
2621da177e4SLinus Torvalds  *          file will be created in the root of the debugfs filesystem.
2631da177e4SLinus Torvalds  * @value: a pointer to the variable that the file should read to and write
2641da177e4SLinus Torvalds  *         from.
2651da177e4SLinus Torvalds  *
2661da177e4SLinus Torvalds  * This function creates a file in debugfs with the given name that
2671da177e4SLinus Torvalds  * contains the value of the variable @value.  If the @mode variable is so
2681da177e4SLinus Torvalds  * set, it can be read from, and written to.
2691da177e4SLinus Torvalds  *
2701da177e4SLinus Torvalds  * This function will return a pointer to a dentry if it succeeds.  This
2711da177e4SLinus Torvalds  * pointer must be passed to the debugfs_remove() function when the file is
2721da177e4SLinus Torvalds  * to be removed (no automatic cleanup happens if your module is unloaded,
2736468b3afSRandy Dunlap  * you are responsible here.)  If an error occurs, %NULL will be returned.
2741da177e4SLinus Torvalds  *
2756468b3afSRandy Dunlap  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
2761da177e4SLinus Torvalds  * returned.  It is not wise to check for this value, but rather, check for
2776468b3afSRandy Dunlap  * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
2781da177e4SLinus Torvalds  * code.
2791da177e4SLinus Torvalds  */
280f4ae40a6SAl Viro struct dentry *debugfs_create_u32(const char *name, umode_t mode,
2811da177e4SLinus Torvalds 				 struct dentry *parent, u32 *value)
2821da177e4SLinus Torvalds {
283b97f6799SStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_u32,
284b97f6799SStephen Boyd 				   &fops_u32_ro, &fops_u32_wo);
2851da177e4SLinus Torvalds }
2861da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(debugfs_create_u32);
2871da177e4SLinus Torvalds 
2888b88b099SChristoph Hellwig static int debugfs_u64_set(void *data, u64 val)
2898447891fSMichael Ellerman {
2908447891fSMichael Ellerman 	*(u64 *)data = val;
2918b88b099SChristoph Hellwig 	return 0;
2928447891fSMichael Ellerman }
2938447891fSMichael Ellerman 
2948b88b099SChristoph Hellwig static int debugfs_u64_get(void *data, u64 *val)
2958447891fSMichael Ellerman {
2968b88b099SChristoph Hellwig 	*val = *(u64 *)data;
2978b88b099SChristoph Hellwig 	return 0;
2988447891fSMichael Ellerman }
2998447891fSMichael Ellerman DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n");
300e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_u64_ro, debugfs_u64_get, NULL, "%llu\n");
301e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n");
3028447891fSMichael Ellerman 
3038447891fSMichael Ellerman /**
3048447891fSMichael Ellerman  * debugfs_create_u64 - create a debugfs file that is used to read and write an unsigned 64-bit value
3058447891fSMichael Ellerman  * @name: a pointer to a string containing the name of the file to create.
3068447891fSMichael Ellerman  * @mode: the permission that the file should have
3078447891fSMichael Ellerman  * @parent: a pointer to the parent dentry for this file.  This should be a
3088447891fSMichael Ellerman  *          directory dentry if set.  If this parameter is %NULL, then the
3098447891fSMichael Ellerman  *          file will be created in the root of the debugfs filesystem.
3108447891fSMichael Ellerman  * @value: a pointer to the variable that the file should read to and write
3118447891fSMichael Ellerman  *         from.
3128447891fSMichael Ellerman  *
3138447891fSMichael Ellerman  * This function creates a file in debugfs with the given name that
3148447891fSMichael Ellerman  * contains the value of the variable @value.  If the @mode variable is so
3158447891fSMichael Ellerman  * set, it can be read from, and written to.
3168447891fSMichael Ellerman  *
3178447891fSMichael Ellerman  * This function will return a pointer to a dentry if it succeeds.  This
3188447891fSMichael Ellerman  * pointer must be passed to the debugfs_remove() function when the file is
3198447891fSMichael Ellerman  * to be removed (no automatic cleanup happens if your module is unloaded,
3208447891fSMichael Ellerman  * you are responsible here.)  If an error occurs, %NULL will be returned.
3218447891fSMichael Ellerman  *
3228447891fSMichael Ellerman  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
3238447891fSMichael Ellerman  * returned.  It is not wise to check for this value, but rather, check for
3248447891fSMichael Ellerman  * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
3258447891fSMichael Ellerman  * code.
3268447891fSMichael Ellerman  */
327f4ae40a6SAl Viro struct dentry *debugfs_create_u64(const char *name, umode_t mode,
3288447891fSMichael Ellerman 				 struct dentry *parent, u64 *value)
3298447891fSMichael Ellerman {
330b97f6799SStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_u64,
331b97f6799SStephen Boyd 				   &fops_u64_ro, &fops_u64_wo);
3328447891fSMichael Ellerman }
3338447891fSMichael Ellerman EXPORT_SYMBOL_GPL(debugfs_create_u64);
3348447891fSMichael Ellerman 
335c23fe831SViresh Kumar static int debugfs_ulong_set(void *data, u64 val)
336c23fe831SViresh Kumar {
337c23fe831SViresh Kumar 	*(unsigned long *)data = val;
338c23fe831SViresh Kumar 	return 0;
339c23fe831SViresh Kumar }
340c23fe831SViresh Kumar 
341c23fe831SViresh Kumar static int debugfs_ulong_get(void *data, u64 *val)
342c23fe831SViresh Kumar {
343c23fe831SViresh Kumar 	*val = *(unsigned long *)data;
344c23fe831SViresh Kumar 	return 0;
345c23fe831SViresh Kumar }
346c23fe831SViresh Kumar DEFINE_SIMPLE_ATTRIBUTE(fops_ulong, debugfs_ulong_get, debugfs_ulong_set, "%llu\n");
347c23fe831SViresh Kumar DEFINE_SIMPLE_ATTRIBUTE(fops_ulong_ro, debugfs_ulong_get, NULL, "%llu\n");
348c23fe831SViresh Kumar DEFINE_SIMPLE_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n");
349c23fe831SViresh Kumar 
350c23fe831SViresh Kumar /**
351c23fe831SViresh Kumar  * debugfs_create_ulong - create a debugfs file that is used to read and write
352c23fe831SViresh Kumar  * an unsigned long value.
353c23fe831SViresh Kumar  * @name: a pointer to a string containing the name of the file to create.
354c23fe831SViresh Kumar  * @mode: the permission that the file should have
355c23fe831SViresh Kumar  * @parent: a pointer to the parent dentry for this file.  This should be a
356c23fe831SViresh Kumar  *          directory dentry if set.  If this parameter is %NULL, then the
357c23fe831SViresh Kumar  *          file will be created in the root of the debugfs filesystem.
358c23fe831SViresh Kumar  * @value: a pointer to the variable that the file should read to and write
359c23fe831SViresh Kumar  *         from.
360c23fe831SViresh Kumar  *
361c23fe831SViresh Kumar  * This function creates a file in debugfs with the given name that
362c23fe831SViresh Kumar  * contains the value of the variable @value.  If the @mode variable is so
363c23fe831SViresh Kumar  * set, it can be read from, and written to.
364c23fe831SViresh Kumar  *
365c23fe831SViresh Kumar  * This function will return a pointer to a dentry if it succeeds.  This
366c23fe831SViresh Kumar  * pointer must be passed to the debugfs_remove() function when the file is
367c23fe831SViresh Kumar  * to be removed (no automatic cleanup happens if your module is unloaded,
368c23fe831SViresh Kumar  * you are responsible here.)  If an error occurs, %NULL will be returned.
369c23fe831SViresh Kumar  *
370c23fe831SViresh Kumar  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
371c23fe831SViresh Kumar  * returned.  It is not wise to check for this value, but rather, check for
372c23fe831SViresh Kumar  * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
373c23fe831SViresh Kumar  * code.
374c23fe831SViresh Kumar  */
375c23fe831SViresh Kumar struct dentry *debugfs_create_ulong(const char *name, umode_t mode,
376c23fe831SViresh Kumar 				    struct dentry *parent, unsigned long *value)
377c23fe831SViresh Kumar {
378c23fe831SViresh Kumar 	return debugfs_create_mode(name, mode, parent, value, &fops_ulong,
379c23fe831SViresh Kumar 				   &fops_ulong_ro, &fops_ulong_wo);
380c23fe831SViresh Kumar }
381c23fe831SViresh Kumar EXPORT_SYMBOL_GPL(debugfs_create_ulong);
382c23fe831SViresh Kumar 
3832ebefc50SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%02llx\n");
384e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x8_ro, debugfs_u8_get, NULL, "0x%02llx\n");
385e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x8_wo, NULL, debugfs_u8_set, "0x%02llx\n");
3862ebefc50SRobin Getz 
3872ebefc50SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%04llx\n");
388e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x16_ro, debugfs_u16_get, NULL, "0x%04llx\n");
389e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x16_wo, NULL, debugfs_u16_set, "0x%04llx\n");
3902ebefc50SRobin Getz 
3912ebefc50SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n");
392e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%08llx\n");
393e4792aa3SRobin Getz DEFINE_SIMPLE_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%08llx\n");
3942ebefc50SRobin Getz 
39515b0beaaSHuang Ying DEFINE_SIMPLE_ATTRIBUTE(fops_x64, debugfs_u64_get, debugfs_u64_set, "0x%016llx\n");
39682b7d4fbSStephen Boyd DEFINE_SIMPLE_ATTRIBUTE(fops_x64_ro, debugfs_u64_get, NULL, "0x%016llx\n");
39782b7d4fbSStephen Boyd DEFINE_SIMPLE_ATTRIBUTE(fops_x64_wo, NULL, debugfs_u64_set, "0x%016llx\n");
39815b0beaaSHuang Ying 
399e6716b87SRandy Dunlap /*
40015b0beaaSHuang Ying  * debugfs_create_x{8,16,32,64} - create a debugfs file that is used to read and write an unsigned {8,16,32,64}-bit value
401e6716b87SRandy Dunlap  *
402e6716b87SRandy Dunlap  * These functions are exactly the same as the above functions (but use a hex
403e6716b87SRandy Dunlap  * output for the decimal challenged). For details look at the above unsigned
404e6716b87SRandy Dunlap  * decimal functions.
405e6716b87SRandy Dunlap  */
406e6716b87SRandy Dunlap 
4072ebefc50SRobin Getz /**
4082ebefc50SRobin Getz  * debugfs_create_x8 - create a debugfs file that is used to read and write an unsigned 8-bit value
409e6716b87SRandy Dunlap  * @name: a pointer to a string containing the name of the file to create.
410e6716b87SRandy Dunlap  * @mode: the permission that the file should have
411e6716b87SRandy Dunlap  * @parent: a pointer to the parent dentry for this file.  This should be a
412e6716b87SRandy Dunlap  *          directory dentry if set.  If this parameter is %NULL, then the
413e6716b87SRandy Dunlap  *          file will be created in the root of the debugfs filesystem.
414e6716b87SRandy Dunlap  * @value: a pointer to the variable that the file should read to and write
415e6716b87SRandy Dunlap  *         from.
4162ebefc50SRobin Getz  */
417f4ae40a6SAl Viro struct dentry *debugfs_create_x8(const char *name, umode_t mode,
4182ebefc50SRobin Getz 				 struct dentry *parent, u8 *value)
4192ebefc50SRobin Getz {
420b97f6799SStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_x8,
421b97f6799SStephen Boyd 				   &fops_x8_ro, &fops_x8_wo);
4222ebefc50SRobin Getz }
4232ebefc50SRobin Getz EXPORT_SYMBOL_GPL(debugfs_create_x8);
4242ebefc50SRobin Getz 
425e6716b87SRandy Dunlap /**
426e6716b87SRandy Dunlap  * debugfs_create_x16 - create a debugfs file that is used to read and write an unsigned 16-bit value
427e6716b87SRandy Dunlap  * @name: a pointer to a string containing the name of the file to create.
428e6716b87SRandy Dunlap  * @mode: the permission that the file should have
429e6716b87SRandy Dunlap  * @parent: a pointer to the parent dentry for this file.  This should be a
430e6716b87SRandy Dunlap  *          directory dentry if set.  If this parameter is %NULL, then the
431e6716b87SRandy Dunlap  *          file will be created in the root of the debugfs filesystem.
432e6716b87SRandy Dunlap  * @value: a pointer to the variable that the file should read to and write
433e6716b87SRandy Dunlap  *         from.
434e6716b87SRandy Dunlap  */
435f4ae40a6SAl Viro struct dentry *debugfs_create_x16(const char *name, umode_t mode,
4362ebefc50SRobin Getz 				 struct dentry *parent, u16 *value)
4372ebefc50SRobin Getz {
438b97f6799SStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_x16,
439b97f6799SStephen Boyd 				   &fops_x16_ro, &fops_x16_wo);
4402ebefc50SRobin Getz }
4412ebefc50SRobin Getz EXPORT_SYMBOL_GPL(debugfs_create_x16);
4422ebefc50SRobin Getz 
443e6716b87SRandy Dunlap /**
444e6716b87SRandy Dunlap  * debugfs_create_x32 - create a debugfs file that is used to read and write an unsigned 32-bit value
445e6716b87SRandy Dunlap  * @name: a pointer to a string containing the name of the file to create.
446e6716b87SRandy Dunlap  * @mode: the permission that the file should have
447e6716b87SRandy Dunlap  * @parent: a pointer to the parent dentry for this file.  This should be a
448e6716b87SRandy Dunlap  *          directory dentry if set.  If this parameter is %NULL, then the
449e6716b87SRandy Dunlap  *          file will be created in the root of the debugfs filesystem.
450e6716b87SRandy Dunlap  * @value: a pointer to the variable that the file should read to and write
451e6716b87SRandy Dunlap  *         from.
452e6716b87SRandy Dunlap  */
453f4ae40a6SAl Viro struct dentry *debugfs_create_x32(const char *name, umode_t mode,
4542ebefc50SRobin Getz 				 struct dentry *parent, u32 *value)
4552ebefc50SRobin Getz {
456b97f6799SStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_x32,
457b97f6799SStephen Boyd 				   &fops_x32_ro, &fops_x32_wo);
4582ebefc50SRobin Getz }
4592ebefc50SRobin Getz EXPORT_SYMBOL_GPL(debugfs_create_x32);
4602ebefc50SRobin Getz 
46115b0beaaSHuang Ying /**
46215b0beaaSHuang Ying  * debugfs_create_x64 - create a debugfs file that is used to read and write an unsigned 64-bit value
46315b0beaaSHuang Ying  * @name: a pointer to a string containing the name of the file to create.
46415b0beaaSHuang Ying  * @mode: the permission that the file should have
46515b0beaaSHuang Ying  * @parent: a pointer to the parent dentry for this file.  This should be a
46615b0beaaSHuang Ying  *          directory dentry if set.  If this parameter is %NULL, then the
46715b0beaaSHuang Ying  *          file will be created in the root of the debugfs filesystem.
46815b0beaaSHuang Ying  * @value: a pointer to the variable that the file should read to and write
46915b0beaaSHuang Ying  *         from.
47015b0beaaSHuang Ying  */
471f4ae40a6SAl Viro struct dentry *debugfs_create_x64(const char *name, umode_t mode,
47215b0beaaSHuang Ying 				 struct dentry *parent, u64 *value)
47315b0beaaSHuang Ying {
47482b7d4fbSStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_x64,
47582b7d4fbSStephen Boyd 				   &fops_x64_ro, &fops_x64_wo);
47615b0beaaSHuang Ying }
47715b0beaaSHuang Ying EXPORT_SYMBOL_GPL(debugfs_create_x64);
47815b0beaaSHuang Ying 
4795e078787SInaky Perez-Gonzalez 
4805e078787SInaky Perez-Gonzalez static int debugfs_size_t_set(void *data, u64 val)
4815e078787SInaky Perez-Gonzalez {
4825e078787SInaky Perez-Gonzalez 	*(size_t *)data = val;
4835e078787SInaky Perez-Gonzalez 	return 0;
4845e078787SInaky Perez-Gonzalez }
4855e078787SInaky Perez-Gonzalez static int debugfs_size_t_get(void *data, u64 *val)
4865e078787SInaky Perez-Gonzalez {
4875e078787SInaky Perez-Gonzalez 	*val = *(size_t *)data;
4885e078787SInaky Perez-Gonzalez 	return 0;
4895e078787SInaky Perez-Gonzalez }
4905e078787SInaky Perez-Gonzalez DEFINE_SIMPLE_ATTRIBUTE(fops_size_t, debugfs_size_t_get, debugfs_size_t_set,
4915e078787SInaky Perez-Gonzalez 			"%llu\n");	/* %llu and %zu are more or less the same */
4926db6652aSStephen Boyd DEFINE_SIMPLE_ATTRIBUTE(fops_size_t_ro, debugfs_size_t_get, NULL, "%llu\n");
4936db6652aSStephen Boyd DEFINE_SIMPLE_ATTRIBUTE(fops_size_t_wo, NULL, debugfs_size_t_set, "%llu\n");
4945e078787SInaky Perez-Gonzalez 
4955e078787SInaky Perez-Gonzalez /**
4965e078787SInaky Perez-Gonzalez  * debugfs_create_size_t - create a debugfs file that is used to read and write an size_t value
4975e078787SInaky Perez-Gonzalez  * @name: a pointer to a string containing the name of the file to create.
4985e078787SInaky Perez-Gonzalez  * @mode: the permission that the file should have
4995e078787SInaky Perez-Gonzalez  * @parent: a pointer to the parent dentry for this file.  This should be a
5005e078787SInaky Perez-Gonzalez  *          directory dentry if set.  If this parameter is %NULL, then the
5015e078787SInaky Perez-Gonzalez  *          file will be created in the root of the debugfs filesystem.
5025e078787SInaky Perez-Gonzalez  * @value: a pointer to the variable that the file should read to and write
5035e078787SInaky Perez-Gonzalez  *         from.
5045e078787SInaky Perez-Gonzalez  */
505f4ae40a6SAl Viro struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
5065e078787SInaky Perez-Gonzalez 				     struct dentry *parent, size_t *value)
5075e078787SInaky Perez-Gonzalez {
5086db6652aSStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_size_t,
5096db6652aSStephen Boyd 				   &fops_size_t_ro, &fops_size_t_wo);
5105e078787SInaky Perez-Gonzalez }
5115e078787SInaky Perez-Gonzalez EXPORT_SYMBOL_GPL(debugfs_create_size_t);
5125e078787SInaky Perez-Gonzalez 
5133a76e5e0SSeth Jennings static int debugfs_atomic_t_set(void *data, u64 val)
5143a76e5e0SSeth Jennings {
5153a76e5e0SSeth Jennings 	atomic_set((atomic_t *)data, val);
5163a76e5e0SSeth Jennings 	return 0;
5173a76e5e0SSeth Jennings }
5183a76e5e0SSeth Jennings static int debugfs_atomic_t_get(void *data, u64 *val)
5193a76e5e0SSeth Jennings {
5203a76e5e0SSeth Jennings 	*val = atomic_read((atomic_t *)data);
5213a76e5e0SSeth Jennings 	return 0;
5223a76e5e0SSeth Jennings }
5233a76e5e0SSeth Jennings DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
5243a76e5e0SSeth Jennings 			debugfs_atomic_t_set, "%lld\n");
5253a76e5e0SSeth Jennings DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, "%lld\n");
5263a76e5e0SSeth Jennings DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, "%lld\n");
5273a76e5e0SSeth Jennings 
5283a76e5e0SSeth Jennings /**
5293a76e5e0SSeth Jennings  * debugfs_create_atomic_t - create a debugfs file that is used to read and
5303a76e5e0SSeth Jennings  * write an atomic_t value
5313a76e5e0SSeth Jennings  * @name: a pointer to a string containing the name of the file to create.
5323a76e5e0SSeth Jennings  * @mode: the permission that the file should have
5333a76e5e0SSeth Jennings  * @parent: a pointer to the parent dentry for this file.  This should be a
5343a76e5e0SSeth Jennings  *          directory dentry if set.  If this parameter is %NULL, then the
5353a76e5e0SSeth Jennings  *          file will be created in the root of the debugfs filesystem.
5363a76e5e0SSeth Jennings  * @value: a pointer to the variable that the file should read to and write
5373a76e5e0SSeth Jennings  *         from.
5383a76e5e0SSeth Jennings  */
5393a76e5e0SSeth Jennings struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
5403a76e5e0SSeth Jennings 				 struct dentry *parent, atomic_t *value)
5413a76e5e0SSeth Jennings {
542b97f6799SStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_atomic_t,
543b97f6799SStephen Boyd 				   &fops_atomic_t_ro, &fops_atomic_t_wo);
5443a76e5e0SSeth Jennings }
5453a76e5e0SSeth Jennings EXPORT_SYMBOL_GPL(debugfs_create_atomic_t);
5465e078787SInaky Perez-Gonzalez 
5470642ef6fSRichard Fitzgerald ssize_t debugfs_read_file_bool(struct file *file, char __user *user_buf,
5481da177e4SLinus Torvalds 			       size_t count, loff_t *ppos)
5491da177e4SLinus Torvalds {
5501da177e4SLinus Torvalds 	char buf[3];
551621a5f7aSViresh Kumar 	bool *val = file->private_data;
5521da177e4SLinus Torvalds 
5531da177e4SLinus Torvalds 	if (*val)
5541da177e4SLinus Torvalds 		buf[0] = 'Y';
5551da177e4SLinus Torvalds 	else
5561da177e4SLinus Torvalds 		buf[0] = 'N';
5571da177e4SLinus Torvalds 	buf[1] = '\n';
5581da177e4SLinus Torvalds 	buf[2] = 0x00;
5591da177e4SLinus Torvalds 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
5601da177e4SLinus Torvalds }
5610642ef6fSRichard Fitzgerald EXPORT_SYMBOL_GPL(debugfs_read_file_bool);
5621da177e4SLinus Torvalds 
5630642ef6fSRichard Fitzgerald ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf,
5641da177e4SLinus Torvalds 				size_t count, loff_t *ppos)
5651da177e4SLinus Torvalds {
5661da177e4SLinus Torvalds 	char buf[32];
567c42d2237SStephen Boyd 	size_t buf_size;
5688705b48eSJonathan Cameron 	bool bv;
569621a5f7aSViresh Kumar 	bool *val = file->private_data;
5701da177e4SLinus Torvalds 
5711da177e4SLinus Torvalds 	buf_size = min(count, (sizeof(buf)-1));
5721da177e4SLinus Torvalds 	if (copy_from_user(buf, user_buf, buf_size))
5731da177e4SLinus Torvalds 		return -EFAULT;
5741da177e4SLinus Torvalds 
575a3b2c8c7SMathias Krause 	buf[buf_size] = '\0';
5768705b48eSJonathan Cameron 	if (strtobool(buf, &bv) == 0)
5778705b48eSJonathan Cameron 		*val = bv;
5781da177e4SLinus Torvalds 
5791da177e4SLinus Torvalds 	return count;
5801da177e4SLinus Torvalds }
5810642ef6fSRichard Fitzgerald EXPORT_SYMBOL_GPL(debugfs_write_file_bool);
5821da177e4SLinus Torvalds 
5834b6f5d20SArjan van de Ven static const struct file_operations fops_bool = {
5840642ef6fSRichard Fitzgerald 	.read =		debugfs_read_file_bool,
5850642ef6fSRichard Fitzgerald 	.write =	debugfs_write_file_bool,
586234e3405SStephen Boyd 	.open =		simple_open,
5876038f373SArnd Bergmann 	.llseek =	default_llseek,
5881da177e4SLinus Torvalds };
5891da177e4SLinus Torvalds 
5906713e8fbSStephen Boyd static const struct file_operations fops_bool_ro = {
5916713e8fbSStephen Boyd 	.read =		debugfs_read_file_bool,
5926713e8fbSStephen Boyd 	.open =		simple_open,
5936713e8fbSStephen Boyd 	.llseek =	default_llseek,
5946713e8fbSStephen Boyd };
5956713e8fbSStephen Boyd 
5966713e8fbSStephen Boyd static const struct file_operations fops_bool_wo = {
5976713e8fbSStephen Boyd 	.write =	debugfs_write_file_bool,
5986713e8fbSStephen Boyd 	.open =		simple_open,
5996713e8fbSStephen Boyd 	.llseek =	default_llseek,
6006713e8fbSStephen Boyd };
6016713e8fbSStephen Boyd 
6021da177e4SLinus Torvalds /**
6036468b3afSRandy Dunlap  * debugfs_create_bool - create a debugfs file that is used to read and write a boolean value
6041da177e4SLinus Torvalds  * @name: a pointer to a string containing the name of the file to create.
6051da177e4SLinus Torvalds  * @mode: the permission that the file should have
6061da177e4SLinus Torvalds  * @parent: a pointer to the parent dentry for this file.  This should be a
6076468b3afSRandy Dunlap  *          directory dentry if set.  If this parameter is %NULL, then the
6081da177e4SLinus Torvalds  *          file will be created in the root of the debugfs filesystem.
6091da177e4SLinus Torvalds  * @value: a pointer to the variable that the file should read to and write
6101da177e4SLinus Torvalds  *         from.
6111da177e4SLinus Torvalds  *
6121da177e4SLinus Torvalds  * This function creates a file in debugfs with the given name that
6131da177e4SLinus Torvalds  * contains the value of the variable @value.  If the @mode variable is so
6141da177e4SLinus Torvalds  * set, it can be read from, and written to.
6151da177e4SLinus Torvalds  *
6161da177e4SLinus Torvalds  * This function will return a pointer to a dentry if it succeeds.  This
6171da177e4SLinus Torvalds  * pointer must be passed to the debugfs_remove() function when the file is
6181da177e4SLinus Torvalds  * to be removed (no automatic cleanup happens if your module is unloaded,
6196468b3afSRandy Dunlap  * you are responsible here.)  If an error occurs, %NULL will be returned.
6201da177e4SLinus Torvalds  *
6216468b3afSRandy Dunlap  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
6221da177e4SLinus Torvalds  * returned.  It is not wise to check for this value, but rather, check for
6236468b3afSRandy Dunlap  * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
6241da177e4SLinus Torvalds  * code.
6251da177e4SLinus Torvalds  */
626f4ae40a6SAl Viro struct dentry *debugfs_create_bool(const char *name, umode_t mode,
627621a5f7aSViresh Kumar 				   struct dentry *parent, bool *value)
6281da177e4SLinus Torvalds {
6296713e8fbSStephen Boyd 	return debugfs_create_mode(name, mode, parent, value, &fops_bool,
6306713e8fbSStephen Boyd 				   &fops_bool_ro, &fops_bool_wo);
6311da177e4SLinus Torvalds }
6321da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(debugfs_create_bool);
6331da177e4SLinus Torvalds 
634dd308bc3SMichael Ellerman static ssize_t read_file_blob(struct file *file, char __user *user_buf,
635dd308bc3SMichael Ellerman 			      size_t count, loff_t *ppos)
636dd308bc3SMichael Ellerman {
637dd308bc3SMichael Ellerman 	struct debugfs_blob_wrapper *blob = file->private_data;
638dd308bc3SMichael Ellerman 	return simple_read_from_buffer(user_buf, count, ppos, blob->data,
639dd308bc3SMichael Ellerman 			blob->size);
640dd308bc3SMichael Ellerman }
641dd308bc3SMichael Ellerman 
64200977a59SArjan van de Ven static const struct file_operations fops_blob = {
643dd308bc3SMichael Ellerman 	.read =		read_file_blob,
644234e3405SStephen Boyd 	.open =		simple_open,
6456038f373SArnd Bergmann 	.llseek =	default_llseek,
646dd308bc3SMichael Ellerman };
647dd308bc3SMichael Ellerman 
648dd308bc3SMichael Ellerman /**
649400ced61SJonathan Corbet  * debugfs_create_blob - create a debugfs file that is used to read a binary blob
650dd308bc3SMichael Ellerman  * @name: a pointer to a string containing the name of the file to create.
651dd308bc3SMichael Ellerman  * @mode: the permission that the file should have
652dd308bc3SMichael Ellerman  * @parent: a pointer to the parent dentry for this file.  This should be a
6536468b3afSRandy Dunlap  *          directory dentry if set.  If this parameter is %NULL, then the
654dd308bc3SMichael Ellerman  *          file will be created in the root of the debugfs filesystem.
655dd308bc3SMichael Ellerman  * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
656dd308bc3SMichael Ellerman  *        to the blob data and the size of the data.
657dd308bc3SMichael Ellerman  *
658dd308bc3SMichael Ellerman  * This function creates a file in debugfs with the given name that exports
659dd308bc3SMichael Ellerman  * @blob->data as a binary blob. If the @mode variable is so set it can be
660dd308bc3SMichael Ellerman  * read from. Writing is not supported.
661dd308bc3SMichael Ellerman  *
662dd308bc3SMichael Ellerman  * This function will return a pointer to a dentry if it succeeds.  This
663dd308bc3SMichael Ellerman  * pointer must be passed to the debugfs_remove() function when the file is
664dd308bc3SMichael Ellerman  * to be removed (no automatic cleanup happens if your module is unloaded,
6656468b3afSRandy Dunlap  * you are responsible here.)  If an error occurs, %NULL will be returned.
666dd308bc3SMichael Ellerman  *
6676468b3afSRandy Dunlap  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
668dd308bc3SMichael Ellerman  * returned.  It is not wise to check for this value, but rather, check for
6696468b3afSRandy Dunlap  * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
670dd308bc3SMichael Ellerman  * code.
671dd308bc3SMichael Ellerman  */
672f4ae40a6SAl Viro struct dentry *debugfs_create_blob(const char *name, umode_t mode,
673dd308bc3SMichael Ellerman 				   struct dentry *parent,
674dd308bc3SMichael Ellerman 				   struct debugfs_blob_wrapper *blob)
675dd308bc3SMichael Ellerman {
676dd308bc3SMichael Ellerman 	return debugfs_create_file(name, mode, parent, blob, &fops_blob);
677dd308bc3SMichael Ellerman }
678dd308bc3SMichael Ellerman EXPORT_SYMBOL_GPL(debugfs_create_blob);
6791a087c6aSAlessandro Rubini 
6809fe2a701SSrivatsa Vaddagiri struct array_data {
6819fe2a701SSrivatsa Vaddagiri 	void *array;
6829fe2a701SSrivatsa Vaddagiri 	u32 elements;
6839fe2a701SSrivatsa Vaddagiri };
6849fe2a701SSrivatsa Vaddagiri 
685e05e279eSLinus Torvalds static size_t u32_format_array(char *buf, size_t bufsize,
686e05e279eSLinus Torvalds 			       u32 *array, int array_size)
6879fe2a701SSrivatsa Vaddagiri {
6889fe2a701SSrivatsa Vaddagiri 	size_t ret = 0;
6899fe2a701SSrivatsa Vaddagiri 
690e05e279eSLinus Torvalds 	while (--array_size >= 0) {
6919fe2a701SSrivatsa Vaddagiri 		size_t len;
692e05e279eSLinus Torvalds 		char term = array_size ? ' ' : '\n';
6939fe2a701SSrivatsa Vaddagiri 
694e05e279eSLinus Torvalds 		len = snprintf(buf, bufsize, "%u%c", *array++, term);
6959fe2a701SSrivatsa Vaddagiri 		ret += len;
6969fe2a701SSrivatsa Vaddagiri 
6979fe2a701SSrivatsa Vaddagiri 		buf += len;
6989fe2a701SSrivatsa Vaddagiri 		bufsize -= len;
6999fe2a701SSrivatsa Vaddagiri 	}
7009fe2a701SSrivatsa Vaddagiri 	return ret;
7019fe2a701SSrivatsa Vaddagiri }
7029fe2a701SSrivatsa Vaddagiri 
70336048853SDavid Rientjes static int u32_array_open(struct inode *inode, struct file *file)
7049fe2a701SSrivatsa Vaddagiri {
7059fe2a701SSrivatsa Vaddagiri 	struct array_data *data = inode->i_private;
706e05e279eSLinus Torvalds 	int size, elements = data->elements;
707e05e279eSLinus Torvalds 	char *buf;
7089fe2a701SSrivatsa Vaddagiri 
709e05e279eSLinus Torvalds 	/*
710e05e279eSLinus Torvalds 	 * Max size:
711e05e279eSLinus Torvalds 	 *  - 10 digits + ' '/'\n' = 11 bytes per number
712e05e279eSLinus Torvalds 	 *  - terminating NUL character
713e05e279eSLinus Torvalds 	 */
714e05e279eSLinus Torvalds 	size = elements*11;
715e05e279eSLinus Torvalds 	buf = kmalloc(size+1, GFP_KERNEL);
716e05e279eSLinus Torvalds 	if (!buf)
71736048853SDavid Rientjes 		return -ENOMEM;
718e05e279eSLinus Torvalds 	buf[size] = 0;
719e05e279eSLinus Torvalds 
720e05e279eSLinus Torvalds 	file->private_data = buf;
721e05e279eSLinus Torvalds 	u32_format_array(buf, size, data->array, data->elements);
722e05e279eSLinus Torvalds 
72336048853SDavid Rientjes 	return nonseekable_open(inode, file);
7249fe2a701SSrivatsa Vaddagiri }
7259fe2a701SSrivatsa Vaddagiri 
72636048853SDavid Rientjes static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,
72736048853SDavid Rientjes 			      loff_t *ppos)
72836048853SDavid Rientjes {
72936048853SDavid Rientjes 	size_t size = strlen(file->private_data);
7309fe2a701SSrivatsa Vaddagiri 
7319fe2a701SSrivatsa Vaddagiri 	return simple_read_from_buffer(buf, len, ppos,
7329fe2a701SSrivatsa Vaddagiri 					file->private_data, size);
7339fe2a701SSrivatsa Vaddagiri }
7349fe2a701SSrivatsa Vaddagiri 
7359fe2a701SSrivatsa Vaddagiri static int u32_array_release(struct inode *inode, struct file *file)
7369fe2a701SSrivatsa Vaddagiri {
7379fe2a701SSrivatsa Vaddagiri 	kfree(file->private_data);
7389fe2a701SSrivatsa Vaddagiri 
7399fe2a701SSrivatsa Vaddagiri 	return 0;
7409fe2a701SSrivatsa Vaddagiri }
7419fe2a701SSrivatsa Vaddagiri 
7429fe2a701SSrivatsa Vaddagiri static const struct file_operations u32_array_fops = {
7439fe2a701SSrivatsa Vaddagiri 	.owner	 = THIS_MODULE,
7449fe2a701SSrivatsa Vaddagiri 	.open	 = u32_array_open,
7459fe2a701SSrivatsa Vaddagiri 	.release = u32_array_release,
7469fe2a701SSrivatsa Vaddagiri 	.read	 = u32_array_read,
7479fe2a701SSrivatsa Vaddagiri 	.llseek  = no_llseek,
7489fe2a701SSrivatsa Vaddagiri };
7499fe2a701SSrivatsa Vaddagiri 
7509fe2a701SSrivatsa Vaddagiri /**
7519fe2a701SSrivatsa Vaddagiri  * debugfs_create_u32_array - create a debugfs file that is used to read u32
7529fe2a701SSrivatsa Vaddagiri  * array.
7539fe2a701SSrivatsa Vaddagiri  * @name: a pointer to a string containing the name of the file to create.
7549fe2a701SSrivatsa Vaddagiri  * @mode: the permission that the file should have.
7559fe2a701SSrivatsa Vaddagiri  * @parent: a pointer to the parent dentry for this file.  This should be a
7569fe2a701SSrivatsa Vaddagiri  *          directory dentry if set.  If this parameter is %NULL, then the
7579fe2a701SSrivatsa Vaddagiri  *          file will be created in the root of the debugfs filesystem.
7589fe2a701SSrivatsa Vaddagiri  * @array: u32 array that provides data.
7599fe2a701SSrivatsa Vaddagiri  * @elements: total number of elements in the array.
7609fe2a701SSrivatsa Vaddagiri  *
7619fe2a701SSrivatsa Vaddagiri  * This function creates a file in debugfs with the given name that exports
7629fe2a701SSrivatsa Vaddagiri  * @array as data. If the @mode variable is so set it can be read from.
7639fe2a701SSrivatsa Vaddagiri  * Writing is not supported. Seek within the file is also not supported.
7649fe2a701SSrivatsa Vaddagiri  * Once array is created its size can not be changed.
7659fe2a701SSrivatsa Vaddagiri  *
7669fe2a701SSrivatsa Vaddagiri  * The function returns a pointer to dentry on success. If debugfs is not
7679fe2a701SSrivatsa Vaddagiri  * enabled in the kernel, the value -%ENODEV will be returned.
7689fe2a701SSrivatsa Vaddagiri  */
7699fe2a701SSrivatsa Vaddagiri struct dentry *debugfs_create_u32_array(const char *name, umode_t mode,
7709fe2a701SSrivatsa Vaddagiri 					    struct dentry *parent,
7719fe2a701SSrivatsa Vaddagiri 					    u32 *array, u32 elements)
7729fe2a701SSrivatsa Vaddagiri {
7739fe2a701SSrivatsa Vaddagiri 	struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
7749fe2a701SSrivatsa Vaddagiri 
7759fe2a701SSrivatsa Vaddagiri 	if (data == NULL)
7769fe2a701SSrivatsa Vaddagiri 		return NULL;
7779fe2a701SSrivatsa Vaddagiri 
7789fe2a701SSrivatsa Vaddagiri 	data->array = array;
7799fe2a701SSrivatsa Vaddagiri 	data->elements = elements;
7809fe2a701SSrivatsa Vaddagiri 
7819fe2a701SSrivatsa Vaddagiri 	return debugfs_create_file(name, mode, parent, data, &u32_array_fops);
7829fe2a701SSrivatsa Vaddagiri }
7839fe2a701SSrivatsa Vaddagiri EXPORT_SYMBOL_GPL(debugfs_create_u32_array);
7849fe2a701SSrivatsa Vaddagiri 
7853b85e4abSHeiko Carstens #ifdef CONFIG_HAS_IOMEM
7863b85e4abSHeiko Carstens 
7871a087c6aSAlessandro Rubini /*
7881a087c6aSAlessandro Rubini  * The regset32 stuff is used to print 32-bit registers using the
7891a087c6aSAlessandro Rubini  * seq_file utilities. We offer printing a register set in an already-opened
7901a087c6aSAlessandro Rubini  * sequential file or create a debugfs file that only prints a regset32.
7911a087c6aSAlessandro Rubini  */
7921a087c6aSAlessandro Rubini 
7931a087c6aSAlessandro Rubini /**
7941a087c6aSAlessandro Rubini  * debugfs_print_regs32 - use seq_print to describe a set of registers
7951a087c6aSAlessandro Rubini  * @s: the seq_file structure being used to generate output
7961a087c6aSAlessandro Rubini  * @regs: an array if struct debugfs_reg32 structures
797b5763accSRandy Dunlap  * @nregs: the length of the above array
7981a087c6aSAlessandro Rubini  * @base: the base address to be used in reading the registers
7991a087c6aSAlessandro Rubini  * @prefix: a string to be prefixed to every output line
8001a087c6aSAlessandro Rubini  *
8011a087c6aSAlessandro Rubini  * This function outputs a text block describing the current values of
8021a087c6aSAlessandro Rubini  * some 32-bit hardware registers. It is meant to be used within debugfs
8031a087c6aSAlessandro Rubini  * files based on seq_file that need to show registers, intermixed with other
8041a087c6aSAlessandro Rubini  * information. The prefix argument may be used to specify a leading string,
8051a087c6aSAlessandro Rubini  * because some peripherals have several blocks of identical registers,
8061a087c6aSAlessandro Rubini  * for example configuration of dma channels
8071a087c6aSAlessandro Rubini  */
8089761536eSJoe Perches void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs,
8091a087c6aSAlessandro Rubini 			  int nregs, void __iomem *base, char *prefix)
8101a087c6aSAlessandro Rubini {
8119761536eSJoe Perches 	int i;
8121a087c6aSAlessandro Rubini 
8131a087c6aSAlessandro Rubini 	for (i = 0; i < nregs; i++, regs++) {
8141a087c6aSAlessandro Rubini 		if (prefix)
8159761536eSJoe Perches 			seq_printf(s, "%s", prefix);
8169761536eSJoe Perches 		seq_printf(s, "%s = 0x%08x\n", regs->name,
8175858441cSDan Carpenter 			   readl(base + regs->offset));
8189761536eSJoe Perches 		if (seq_has_overflowed(s))
8199761536eSJoe Perches 			break;
8201a087c6aSAlessandro Rubini 	}
8211a087c6aSAlessandro Rubini }
8221a087c6aSAlessandro Rubini EXPORT_SYMBOL_GPL(debugfs_print_regs32);
8231a087c6aSAlessandro Rubini 
8241a087c6aSAlessandro Rubini static int debugfs_show_regset32(struct seq_file *s, void *data)
8251a087c6aSAlessandro Rubini {
8261a087c6aSAlessandro Rubini 	struct debugfs_regset32 *regset = s->private;
8271a087c6aSAlessandro Rubini 
8281a087c6aSAlessandro Rubini 	debugfs_print_regs32(s, regset->regs, regset->nregs, regset->base, "");
8291a087c6aSAlessandro Rubini 	return 0;
8301a087c6aSAlessandro Rubini }
8311a087c6aSAlessandro Rubini 
8321a087c6aSAlessandro Rubini static int debugfs_open_regset32(struct inode *inode, struct file *file)
8331a087c6aSAlessandro Rubini {
8341a087c6aSAlessandro Rubini 	return single_open(file, debugfs_show_regset32, inode->i_private);
8351a087c6aSAlessandro Rubini }
8361a087c6aSAlessandro Rubini 
8371a087c6aSAlessandro Rubini static const struct file_operations fops_regset32 = {
8381a087c6aSAlessandro Rubini 	.open =		debugfs_open_regset32,
8391a087c6aSAlessandro Rubini 	.read =		seq_read,
8401a087c6aSAlessandro Rubini 	.llseek =	seq_lseek,
8411a087c6aSAlessandro Rubini 	.release =	single_release,
8421a087c6aSAlessandro Rubini };
8431a087c6aSAlessandro Rubini 
8441a087c6aSAlessandro Rubini /**
8451a087c6aSAlessandro Rubini  * debugfs_create_regset32 - create a debugfs file that returns register values
8461a087c6aSAlessandro Rubini  * @name: a pointer to a string containing the name of the file to create.
8471a087c6aSAlessandro Rubini  * @mode: the permission that the file should have
8481a087c6aSAlessandro Rubini  * @parent: a pointer to the parent dentry for this file.  This should be a
8491a087c6aSAlessandro Rubini  *          directory dentry if set.  If this parameter is %NULL, then the
8501a087c6aSAlessandro Rubini  *          file will be created in the root of the debugfs filesystem.
8511a087c6aSAlessandro Rubini  * @regset: a pointer to a struct debugfs_regset32, which contains a pointer
8521a087c6aSAlessandro Rubini  *          to an array of register definitions, the array size and the base
8531a087c6aSAlessandro Rubini  *          address where the register bank is to be found.
8541a087c6aSAlessandro Rubini  *
8551a087c6aSAlessandro Rubini  * This function creates a file in debugfs with the given name that reports
8561a087c6aSAlessandro Rubini  * the names and values of a set of 32-bit registers. If the @mode variable
8571a087c6aSAlessandro Rubini  * is so set it can be read from. Writing is not supported.
8581a087c6aSAlessandro Rubini  *
8591a087c6aSAlessandro Rubini  * This function will return a pointer to a dentry if it succeeds.  This
8601a087c6aSAlessandro Rubini  * pointer must be passed to the debugfs_remove() function when the file is
8611a087c6aSAlessandro Rubini  * to be removed (no automatic cleanup happens if your module is unloaded,
8621a087c6aSAlessandro Rubini  * you are responsible here.)  If an error occurs, %NULL will be returned.
8631a087c6aSAlessandro Rubini  *
8641a087c6aSAlessandro Rubini  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
8651a087c6aSAlessandro Rubini  * returned.  It is not wise to check for this value, but rather, check for
8661a087c6aSAlessandro Rubini  * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
8671a087c6aSAlessandro Rubini  * code.
8681a087c6aSAlessandro Rubini  */
86988187398SAl Viro struct dentry *debugfs_create_regset32(const char *name, umode_t mode,
8701a087c6aSAlessandro Rubini 				       struct dentry *parent,
8711a087c6aSAlessandro Rubini 				       struct debugfs_regset32 *regset)
8721a087c6aSAlessandro Rubini {
8731a087c6aSAlessandro Rubini 	return debugfs_create_file(name, mode, parent, regset, &fops_regset32);
8741a087c6aSAlessandro Rubini }
8751a087c6aSAlessandro Rubini EXPORT_SYMBOL_GPL(debugfs_create_regset32);
8763b85e4abSHeiko Carstens 
8773b85e4abSHeiko Carstens #endif /* CONFIG_HAS_IOMEM */
87898210b7fSArend van Spriel 
87998210b7fSArend van Spriel struct debugfs_devm_entry {
88098210b7fSArend van Spriel 	int (*read)(struct seq_file *seq, void *data);
88198210b7fSArend van Spriel 	struct device *dev;
88298210b7fSArend van Spriel };
88398210b7fSArend van Spriel 
88498210b7fSArend van Spriel static int debugfs_devm_entry_open(struct inode *inode, struct file *f)
88598210b7fSArend van Spriel {
88698210b7fSArend van Spriel 	struct debugfs_devm_entry *entry = inode->i_private;
88798210b7fSArend van Spriel 
88898210b7fSArend van Spriel 	return single_open(f, entry->read, entry->dev);
88998210b7fSArend van Spriel }
89098210b7fSArend van Spriel 
89198210b7fSArend van Spriel static const struct file_operations debugfs_devm_entry_ops = {
89298210b7fSArend van Spriel 	.owner = THIS_MODULE,
89398210b7fSArend van Spriel 	.open = debugfs_devm_entry_open,
89498210b7fSArend van Spriel 	.release = single_release,
89598210b7fSArend van Spriel 	.read = seq_read,
89698210b7fSArend van Spriel 	.llseek = seq_lseek
89798210b7fSArend van Spriel };
89898210b7fSArend van Spriel 
89998210b7fSArend van Spriel /**
90098210b7fSArend van Spriel  * debugfs_create_devm_seqfile - create a debugfs file that is bound to device.
90198210b7fSArend van Spriel  *
90298210b7fSArend van Spriel  * @dev: device related to this debugfs file.
90398210b7fSArend van Spriel  * @name: name of the debugfs file.
90498210b7fSArend van Spriel  * @parent: a pointer to the parent dentry for this file.  This should be a
90598210b7fSArend van Spriel  *	directory dentry if set.  If this parameter is %NULL, then the
90698210b7fSArend van Spriel  *	file will be created in the root of the debugfs filesystem.
90798210b7fSArend van Spriel  * @read_fn: function pointer called to print the seq_file content.
90898210b7fSArend van Spriel  */
90998210b7fSArend van Spriel struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,
91098210b7fSArend van Spriel 					   struct dentry *parent,
91198210b7fSArend van Spriel 					   int (*read_fn)(struct seq_file *s,
91298210b7fSArend van Spriel 							  void *data))
91398210b7fSArend van Spriel {
91498210b7fSArend van Spriel 	struct debugfs_devm_entry *entry;
91598210b7fSArend van Spriel 
91698210b7fSArend van Spriel 	if (IS_ERR(parent))
91798210b7fSArend van Spriel 		return ERR_PTR(-ENOENT);
91898210b7fSArend van Spriel 
91998210b7fSArend van Spriel 	entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL);
92098210b7fSArend van Spriel 	if (!entry)
92198210b7fSArend van Spriel 		return ERR_PTR(-ENOMEM);
92298210b7fSArend van Spriel 
92398210b7fSArend van Spriel 	entry->read = read_fn;
92498210b7fSArend van Spriel 	entry->dev = dev;
92598210b7fSArend van Spriel 
92698210b7fSArend van Spriel 	return debugfs_create_file(name, S_IRUGO, parent, entry,
92798210b7fSArend van Spriel 				   &debugfs_devm_entry_ops);
92898210b7fSArend van Spriel }
92998210b7fSArend van Spriel EXPORT_SYMBOL_GPL(debugfs_create_devm_seqfile);
93098210b7fSArend van Spriel 
931