Commit 5166b7c006eeb4f6becc0822974d8da259484ba1

Authored by Mark Brown
1 parent afab2f7b21

regmap: debugfs: Cache offsets of valid regions for dump

Avoid doing a linear scan of the entire register map for each read() of
the debugfs register dump by recording the offsets where valid registers
exist when we first read the registers file. This assumes the set of
valid registers never changes, if this is not the case invalidation of
the cache will be required.

This could be further improved for large blocks of contiguous registers
by calculating the register we will read from within the block - currently
we do a linear scan of the block. An rbtree may also be worthwhile.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

Showing 2 changed files with 63 additions and 14 deletions Inline Diff

drivers/base/regmap/internal.h
1 /* 1 /*
2 * Register map access API internal header 2 * Register map access API internal header
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics plc 4 * Copyright 2011 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13 #ifndef _REGMAP_INTERNAL_H 13 #ifndef _REGMAP_INTERNAL_H
14 #define _REGMAP_INTERNAL_H 14 #define _REGMAP_INTERNAL_H
15 15
16 #include <linux/regmap.h> 16 #include <linux/regmap.h>
17 #include <linux/fs.h> 17 #include <linux/fs.h>
18 #include <linux/list.h>
18 19
19 struct regmap; 20 struct regmap;
20 struct regcache_ops; 21 struct regcache_ops;
21 22
23 struct regmap_debugfs_off_cache {
24 struct list_head list;
25 off_t min;
26 off_t max;
27 unsigned int base_reg;
28 };
29
22 struct regmap_format { 30 struct regmap_format {
23 size_t buf_size; 31 size_t buf_size;
24 size_t reg_bytes; 32 size_t reg_bytes;
25 size_t pad_bytes; 33 size_t pad_bytes;
26 size_t val_bytes; 34 size_t val_bytes;
27 void (*format_write)(struct regmap *map, 35 void (*format_write)(struct regmap *map,
28 unsigned int reg, unsigned int val); 36 unsigned int reg, unsigned int val);
29 void (*format_reg)(void *buf, unsigned int reg, unsigned int shift); 37 void (*format_reg)(void *buf, unsigned int reg, unsigned int shift);
30 void (*format_val)(void *buf, unsigned int val, unsigned int shift); 38 void (*format_val)(void *buf, unsigned int val, unsigned int shift);
31 unsigned int (*parse_val)(void *buf); 39 unsigned int (*parse_val)(void *buf);
32 }; 40 };
33 41
34 typedef void (*regmap_lock)(struct regmap *map); 42 typedef void (*regmap_lock)(struct regmap *map);
35 typedef void (*regmap_unlock)(struct regmap *map); 43 typedef void (*regmap_unlock)(struct regmap *map);
36 44
37 struct regmap { 45 struct regmap {
38 struct mutex mutex; 46 struct mutex mutex;
39 spinlock_t spinlock; 47 spinlock_t spinlock;
40 regmap_lock lock; 48 regmap_lock lock;
41 regmap_unlock unlock; 49 regmap_unlock unlock;
42 50
43 struct device *dev; /* Device we do I/O on */ 51 struct device *dev; /* Device we do I/O on */
44 void *work_buf; /* Scratch buffer used to format I/O */ 52 void *work_buf; /* Scratch buffer used to format I/O */
45 struct regmap_format format; /* Buffer format */ 53 struct regmap_format format; /* Buffer format */
46 const struct regmap_bus *bus; 54 const struct regmap_bus *bus;
47 void *bus_context; 55 void *bus_context;
48 const char *name; 56 const char *name;
49 57
50 #ifdef CONFIG_DEBUG_FS 58 #ifdef CONFIG_DEBUG_FS
51 struct dentry *debugfs; 59 struct dentry *debugfs;
52 const char *debugfs_name; 60 const char *debugfs_name;
53 61
54 unsigned int debugfs_reg_len; 62 unsigned int debugfs_reg_len;
55 unsigned int debugfs_val_len; 63 unsigned int debugfs_val_len;
56 unsigned int debugfs_tot_len; 64 unsigned int debugfs_tot_len;
65
66 struct list_head debugfs_off_cache;
57 #endif 67 #endif
58 68
59 unsigned int max_register; 69 unsigned int max_register;
60 bool (*writeable_reg)(struct device *dev, unsigned int reg); 70 bool (*writeable_reg)(struct device *dev, unsigned int reg);
61 bool (*readable_reg)(struct device *dev, unsigned int reg); 71 bool (*readable_reg)(struct device *dev, unsigned int reg);
62 bool (*volatile_reg)(struct device *dev, unsigned int reg); 72 bool (*volatile_reg)(struct device *dev, unsigned int reg);
63 bool (*precious_reg)(struct device *dev, unsigned int reg); 73 bool (*precious_reg)(struct device *dev, unsigned int reg);
64 74
65 u8 read_flag_mask; 75 u8 read_flag_mask;
66 u8 write_flag_mask; 76 u8 write_flag_mask;
67 77
68 /* number of bits to (left) shift the reg value when formatting*/ 78 /* number of bits to (left) shift the reg value when formatting*/
69 int reg_shift; 79 int reg_shift;
70 int reg_stride; 80 int reg_stride;
71 81
72 /* regcache specific members */ 82 /* regcache specific members */
73 const struct regcache_ops *cache_ops; 83 const struct regcache_ops *cache_ops;
74 enum regcache_type cache_type; 84 enum regcache_type cache_type;
75 85
76 /* number of bytes in reg_defaults_raw */ 86 /* number of bytes in reg_defaults_raw */
77 unsigned int cache_size_raw; 87 unsigned int cache_size_raw;
78 /* number of bytes per word in reg_defaults_raw */ 88 /* number of bytes per word in reg_defaults_raw */
79 unsigned int cache_word_size; 89 unsigned int cache_word_size;
80 /* number of entries in reg_defaults */ 90 /* number of entries in reg_defaults */
81 unsigned int num_reg_defaults; 91 unsigned int num_reg_defaults;
82 /* number of entries in reg_defaults_raw */ 92 /* number of entries in reg_defaults_raw */
83 unsigned int num_reg_defaults_raw; 93 unsigned int num_reg_defaults_raw;
84 94
85 /* if set, only the cache is modified not the HW */ 95 /* if set, only the cache is modified not the HW */
86 u32 cache_only; 96 u32 cache_only;
87 /* if set, only the HW is modified not the cache */ 97 /* if set, only the HW is modified not the cache */
88 u32 cache_bypass; 98 u32 cache_bypass;
89 /* if set, remember to free reg_defaults_raw */ 99 /* if set, remember to free reg_defaults_raw */
90 bool cache_free; 100 bool cache_free;
91 101
92 struct reg_default *reg_defaults; 102 struct reg_default *reg_defaults;
93 const void *reg_defaults_raw; 103 const void *reg_defaults_raw;
94 void *cache; 104 void *cache;
95 u32 cache_dirty; 105 u32 cache_dirty;
96 106
97 struct reg_default *patch; 107 struct reg_default *patch;
98 int patch_regs; 108 int patch_regs;
99 109
100 /* if set, converts bulk rw to single rw */ 110 /* if set, converts bulk rw to single rw */
101 bool use_single_rw; 111 bool use_single_rw;
102 112
103 struct rb_root range_tree; 113 struct rb_root range_tree;
104 void *selector_work_buf; /* Scratch buffer used for selector */ 114 void *selector_work_buf; /* Scratch buffer used for selector */
105 }; 115 };
106 116
107 struct regcache_ops { 117 struct regcache_ops {
108 const char *name; 118 const char *name;
109 enum regcache_type type; 119 enum regcache_type type;
110 int (*init)(struct regmap *map); 120 int (*init)(struct regmap *map);
111 int (*exit)(struct regmap *map); 121 int (*exit)(struct regmap *map);
112 int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); 122 int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
113 int (*write)(struct regmap *map, unsigned int reg, unsigned int value); 123 int (*write)(struct regmap *map, unsigned int reg, unsigned int value);
114 int (*sync)(struct regmap *map, unsigned int min, unsigned int max); 124 int (*sync)(struct regmap *map, unsigned int min, unsigned int max);
115 }; 125 };
116 126
117 bool regmap_writeable(struct regmap *map, unsigned int reg); 127 bool regmap_writeable(struct regmap *map, unsigned int reg);
118 bool regmap_readable(struct regmap *map, unsigned int reg); 128 bool regmap_readable(struct regmap *map, unsigned int reg);
119 bool regmap_volatile(struct regmap *map, unsigned int reg); 129 bool regmap_volatile(struct regmap *map, unsigned int reg);
120 bool regmap_precious(struct regmap *map, unsigned int reg); 130 bool regmap_precious(struct regmap *map, unsigned int reg);
121 131
122 int _regmap_write(struct regmap *map, unsigned int reg, 132 int _regmap_write(struct regmap *map, unsigned int reg,
123 unsigned int val); 133 unsigned int val);
124 134
125 struct regmap_range_node { 135 struct regmap_range_node {
126 struct rb_node node; 136 struct rb_node node;
127 const char *name; 137 const char *name;
128 struct regmap *map; 138 struct regmap *map;
129 139
130 unsigned int range_min; 140 unsigned int range_min;
131 unsigned int range_max; 141 unsigned int range_max;
132 142
133 unsigned int selector_reg; 143 unsigned int selector_reg;
134 unsigned int selector_mask; 144 unsigned int selector_mask;
135 int selector_shift; 145 int selector_shift;
136 146
137 unsigned int window_start; 147 unsigned int window_start;
138 unsigned int window_len; 148 unsigned int window_len;
139 }; 149 };
140 150
141 #ifdef CONFIG_DEBUG_FS 151 #ifdef CONFIG_DEBUG_FS
142 extern void regmap_debugfs_initcall(void); 152 extern void regmap_debugfs_initcall(void);
143 extern void regmap_debugfs_init(struct regmap *map, const char *name); 153 extern void regmap_debugfs_init(struct regmap *map, const char *name);
144 extern void regmap_debugfs_exit(struct regmap *map); 154 extern void regmap_debugfs_exit(struct regmap *map);
145 #else 155 #else
146 static inline void regmap_debugfs_initcall(void) { } 156 static inline void regmap_debugfs_initcall(void) { }
147 static inline void regmap_debugfs_init(struct regmap *map, const char *name) { } 157 static inline void regmap_debugfs_init(struct regmap *map, const char *name) { }
148 static inline void regmap_debugfs_exit(struct regmap *map) { } 158 static inline void regmap_debugfs_exit(struct regmap *map) { }
149 #endif 159 #endif
150 160
151 /* regcache core declarations */ 161 /* regcache core declarations */
152 int regcache_init(struct regmap *map, const struct regmap_config *config); 162 int regcache_init(struct regmap *map, const struct regmap_config *config);
153 void regcache_exit(struct regmap *map); 163 void regcache_exit(struct regmap *map);
154 int regcache_read(struct regmap *map, 164 int regcache_read(struct regmap *map,
155 unsigned int reg, unsigned int *value); 165 unsigned int reg, unsigned int *value);
156 int regcache_write(struct regmap *map, 166 int regcache_write(struct regmap *map,
157 unsigned int reg, unsigned int value); 167 unsigned int reg, unsigned int value);
158 int regcache_sync(struct regmap *map); 168 int regcache_sync(struct regmap *map);
159 169
160 unsigned int regcache_get_val(const void *base, unsigned int idx, 170 unsigned int regcache_get_val(const void *base, unsigned int idx,
161 unsigned int word_size); 171 unsigned int word_size);
162 bool regcache_set_val(void *base, unsigned int idx, 172 bool regcache_set_val(void *base, unsigned int idx,
163 unsigned int val, unsigned int word_size); 173 unsigned int val, unsigned int word_size);
164 int regcache_lookup_reg(struct regmap *map, unsigned int reg); 174 int regcache_lookup_reg(struct regmap *map, unsigned int reg);
165 175
166 extern struct regcache_ops regcache_rbtree_ops; 176 extern struct regcache_ops regcache_rbtree_ops;
167 extern struct regcache_ops regcache_lzo_ops; 177 extern struct regcache_ops regcache_lzo_ops;
168 178
169 #endif 179 #endif
170 180
drivers/base/regmap/regmap-debugfs.c
1 /* 1 /*
2 * Register map access API - debugfs 2 * Register map access API - debugfs
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics plc 4 * Copyright 2011 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13 #include <linux/slab.h> 13 #include <linux/slab.h>
14 #include <linux/mutex.h> 14 #include <linux/mutex.h>
15 #include <linux/debugfs.h> 15 #include <linux/debugfs.h>
16 #include <linux/uaccess.h> 16 #include <linux/uaccess.h>
17 #include <linux/device.h> 17 #include <linux/device.h>
18 18
19 #include "internal.h" 19 #include "internal.h"
20 20
21 static struct dentry *regmap_debugfs_root; 21 static struct dentry *regmap_debugfs_root;
22 22
23 /* Calculate the length of a fixed format */ 23 /* Calculate the length of a fixed format */
24 static size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size) 24 static size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size)
25 { 25 {
26 snprintf(buf, buf_size, "%x", max_val); 26 snprintf(buf, buf_size, "%x", max_val);
27 return strlen(buf); 27 return strlen(buf);
28 } 28 }
29 29
30 static ssize_t regmap_name_read_file(struct file *file, 30 static ssize_t regmap_name_read_file(struct file *file,
31 char __user *user_buf, size_t count, 31 char __user *user_buf, size_t count,
32 loff_t *ppos) 32 loff_t *ppos)
33 { 33 {
34 struct regmap *map = file->private_data; 34 struct regmap *map = file->private_data;
35 int ret; 35 int ret;
36 char *buf; 36 char *buf;
37 37
38 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 38 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
39 if (!buf) 39 if (!buf)
40 return -ENOMEM; 40 return -ENOMEM;
41 41
42 ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name); 42 ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name);
43 if (ret < 0) { 43 if (ret < 0) {
44 kfree(buf); 44 kfree(buf);
45 return ret; 45 return ret;
46 } 46 }
47 47
48 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 48 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
49 kfree(buf); 49 kfree(buf);
50 return ret; 50 return ret;
51 } 51 }
52 52
53 static const struct file_operations regmap_name_fops = { 53 static const struct file_operations regmap_name_fops = {
54 .open = simple_open, 54 .open = simple_open,
55 .read = regmap_name_read_file, 55 .read = regmap_name_read_file,
56 .llseek = default_llseek, 56 .llseek = default_llseek,
57 }; 57 };
58 58
59 /* 59 /*
60 * Work out where the start offset maps into register numbers, bearing 60 * Work out where the start offset maps into register numbers, bearing
61 * in mind that we suppress hidden registers. 61 * in mind that we suppress hidden registers.
62 */ 62 */
63 static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, 63 static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
64 unsigned int base, 64 unsigned int base,
65 loff_t from, 65 loff_t from,
66 loff_t *pos) 66 loff_t *pos)
67 { 67 {
68 loff_t p = *pos; 68 struct regmap_debugfs_off_cache *c = NULL;
69 unsigned int i; 69 loff_t p = 0;
70 unsigned int i, ret;
70 71
71 for (i = base; i <= map->max_register; i += map->reg_stride) { 72 /*
72 if (!regmap_readable(map, i)) 73 * If we don't have a cache build one so we don't have to do a
73 continue; 74 * linear scan each time.
75 */
76 if (list_empty(&map->debugfs_off_cache)) {
77 for (i = base; i <= map->max_register; i += map->reg_stride) {
78 /* Skip unprinted registers, closing off cache entry */
79 if (!regmap_readable(map, i) ||
80 regmap_precious(map, i)) {
81 if (c) {
82 c->max = p - 1;
83 list_add_tail(&c->list,
84 &map->debugfs_off_cache);
85 c = NULL;
86 }
74 87
75 if (regmap_precious(map, i)) 88 continue;
76 continue; 89 }
77 90
78 if (i >= from) { 91 /* No cache entry? Start a new one */
79 *pos = p; 92 if (!c) {
80 return i; 93 c = kzalloc(sizeof(*c), GFP_KERNEL);
94 if (!c)
95 break;
96 c->min = p;
97 c->base_reg = i;
98 }
99
100 p += map->debugfs_tot_len;
81 } 101 }
102 }
82 103
83 p += map->debugfs_tot_len; 104 /* Find the relevant block */
105 list_for_each_entry(c, &map->debugfs_off_cache, list) {
106 if (*pos >= c->min && *pos <= c->max) {
107 *pos = c->min;
108 return c->base_reg;
109 }
110
111 ret = c->max;
84 } 112 }
85 113
86 return base; 114 return ret;
87 } 115 }
88 116
89 static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from, 117 static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
90 unsigned int to, char __user *user_buf, 118 unsigned int to, char __user *user_buf,
91 size_t count, loff_t *ppos) 119 size_t count, loff_t *ppos)
92 { 120 {
93 size_t buf_pos = 0; 121 size_t buf_pos = 0;
94 loff_t p = *ppos; 122 loff_t p = *ppos;
95 ssize_t ret; 123 ssize_t ret;
96 int i; 124 int i;
97 char *buf; 125 char *buf;
98 unsigned int val, start_reg; 126 unsigned int val, start_reg;
99 127
100 if (*ppos < 0 || !count) 128 if (*ppos < 0 || !count)
101 return -EINVAL; 129 return -EINVAL;
102 130
103 buf = kmalloc(count, GFP_KERNEL); 131 buf = kmalloc(count, GFP_KERNEL);
104 if (!buf) 132 if (!buf)
105 return -ENOMEM; 133 return -ENOMEM;
106 134
107 /* Calculate the length of a fixed format */ 135 /* Calculate the length of a fixed format */
108 if (!map->debugfs_tot_len) { 136 if (!map->debugfs_tot_len) {
109 map->debugfs_reg_len = regmap_calc_reg_len(map->max_register, 137 map->debugfs_reg_len = regmap_calc_reg_len(map->max_register,
110 buf, count); 138 buf, count);
111 map->debugfs_val_len = 2 * map->format.val_bytes; 139 map->debugfs_val_len = 2 * map->format.val_bytes;
112 map->debugfs_tot_len = map->debugfs_reg_len + 140 map->debugfs_tot_len = map->debugfs_reg_len +
113 map->debugfs_val_len + 3; /* : \n */ 141 map->debugfs_val_len + 3; /* : \n */
114 } 142 }
115 143
116 /* Work out which register we're starting at */ 144 /* Work out which register we're starting at */
117 start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p); 145 start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p);
118 146
119 for (i = start_reg; i <= to; i += map->reg_stride) { 147 for (i = start_reg; i <= to; i += map->reg_stride) {
120 if (!regmap_readable(map, i)) 148 if (!regmap_readable(map, i))
121 continue; 149 continue;
122 150
123 if (regmap_precious(map, i)) 151 if (regmap_precious(map, i))
124 continue; 152 continue;
125 153
126 /* If we're in the region the user is trying to read */ 154 /* If we're in the region the user is trying to read */
127 if (p >= *ppos) { 155 if (p >= *ppos) {
128 /* ...but not beyond it */ 156 /* ...but not beyond it */
129 if (buf_pos + 1 + map->debugfs_tot_len >= count) 157 if (buf_pos + 1 + map->debugfs_tot_len >= count)
130 break; 158 break;
131 159
132 /* Format the register */ 160 /* Format the register */
133 snprintf(buf + buf_pos, count - buf_pos, "%.*x: ", 161 snprintf(buf + buf_pos, count - buf_pos, "%.*x: ",
134 map->debugfs_reg_len, i - from); 162 map->debugfs_reg_len, i - from);
135 buf_pos += map->debugfs_reg_len + 2; 163 buf_pos += map->debugfs_reg_len + 2;
136 164
137 /* Format the value, write all X if we can't read */ 165 /* Format the value, write all X if we can't read */
138 ret = regmap_read(map, i, &val); 166 ret = regmap_read(map, i, &val);
139 if (ret == 0) 167 if (ret == 0)
140 snprintf(buf + buf_pos, count - buf_pos, 168 snprintf(buf + buf_pos, count - buf_pos,
141 "%.*x", map->debugfs_val_len, val); 169 "%.*x", map->debugfs_val_len, val);
142 else 170 else
143 memset(buf + buf_pos, 'X', 171 memset(buf + buf_pos, 'X',
144 map->debugfs_val_len); 172 map->debugfs_val_len);
145 buf_pos += 2 * map->format.val_bytes; 173 buf_pos += 2 * map->format.val_bytes;
146 174
147 buf[buf_pos++] = '\n'; 175 buf[buf_pos++] = '\n';
148 } 176 }
149 p += map->debugfs_tot_len; 177 p += map->debugfs_tot_len;
150 } 178 }
151 179
152 ret = buf_pos; 180 ret = buf_pos;
153 181
154 if (copy_to_user(user_buf, buf, buf_pos)) { 182 if (copy_to_user(user_buf, buf, buf_pos)) {
155 ret = -EFAULT; 183 ret = -EFAULT;
156 goto out; 184 goto out;
157 } 185 }
158 186
159 *ppos += buf_pos; 187 *ppos += buf_pos;
160 188
161 out: 189 out:
162 kfree(buf); 190 kfree(buf);
163 return ret; 191 return ret;
164 } 192 }
165 193
166 static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, 194 static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
167 size_t count, loff_t *ppos) 195 size_t count, loff_t *ppos)
168 { 196 {
169 struct regmap *map = file->private_data; 197 struct regmap *map = file->private_data;
170 198
171 return regmap_read_debugfs(map, 0, map->max_register, user_buf, 199 return regmap_read_debugfs(map, 0, map->max_register, user_buf,
172 count, ppos); 200 count, ppos);
173 } 201 }
174 202
175 #undef REGMAP_ALLOW_WRITE_DEBUGFS 203 #undef REGMAP_ALLOW_WRITE_DEBUGFS
176 #ifdef REGMAP_ALLOW_WRITE_DEBUGFS 204 #ifdef REGMAP_ALLOW_WRITE_DEBUGFS
177 /* 205 /*
178 * This can be dangerous especially when we have clients such as 206 * This can be dangerous especially when we have clients such as
179 * PMICs, therefore don't provide any real compile time configuration option 207 * PMICs, therefore don't provide any real compile time configuration option
180 * for this feature, people who want to use this will need to modify 208 * for this feature, people who want to use this will need to modify
181 * the source code directly. 209 * the source code directly.
182 */ 210 */
183 static ssize_t regmap_map_write_file(struct file *file, 211 static ssize_t regmap_map_write_file(struct file *file,
184 const char __user *user_buf, 212 const char __user *user_buf,
185 size_t count, loff_t *ppos) 213 size_t count, loff_t *ppos)
186 { 214 {
187 char buf[32]; 215 char buf[32];
188 size_t buf_size; 216 size_t buf_size;
189 char *start = buf; 217 char *start = buf;
190 unsigned long reg, value; 218 unsigned long reg, value;
191 struct regmap *map = file->private_data; 219 struct regmap *map = file->private_data;
192 220
193 buf_size = min(count, (sizeof(buf)-1)); 221 buf_size = min(count, (sizeof(buf)-1));
194 if (copy_from_user(buf, user_buf, buf_size)) 222 if (copy_from_user(buf, user_buf, buf_size))
195 return -EFAULT; 223 return -EFAULT;
196 buf[buf_size] = 0; 224 buf[buf_size] = 0;
197 225
198 while (*start == ' ') 226 while (*start == ' ')
199 start++; 227 start++;
200 reg = simple_strtoul(start, &start, 16); 228 reg = simple_strtoul(start, &start, 16);
201 while (*start == ' ') 229 while (*start == ' ')
202 start++; 230 start++;
203 if (strict_strtoul(start, 16, &value)) 231 if (strict_strtoul(start, 16, &value))
204 return -EINVAL; 232 return -EINVAL;
205 233
206 /* Userspace has been fiddling around behind the kernel's back */ 234 /* Userspace has been fiddling around behind the kernel's back */
207 add_taint(TAINT_USER); 235 add_taint(TAINT_USER);
208 236
209 regmap_write(map, reg, value); 237 regmap_write(map, reg, value);
210 return buf_size; 238 return buf_size;
211 } 239 }
212 #else 240 #else
213 #define regmap_map_write_file NULL 241 #define regmap_map_write_file NULL
214 #endif 242 #endif
215 243
216 static const struct file_operations regmap_map_fops = { 244 static const struct file_operations regmap_map_fops = {
217 .open = simple_open, 245 .open = simple_open,
218 .read = regmap_map_read_file, 246 .read = regmap_map_read_file,
219 .write = regmap_map_write_file, 247 .write = regmap_map_write_file,
220 .llseek = default_llseek, 248 .llseek = default_llseek,
221 }; 249 };
222 250
223 static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf, 251 static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf,
224 size_t count, loff_t *ppos) 252 size_t count, loff_t *ppos)
225 { 253 {
226 struct regmap_range_node *range = file->private_data; 254 struct regmap_range_node *range = file->private_data;
227 struct regmap *map = range->map; 255 struct regmap *map = range->map;
228 256
229 return regmap_read_debugfs(map, range->range_min, range->range_max, 257 return regmap_read_debugfs(map, range->range_min, range->range_max,
230 user_buf, count, ppos); 258 user_buf, count, ppos);
231 } 259 }
232 260
233 static const struct file_operations regmap_range_fops = { 261 static const struct file_operations regmap_range_fops = {
234 .open = simple_open, 262 .open = simple_open,
235 .read = regmap_range_read_file, 263 .read = regmap_range_read_file,
236 .llseek = default_llseek, 264 .llseek = default_llseek,
237 }; 265 };
238 266
239 static ssize_t regmap_access_read_file(struct file *file, 267 static ssize_t regmap_access_read_file(struct file *file,
240 char __user *user_buf, size_t count, 268 char __user *user_buf, size_t count,
241 loff_t *ppos) 269 loff_t *ppos)
242 { 270 {
243 int reg_len, tot_len; 271 int reg_len, tot_len;
244 size_t buf_pos = 0; 272 size_t buf_pos = 0;
245 loff_t p = 0; 273 loff_t p = 0;
246 ssize_t ret; 274 ssize_t ret;
247 int i; 275 int i;
248 struct regmap *map = file->private_data; 276 struct regmap *map = file->private_data;
249 char *buf; 277 char *buf;
250 278
251 if (*ppos < 0 || !count) 279 if (*ppos < 0 || !count)
252 return -EINVAL; 280 return -EINVAL;
253 281
254 buf = kmalloc(count, GFP_KERNEL); 282 buf = kmalloc(count, GFP_KERNEL);
255 if (!buf) 283 if (!buf)
256 return -ENOMEM; 284 return -ENOMEM;
257 285
258 /* Calculate the length of a fixed format */ 286 /* Calculate the length of a fixed format */
259 reg_len = regmap_calc_reg_len(map->max_register, buf, count); 287 reg_len = regmap_calc_reg_len(map->max_register, buf, count);
260 tot_len = reg_len + 10; /* ': R W V P\n' */ 288 tot_len = reg_len + 10; /* ': R W V P\n' */
261 289
262 for (i = 0; i <= map->max_register; i += map->reg_stride) { 290 for (i = 0; i <= map->max_register; i += map->reg_stride) {
263 /* Ignore registers which are neither readable nor writable */ 291 /* Ignore registers which are neither readable nor writable */
264 if (!regmap_readable(map, i) && !regmap_writeable(map, i)) 292 if (!regmap_readable(map, i) && !regmap_writeable(map, i))
265 continue; 293 continue;
266 294
267 /* If we're in the region the user is trying to read */ 295 /* If we're in the region the user is trying to read */
268 if (p >= *ppos) { 296 if (p >= *ppos) {
269 /* ...but not beyond it */ 297 /* ...but not beyond it */
270 if (buf_pos >= count - 1 - tot_len) 298 if (buf_pos >= count - 1 - tot_len)
271 break; 299 break;
272 300
273 /* Format the register */ 301 /* Format the register */
274 snprintf(buf + buf_pos, count - buf_pos, 302 snprintf(buf + buf_pos, count - buf_pos,
275 "%.*x: %c %c %c %c\n", 303 "%.*x: %c %c %c %c\n",
276 reg_len, i, 304 reg_len, i,
277 regmap_readable(map, i) ? 'y' : 'n', 305 regmap_readable(map, i) ? 'y' : 'n',
278 regmap_writeable(map, i) ? 'y' : 'n', 306 regmap_writeable(map, i) ? 'y' : 'n',
279 regmap_volatile(map, i) ? 'y' : 'n', 307 regmap_volatile(map, i) ? 'y' : 'n',
280 regmap_precious(map, i) ? 'y' : 'n'); 308 regmap_precious(map, i) ? 'y' : 'n');
281 309
282 buf_pos += tot_len; 310 buf_pos += tot_len;
283 } 311 }
284 p += tot_len; 312 p += tot_len;
285 } 313 }
286 314
287 ret = buf_pos; 315 ret = buf_pos;
288 316
289 if (copy_to_user(user_buf, buf, buf_pos)) { 317 if (copy_to_user(user_buf, buf, buf_pos)) {
290 ret = -EFAULT; 318 ret = -EFAULT;
291 goto out; 319 goto out;
292 } 320 }
293 321
294 *ppos += buf_pos; 322 *ppos += buf_pos;
295 323
296 out: 324 out:
297 kfree(buf); 325 kfree(buf);
298 return ret; 326 return ret;
299 } 327 }
300 328
301 static const struct file_operations regmap_access_fops = { 329 static const struct file_operations regmap_access_fops = {
302 .open = simple_open, 330 .open = simple_open,
303 .read = regmap_access_read_file, 331 .read = regmap_access_read_file,
304 .llseek = default_llseek, 332 .llseek = default_llseek,
305 }; 333 };
306 334
307 void regmap_debugfs_init(struct regmap *map, const char *name) 335 void regmap_debugfs_init(struct regmap *map, const char *name)
308 { 336 {
309 struct rb_node *next; 337 struct rb_node *next;
310 struct regmap_range_node *range_node; 338 struct regmap_range_node *range_node;
311 339
340 INIT_LIST_HEAD(&map->debugfs_off_cache);
341
312 if (name) { 342 if (name) {
313 map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", 343 map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
314 dev_name(map->dev), name); 344 dev_name(map->dev), name);
315 name = map->debugfs_name; 345 name = map->debugfs_name;
316 } else { 346 } else {
317 name = dev_name(map->dev); 347 name = dev_name(map->dev);
318 } 348 }
319 349
320 map->debugfs = debugfs_create_dir(name, regmap_debugfs_root); 350 map->debugfs = debugfs_create_dir(name, regmap_debugfs_root);
321 if (!map->debugfs) { 351 if (!map->debugfs) {
322 dev_warn(map->dev, "Failed to create debugfs directory\n"); 352 dev_warn(map->dev, "Failed to create debugfs directory\n");
323 return; 353 return;
324 } 354 }
325 355
326 debugfs_create_file("name", 0400, map->debugfs, 356 debugfs_create_file("name", 0400, map->debugfs,
327 map, &regmap_name_fops); 357 map, &regmap_name_fops);
328 358
329 if (map->max_register) { 359 if (map->max_register) {
330 debugfs_create_file("registers", 0400, map->debugfs, 360 debugfs_create_file("registers", 0400, map->debugfs,
331 map, &regmap_map_fops); 361 map, &regmap_map_fops);
332 debugfs_create_file("access", 0400, map->debugfs, 362 debugfs_create_file("access", 0400, map->debugfs,
333 map, &regmap_access_fops); 363 map, &regmap_access_fops);
334 } 364 }
335 365
336 if (map->cache_type) { 366 if (map->cache_type) {
337 debugfs_create_bool("cache_only", 0400, map->debugfs, 367 debugfs_create_bool("cache_only", 0400, map->debugfs,
338 &map->cache_only); 368 &map->cache_only);
339 debugfs_create_bool("cache_dirty", 0400, map->debugfs, 369 debugfs_create_bool("cache_dirty", 0400, map->debugfs,
340 &map->cache_dirty); 370 &map->cache_dirty);
341 debugfs_create_bool("cache_bypass", 0400, map->debugfs, 371 debugfs_create_bool("cache_bypass", 0400, map->debugfs,
342 &map->cache_bypass); 372 &map->cache_bypass);
343 } 373 }
344 374
345 next = rb_first(&map->range_tree); 375 next = rb_first(&map->range_tree);
346 while (next) { 376 while (next) {
347 range_node = rb_entry(next, struct regmap_range_node, node); 377 range_node = rb_entry(next, struct regmap_range_node, node);
348 378
349 if (range_node->name) 379 if (range_node->name)
350 debugfs_create_file(range_node->name, 0400, 380 debugfs_create_file(range_node->name, 0400,
351 map->debugfs, range_node, 381 map->debugfs, range_node,
352 &regmap_range_fops); 382 &regmap_range_fops);
353 383
354 next = rb_next(&range_node->node); 384 next = rb_next(&range_node->node);
355 } 385 }
356 } 386 }
357 387
358 void regmap_debugfs_exit(struct regmap *map) 388 void regmap_debugfs_exit(struct regmap *map)
359 { 389 {
390 struct regmap_debugfs_off_cache *c;
391
360 debugfs_remove_recursive(map->debugfs); 392 debugfs_remove_recursive(map->debugfs);
393 while (!list_empty(&map->debugfs_off_cache)) {
394 c = list_first_entry(&map->debugfs_off_cache,
395 struct regmap_debugfs_off_cache,
396 list);
397 list_del(&c->list);
398 kfree(c);
399 }
361 kfree(map->debugfs_name); 400 kfree(map->debugfs_name);
362 } 401 }
363 402
364 void regmap_debugfs_initcall(void) 403 void regmap_debugfs_initcall(void)
365 { 404 {
366 regmap_debugfs_root = debugfs_create_dir("regmap", NULL); 405 regmap_debugfs_root = debugfs_create_dir("regmap", NULL);
367 if (!regmap_debugfs_root) { 406 if (!regmap_debugfs_root) {
368 pr_warn("regmap: Failed to create debugfs root\n"); 407 pr_warn("regmap: Failed to create debugfs root\n");
369 return; 408 return;
370 } 409 }
371 } 410 }
372 411