LCOV - code coverage report
Current view: top level - fs/debugfs - file.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 80 368 21.7 %
Date: 2021-04-22 12:43:58 Functions: 11 92 12.0 %

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

Generated by: LCOV version 1.14