Add get/set callbacks for debugfs
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 6 Dec 2016 15:04:58 +0000 (18:04 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Fri, 9 Dec 2016 12:26:32 +0000 (15:26 +0300)
Change-Id: I9446ebe3aefa9e21655c96a7d163348e605d8c74
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
master/swap_debugfs.c
master/swap_debugfs.h

index d3042b4..d4f31ee 100644 (file)
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include "swap_initializer.h"
+#include "swap_debugfs.h"
+
+
+/* based on define DEFINE_SIMPLE_ATTRIBUTE */
+#define SWAP_DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)      \
+static int __fops ## _open(struct inode *inode, struct file *file)     \
+{                                                                      \
+       int ret;                                                        \
+                                                                       \
+       ret = swap_init_simple_open(inode, file);                       \
+       if (ret)                                                        \
+               return ret;                                             \
+                                                                       \
+       __simple_attr_check_format(__fmt, 0ull);                        \
+       ret = simple_attr_open(inode, file, __get, __set, __fmt);       \
+       if (ret)                                                        \
+               swap_init_simple_release(inode, file);                  \
+                                                                       \
+       return ret;                                                     \
+}                                                                      \
+static int __fops ## _release(struct inode *inode, struct file *file)  \
+{                                                                      \
+       simple_attr_release(inode, file);                               \
+       swap_init_simple_release(inode, file);                          \
+                                                                       \
+       return 0;                                                       \
+}                                                                      \
+static const struct file_operations __fops = {                         \
+       .owner   = THIS_MODULE,                                         \
+       .open    = __fops ## _open,                                     \
+       .release = __fops ## _release,                                  \
+       .read    = simple_attr_read,                                    \
+       .write   = simple_attr_write,                                   \
+       .llseek  = generic_file_llseek,                                 \
+}
+
+
+static int fset_u64(void *data, u64 val)
+{
+       struct dfs_setget_64 *setget = data;
+
+       return setget->set(val);
+}
+
+static int fget_u64(void *data, u64 *val)
+{
+       struct dfs_setget_64 *setget = data;
+
+       *val = setget->get();
+       return 0;
+}
+
+SWAP_DEFINE_SIMPLE_ATTRIBUTE(fops_setget_u64, fget_u64, fset_u64, "%llu\n");
+SWAP_DEFINE_SIMPLE_ATTRIBUTE(fops_setget_u64_ro, fget_u64, NULL, "%llu\n");
+SWAP_DEFINE_SIMPLE_ATTRIBUTE(fops_setget_u64_wo, NULL, fset_u64, "%llu\n");
+
+SWAP_DEFINE_SIMPLE_ATTRIBUTE(fops_setget_x64, fget_u64, fset_u64, "0x%08llx\n");
+SWAP_DEFINE_SIMPLE_ATTRIBUTE(fops_setget_x64_ro, fget_u64, NULL, "0x%08llx\n");
+SWAP_DEFINE_SIMPLE_ATTRIBUTE(fops_setget_x64_wo, NULL, fset_u64, "0x%08llx\n");
+
+static struct dentry *do_create_dfs_file(const char *name, umode_t mode,
+                                        struct dentry *parent, void *data,
+                                        const struct file_operations *fops,
+                                        const struct file_operations *fops_ro,
+                                        const struct file_operations *fops_wo)
+{
+       /* if there are no write bits set, make read only */
+       if (!(mode & S_IWUGO))
+               return debugfs_create_file(name, mode, parent, data, fops_ro);
+       /* if there are no read bits set, make write only */
+       if (!(mode & S_IRUGO))
+               return debugfs_create_file(name, mode, parent, data, fops_wo);
+
+       return debugfs_create_file(name, mode, parent, data, fops);
+}
+
+struct dentry *debugfs_create_setget_u64(const char *name, umode_t mode,
+                                        struct dentry *parent,
+                                        struct dfs_setget_64 *setget)
+{
+       return do_create_dfs_file(name, mode, parent, setget,
+                                 &fops_setget_u64,
+                                 &fops_setget_u64_ro,
+                                 &fops_setget_u64_wo);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_setget_u64);
+
+struct dentry *debugfs_create_setget_x64(const char *name, umode_t mode,
+                                        struct dentry *parent,
+                                        struct dfs_setget_64 *setget)
+{
+       return do_create_dfs_file(name, mode, parent, setget,
+                                 &fops_setget_x64,
+                                 &fops_setget_x64_ro,
+                                 &fops_setget_x64_wo);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_setget_x64);
 
 
 static int set_enable(int enable)
index 0df8c3a..498ee07 100644 (file)
 #define _SWAP_DEBUGFS_H
 
 
+#include <linux/types.h>
+
+
+struct dfs_setget_64 {
+       int (*set)(u64 val);
+       u64 (*get)(void);
+};
+
 struct dentry;
 
+struct dentry *debugfs_create_setget_u64(const char *name, umode_t mode,
+                                        struct dentry *parent,
+                                        struct dfs_setget_64 *setget);
+
+struct dentry *debugfs_create_setget_x64(const char *name, umode_t mode,
+                                        struct dentry *parent,
+                                        struct dfs_setget_64 *setget);
+
 struct dentry *swap_debugfs_getdir(void);
 
 int swap_debugfs_init(void);