Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *  file.c - part of debugfs, a tiny little debug file system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *  Copyright (C) 2004 IBM Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *  debugfs is for people to use instead of /proc or /sys.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *  See Documentation/filesystems/ for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) struct poll_table_struct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) static ssize_t default_read_file(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 				 size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) static ssize_t default_write_file(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 				   size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) const struct file_operations debugfs_noop_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	.read =		default_read_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	.write =	default_write_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	.open =		simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	.llseek =	noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define F_DENTRY(filp) ((filp)->f_path.dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) const struct file_operations *debugfs_real_fops(const struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	struct debugfs_fsdata *fsd = F_DENTRY(filp)->d_fsdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 		 * Urgh, we've been called w/o a protecting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 		 * debugfs_file_get().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	return fsd->real_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) EXPORT_SYMBOL_GPL(debugfs_real_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68)  * debugfs_file_get - mark the beginning of file data access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69)  * @dentry: the dentry object whose data is being accessed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71)  * Up to a matching call to debugfs_file_put(), any successive call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72)  * into the file removing functions debugfs_remove() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)  * debugfs_remove_recursive() will block. Since associated private
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)  * file data may only get freed after a successful return of any of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  * the removal functions, you may safely access it after a successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * call to debugfs_file_get() without worrying about lifetime issues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * If -%EIO is returned, the file has already been removed and thus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * it is not safe to access any of its data. If, on the other hand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  * it is allowed to access the file data, zero is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) int debugfs_file_get(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	struct debugfs_fsdata *fsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	void *d_fsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	d_fsd = READ_ONCE(dentry->d_fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	if (!((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 		fsd = d_fsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		fsd = kmalloc(sizeof(*fsd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		if (!fsd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		fsd->real_fops = (void *)((unsigned long)d_fsd &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 					~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 		refcount_set(&fsd->active_users, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		init_completion(&fsd->active_users_drained);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		if (cmpxchg(&dentry->d_fsdata, d_fsd, fsd) != d_fsd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 			kfree(fsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 			fsd = READ_ONCE(dentry->d_fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	 * In case of a successful cmpxchg() above, this check is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	 * strictly necessary and must follow it, see the comment in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	 * __debugfs_remove_file().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	 * OTOH, if the cmpxchg() hasn't been executed or wasn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	 * successful, this serves the purpose of not starving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	 * removers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	if (d_unlinked(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	if (!refcount_inc_not_zero(&fsd->active_users))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) EXPORT_SYMBOL_GPL(debugfs_file_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  * debugfs_file_put - mark the end of file data access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  * @dentry: the dentry object formerly passed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  *          debugfs_file_get().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  * Allow any ongoing concurrent call into debugfs_remove() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  * debugfs_remove_recursive() blocked by a former call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  * debugfs_file_get() to proceed and return to its caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) void debugfs_file_put(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	struct debugfs_fsdata *fsd = READ_ONCE(dentry->d_fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	if (refcount_dec_and_test(&fsd->active_users))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 		complete(&fsd->active_users_drained);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) EXPORT_SYMBOL_GPL(debugfs_file_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)  * Only permit access to world-readable files when the kernel is locked down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143)  * We also need to exclude any file that has ways to write or alter it as root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)  * can bypass the permissions check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) static int debugfs_locked_down(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 			       struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 			       const struct file_operations *real_fops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	if ((inode->i_mode & 07777 & ~0444) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	    !(filp->f_mode & FMODE_WRITE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	    !real_fops->unlocked_ioctl &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	    !real_fops->compat_ioctl &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	    !real_fops->mmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	if (security_locked_down(LOCKDOWN_DEBUGFS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) static int open_proxy_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	struct dentry *dentry = F_DENTRY(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	const struct file_operations *real_fops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	r = debugfs_file_get(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		return r == -EIO ? -ENOENT : r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	real_fops = debugfs_real_fops(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	r = debugfs_locked_down(inode, filp, real_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	if (!fops_get(real_fops)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) #ifdef CONFIG_MODULES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		if (real_fops->owner &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		    real_fops->owner->state == MODULE_STATE_GOING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 			r = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		/* Huh? Module did not clean up after itself at exit? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		WARN(1, "debugfs file owner did not clean up at exit: %pd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 			dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		r = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	replace_fops(filp, real_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	if (real_fops->open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		r = real_fops->open(inode, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	debugfs_file_put(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) const struct file_operations debugfs_open_proxy_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	.open = open_proxy_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) #define PROTO(args...) args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) #define ARGS(args...) args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) #define FULL_PROXY_FUNC(name, ret_type, filp, proto, args)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) static ret_type full_proxy_ ## name(proto)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	struct dentry *dentry = F_DENTRY(filp);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	const struct file_operations *real_fops;			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	ret_type r;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	r = debugfs_file_get(dentry);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	if (unlikely(r))						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		return r;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	real_fops = debugfs_real_fops(filp);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	r = real_fops->name(args);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	debugfs_file_put(dentry);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	return r;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) FULL_PROXY_FUNC(llseek, loff_t, filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		PROTO(struct file *filp, loff_t offset, int whence),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		ARGS(filp, offset, whence));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) FULL_PROXY_FUNC(read, ssize_t, filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		PROTO(struct file *filp, char __user *buf, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 			loff_t *ppos),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		ARGS(filp, buf, size, ppos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) FULL_PROXY_FUNC(write, ssize_t, filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		PROTO(struct file *filp, const char __user *buf, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			loff_t *ppos),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		ARGS(filp, buf, size, ppos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) FULL_PROXY_FUNC(unlocked_ioctl, long, filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		PROTO(struct file *filp, unsigned int cmd, unsigned long arg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		ARGS(filp, cmd, arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) static __poll_t full_proxy_poll(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 				struct poll_table_struct *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	struct dentry *dentry = F_DENTRY(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	__poll_t r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	const struct file_operations *real_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	if (debugfs_file_get(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		return EPOLLHUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	real_fops = debugfs_real_fops(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	r = real_fops->poll(filp, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	debugfs_file_put(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) static int full_proxy_release(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	const struct dentry *dentry = F_DENTRY(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	const struct file_operations *real_fops = debugfs_real_fops(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	const struct file_operations *proxy_fops = filp->f_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	 * We must not protect this against removal races here: the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	 * original releaser should be called unconditionally in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	 * not to leak any resources. Releasers must not assume that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	 * ->i_private is still being meaningful here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (real_fops->release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		r = real_fops->release(inode, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	replace_fops(filp, d_inode(dentry)->i_fop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	kfree(proxy_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	fops_put(real_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) static void __full_proxy_fops_init(struct file_operations *proxy_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 				const struct file_operations *real_fops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	proxy_fops->release = full_proxy_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	if (real_fops->llseek)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		proxy_fops->llseek = full_proxy_llseek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	if (real_fops->read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		proxy_fops->read = full_proxy_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	if (real_fops->write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		proxy_fops->write = full_proxy_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (real_fops->poll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		proxy_fops->poll = full_proxy_poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	if (real_fops->unlocked_ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		proxy_fops->unlocked_ioctl = full_proxy_unlocked_ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) static int full_proxy_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	struct dentry *dentry = F_DENTRY(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	const struct file_operations *real_fops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	struct file_operations *proxy_fops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	r = debugfs_file_get(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		return r == -EIO ? -ENOENT : r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	real_fops = debugfs_real_fops(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	r = debugfs_locked_down(inode, filp, real_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	if (!fops_get(real_fops)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) #ifdef CONFIG_MODULES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		if (real_fops->owner &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		    real_fops->owner->state == MODULE_STATE_GOING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			r = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		/* Huh? Module did not cleanup after itself at exit? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		WARN(1, "debugfs file owner did not clean up at exit: %pd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 			dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		r = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	proxy_fops = kzalloc(sizeof(*proxy_fops), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	if (!proxy_fops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		r = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		goto free_proxy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	__full_proxy_fops_init(proxy_fops, real_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	replace_fops(filp, proxy_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	if (real_fops->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		r = real_fops->open(inode, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 			replace_fops(filp, d_inode(dentry)->i_fop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 			goto free_proxy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		} else if (filp->f_op != proxy_fops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 			/* No protection against file removal anymore. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 			WARN(1, "debugfs file owner replaced proxy fops: %pd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 				dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 			goto free_proxy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) free_proxy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	kfree(proxy_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	fops_put(real_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	debugfs_file_put(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) const struct file_operations debugfs_full_proxy_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	.open = full_proxy_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) ssize_t debugfs_attr_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			size_t len, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	struct dentry *dentry = F_DENTRY(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	ret = debugfs_file_get(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	ret = simple_attr_read(file, buf, len, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	debugfs_file_put(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) EXPORT_SYMBOL_GPL(debugfs_attr_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 			 size_t len, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	struct dentry *dentry = F_DENTRY(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	ret = debugfs_file_get(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	ret = simple_attr_write(file, buf, len, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	debugfs_file_put(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) EXPORT_SYMBOL_GPL(debugfs_attr_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) static struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 					struct dentry *parent, void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 					const struct file_operations *fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 					const struct file_operations *fops_ro,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 					const struct file_operations *fops_wo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	/* if there are no write bits set, make read only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	if (!(mode & S_IWUGO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		return debugfs_create_file_unsafe(name, mode, parent, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 						fops_ro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	/* if there are no read bits set, make write only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	if (!(mode & S_IRUGO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		return debugfs_create_file_unsafe(name, mode, parent, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 						fops_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	return debugfs_create_file_unsafe(name, mode, parent, value, fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) static int debugfs_u8_set(void *data, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	*(u8 *)data = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) static int debugfs_u8_get(void *data, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	*val = *(u8 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) DEFINE_DEBUGFS_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_ro, debugfs_u8_get, NULL, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)  * debugfs_create_u8 - create a debugfs file that is used to read and write an unsigned 8-bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438)  * This function creates a file in debugfs with the given name that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439)  * contains the value of the variable @value.  If the @mode variable is so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440)  * set, it can be read from, and written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		       u8 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 				   &fops_u8_ro, &fops_u8_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) EXPORT_SYMBOL_GPL(debugfs_create_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static int debugfs_u16_set(void *data, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	*(u16 *)data = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) static int debugfs_u16_get(void *data, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	*val = *(u16 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) DEFINE_DEBUGFS_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_ro, debugfs_u16_get, NULL, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465)  * debugfs_create_u16 - create a debugfs file that is used to read and write an unsigned 16-bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474)  * This function creates a file in debugfs with the given name that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  * contains the value of the variable @value.  If the @mode variable is so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  * set, it can be read from, and written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 			u16 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 				   &fops_u16_ro, &fops_u16_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) EXPORT_SYMBOL_GPL(debugfs_create_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) static int debugfs_u32_set(void *data, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	*(u32 *)data = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) static int debugfs_u32_get(void *data, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	*val = *(u32 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) DEFINE_DEBUGFS_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_ro, debugfs_u32_get, NULL, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501)  * debugfs_create_u32 - create a debugfs file that is used to read and write an unsigned 32-bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  * This function creates a file in debugfs with the given name that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  * contains the value of the variable @value.  If the @mode variable is so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  * set, it can be read from, and written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) void debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 				   &fops_u32_ro, &fops_u32_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) EXPORT_SYMBOL_GPL(debugfs_create_u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static int debugfs_u64_set(void *data, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	*(u64 *)data = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) static int debugfs_u64_get(void *data, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	*val = *(u64 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) DEFINE_DEBUGFS_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_ro, debugfs_u64_get, NULL, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538)  * debugfs_create_u64 - create a debugfs file that is used to read and write an unsigned 64-bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547)  * This function creates a file in debugfs with the given name that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548)  * contains the value of the variable @value.  If the @mode variable is so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549)  * set, it can be read from, and written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 			u64 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 				   &fops_u64_ro, &fops_u64_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) EXPORT_SYMBOL_GPL(debugfs_create_u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) static int debugfs_ulong_set(void *data, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	*(unsigned long *)data = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) static int debugfs_ulong_get(void *data, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	*val = *(unsigned long *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong, debugfs_ulong_get, debugfs_ulong_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 			"%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_ro, debugfs_ulong_get, NULL, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  * debugfs_create_ulong - create a debugfs file that is used to read and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577)  * an unsigned long value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586)  * This function creates a file in debugfs with the given name that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587)  * contains the value of the variable @value.  If the @mode variable is so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588)  * set, it can be read from, and written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590)  * This function will return a pointer to a dentry if it succeeds.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591)  * pointer must be passed to the debugfs_remove() function when the file is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592)  * to be removed (no automatic cleanup happens if your module is unloaded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593)  * you are responsible here.)  If an error occurs, ERR_PTR(-ERROR) will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)  * returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596)  * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597)  * be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) struct dentry *debugfs_create_ulong(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 				    struct dentry *parent, unsigned long *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	return debugfs_create_mode_unsafe(name, mode, parent, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 					&fops_ulong, &fops_ulong_ro,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 					&fops_ulong_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) EXPORT_SYMBOL_GPL(debugfs_create_ulong);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) DEFINE_DEBUGFS_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%02llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) DEFINE_DEBUGFS_ATTRIBUTE(fops_x8_ro, debugfs_u8_get, NULL, "0x%02llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) DEFINE_DEBUGFS_ATTRIBUTE(fops_x8_wo, NULL, debugfs_u8_set, "0x%02llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) DEFINE_DEBUGFS_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			"0x%04llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) DEFINE_DEBUGFS_ATTRIBUTE(fops_x16_ro, debugfs_u16_get, NULL, "0x%04llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) DEFINE_DEBUGFS_ATTRIBUTE(fops_x16_wo, NULL, debugfs_u16_set, "0x%04llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 			"0x%08llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) DEFINE_DEBUGFS_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%08llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) DEFINE_DEBUGFS_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%08llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) DEFINE_DEBUGFS_ATTRIBUTE(fops_x64, debugfs_u64_get, debugfs_u64_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 			"0x%016llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_ro, debugfs_u64_get, NULL, "0x%016llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_wo, NULL, debugfs_u64_set, "0x%016llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628)  * 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
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630)  * These functions are exactly the same as the above functions (but use a hex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  * output for the decimal challenged). For details look at the above unsigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  * decimal functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636)  * debugfs_create_x8 - create a debugfs file that is used to read and write an unsigned 8-bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		       u8 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 				   &fops_x8_ro, &fops_x8_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) EXPORT_SYMBOL_GPL(debugfs_create_x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654)  * debugfs_create_x16 - create a debugfs file that is used to read and write an unsigned 16-bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			u16 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 				   &fops_x16_ro, &fops_x16_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) EXPORT_SYMBOL_GPL(debugfs_create_x16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672)  * debugfs_create_x32 - create a debugfs file that is used to read and write an unsigned 32-bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 			u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 				   &fops_x32_ro, &fops_x32_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) EXPORT_SYMBOL_GPL(debugfs_create_x32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690)  * debugfs_create_x64 - create a debugfs file that is used to read and write an unsigned 64-bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			u64 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 				   &fops_x64_ro, &fops_x64_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) EXPORT_SYMBOL_GPL(debugfs_create_x64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) static int debugfs_size_t_set(void *data, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	*(size_t *)data = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) static int debugfs_size_t_get(void *data, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	*val = *(size_t *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) DEFINE_DEBUGFS_ATTRIBUTE(fops_size_t, debugfs_size_t_get, debugfs_size_t_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			"%llu\n"); /* %llu and %zu are more or less the same */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) DEFINE_DEBUGFS_ATTRIBUTE(fops_size_t_ro, debugfs_size_t_get, NULL, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) DEFINE_DEBUGFS_ATTRIBUTE(fops_size_t_wo, NULL, debugfs_size_t_set, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724)  * debugfs_create_size_t - create a debugfs file that is used to read and write an size_t value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) void debugfs_create_size_t(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			   struct dentry *parent, size_t *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_size_t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 				   &fops_size_t_ro, &fops_size_t_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) EXPORT_SYMBOL_GPL(debugfs_create_size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) static int debugfs_atomic_t_set(void *data, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	atomic_set((atomic_t *)data, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) static int debugfs_atomic_t_get(void *data, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	*val = atomic_read((atomic_t *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			debugfs_atomic_t_set, "%lld\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			"%lld\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			"%lld\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)  * debugfs_create_atomic_t - create a debugfs file that is used to read and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760)  * write an atomic_t value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) void debugfs_create_atomic_t(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			     struct dentry *parent, atomic_t *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_atomic_t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 				   &fops_atomic_t_ro, &fops_atomic_t_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) EXPORT_SYMBOL_GPL(debugfs_create_atomic_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) ssize_t debugfs_read_file_bool(struct file *file, char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			       size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	char buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	bool val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	struct dentry *dentry = F_DENTRY(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	r = debugfs_file_get(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	if (unlikely(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	val = *(bool *)file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	debugfs_file_put(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		buf[0] = 'Y';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		buf[0] = 'N';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	buf[1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	buf[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) EXPORT_SYMBOL_GPL(debugfs_read_file_bool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	bool bv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	bool *val = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	struct dentry *dentry = F_DENTRY(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	r = kstrtobool_from_user(user_buf, count, &bv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		r = debugfs_file_get(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		if (unlikely(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		*val = bv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		debugfs_file_put(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) EXPORT_SYMBOL_GPL(debugfs_write_file_bool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) static const struct file_operations fops_bool = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	.read =		debugfs_read_file_bool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	.write =	debugfs_write_file_bool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	.open =		simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	.llseek =	default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) static const struct file_operations fops_bool_ro = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	.read =		debugfs_read_file_bool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	.open =		simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	.llseek =	default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) static const struct file_operations fops_bool_wo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	.write =	debugfs_write_file_bool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	.open =		simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	.llseek =	default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)  * debugfs_create_bool - create a debugfs file that is used to read and write a boolean value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848)  * @value: a pointer to the variable that the file should read to and write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849)  *         from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851)  * This function creates a file in debugfs with the given name that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852)  * contains the value of the variable @value.  If the @mode variable is so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853)  * set, it can be read from, and written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855)  * This function will return a pointer to a dentry if it succeeds.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856)  * pointer must be passed to the debugfs_remove() function when the file is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857)  * to be removed (no automatic cleanup happens if your module is unloaded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858)  * you are responsible here.)  If an error occurs, ERR_PTR(-ERROR) will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859)  * returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861)  * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862)  * be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) struct dentry *debugfs_create_bool(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 				   struct dentry *parent, bool *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_bool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 				   &fops_bool_ro, &fops_bool_wo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) EXPORT_SYMBOL_GPL(debugfs_create_bool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) static ssize_t read_file_blob(struct file *file, char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			      size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	struct debugfs_blob_wrapper *blob = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	struct dentry *dentry = F_DENTRY(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	ssize_t r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	r = debugfs_file_get(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	if (unlikely(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	r = simple_read_from_buffer(user_buf, count, ppos, blob->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 				blob->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	debugfs_file_put(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) static const struct file_operations fops_blob = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	.read =		read_file_blob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	.open =		simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	.llseek =	default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895)  * debugfs_create_blob - create a debugfs file that is used to read a binary blob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901)  * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902)  *        to the blob data and the size of the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904)  * This function creates a file in debugfs with the given name that exports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905)  * @blob->data as a binary blob. If the @mode variable is so set it can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906)  * read from. Writing is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908)  * This function will return a pointer to a dentry if it succeeds.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909)  * pointer must be passed to the debugfs_remove() function when the file is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910)  * to be removed (no automatic cleanup happens if your module is unloaded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911)  * you are responsible here.)  If an error occurs, ERR_PTR(-ERROR) will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912)  * returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914)  * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915)  * be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) struct dentry *debugfs_create_blob(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 				   struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 				   struct debugfs_blob_wrapper *blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	return debugfs_create_file_unsafe(name, mode, parent, blob, &fops_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) EXPORT_SYMBOL_GPL(debugfs_create_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) static size_t u32_format_array(char *buf, size_t bufsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			       u32 *array, int array_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	size_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	while (--array_size >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		char term = array_size ? ' ' : '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		len = snprintf(buf, bufsize, "%u%c", *array++, term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		ret += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		buf += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		bufsize -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) static int u32_array_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	struct debugfs_u32_array *data = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	int size, elements = data->n_elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	 * Max size:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	 *  - 10 digits + ' '/'\n' = 11 bytes per number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	 *  - terminating NUL character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	size = elements*11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	buf = kmalloc(size+1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	buf[size] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	file->private_data = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	u32_format_array(buf, size, data->array, data->n_elements);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	return nonseekable_open(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			      loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	size_t size = strlen(file->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	return simple_read_from_buffer(buf, len, ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 					file->private_data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) static int u32_array_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	kfree(file->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) static const struct file_operations u32_array_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	.owner	 = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	.open	 = u32_array_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	.release = u32_array_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	.read	 = u32_array_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	.llseek  = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991)  * debugfs_create_u32_array - create a debugfs file that is used to read u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992)  * array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994)  * @mode: the permission that the file should have.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998)  * @array: wrapper struct containing data pointer and size of the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)  * This function creates a file in debugfs with the given name that exports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)  * @array as data. If the @mode variable is so set it can be read from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)  * Writing is not supported. Seek within the file is also not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)  * Once array is created its size can not be changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) void debugfs_create_u32_array(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 			      struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 			      struct debugfs_u32_array *array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	debugfs_create_file_unsafe(name, mode, parent, array, &u32_array_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) EXPORT_SYMBOL_GPL(debugfs_create_u32_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) #ifdef CONFIG_HAS_IOMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)  * The regset32 stuff is used to print 32-bit registers using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)  * seq_file utilities. We offer printing a register set in an already-opened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)  * sequential file or create a debugfs file that only prints a regset32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)  * debugfs_print_regs32 - use seq_print to describe a set of registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)  * @s: the seq_file structure being used to generate output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)  * @regs: an array if struct debugfs_reg32 structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)  * @nregs: the length of the above array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)  * @base: the base address to be used in reading the registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)  * @prefix: a string to be prefixed to every output line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)  * This function outputs a text block describing the current values of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)  * some 32-bit hardware registers. It is meant to be used within debugfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)  * files based on seq_file that need to show registers, intermixed with other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)  * information. The prefix argument may be used to specify a leading string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)  * because some peripherals have several blocks of identical registers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)  * for example configuration of dma channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			  int nregs, void __iomem *base, char *prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	for (i = 0; i < nregs; i++, regs++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		if (prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			seq_printf(s, "%s", prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		seq_printf(s, "%s = 0x%08x\n", regs->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			   readl(base + regs->offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		if (seq_has_overflowed(s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) EXPORT_SYMBOL_GPL(debugfs_print_regs32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static int debugfs_show_regset32(struct seq_file *s, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	struct debugfs_regset32 *regset = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	if (regset->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		pm_runtime_get_sync(regset->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	debugfs_print_regs32(s, regset->regs, regset->nregs, regset->base, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	if (regset->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		pm_runtime_put(regset->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static int debugfs_open_regset32(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	return single_open(file, debugfs_show_regset32, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static const struct file_operations fops_regset32 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	.open =		debugfs_open_regset32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	.read =		seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	.llseek =	seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	.release =	single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)  * debugfs_create_regset32 - create a debugfs file that returns register values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)  * @name: a pointer to a string containing the name of the file to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)  * @mode: the permission that the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)  *          directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)  *          file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)  * @regset: a pointer to a struct debugfs_regset32, which contains a pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)  *          to an array of register definitions, the array size and the base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)  *          address where the register bank is to be found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)  * This function creates a file in debugfs with the given name that reports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)  * the names and values of a set of 32-bit registers. If the @mode variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)  * is so set it can be read from. Writing is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) void debugfs_create_regset32(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 			     struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 			     struct debugfs_regset32 *regset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	debugfs_create_file(name, mode, parent, regset, &fops_regset32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) EXPORT_SYMBOL_GPL(debugfs_create_regset32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) #endif /* CONFIG_HAS_IOMEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct debugfs_devm_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	int (*read)(struct seq_file *seq, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static int debugfs_devm_entry_open(struct inode *inode, struct file *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	struct debugfs_devm_entry *entry = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	return single_open(f, entry->read, entry->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static const struct file_operations debugfs_devm_entry_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	.open = debugfs_devm_entry_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	.release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	.read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	.llseek = seq_lseek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)  * debugfs_create_devm_seqfile - create a debugfs file that is bound to device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)  * @dev: device related to this debugfs file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)  * @name: name of the debugfs file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)  * @parent: a pointer to the parent dentry for this file.  This should be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)  *	directory dentry if set.  If this parameter is %NULL, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)  *	file will be created in the root of the debugfs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)  * @read_fn: function pointer called to print the seq_file content.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) void debugfs_create_devm_seqfile(struct device *dev, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 				 struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 				 int (*read_fn)(struct seq_file *s, void *data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	struct debugfs_devm_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	if (IS_ERR(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	entry->read = read_fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	entry->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	debugfs_create_file(name, S_IRUGO, parent, entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 			    &debugfs_devm_entry_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) EXPORT_SYMBOL_GPL(debugfs_create_devm_seqfile);