regmap: debugfs: Don't bother actually printing when calculating max length
[firefly-linux-kernel-4.4.55.git] / drivers / base / regmap / regmap-debugfs.c
1 /*
2  * Register map access API - debugfs
3  *
4  * Copyright 2011 Wolfson Microelectronics plc
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7  *
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
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/slab.h>
14 #include <linux/mutex.h>
15 #include <linux/debugfs.h>
16 #include <linux/uaccess.h>
17 #include <linux/device.h>
18
19 #include "internal.h"
20
21 static struct dentry *regmap_debugfs_root;
22
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)
25 {
26         return snprintf(NULL, 0, "%x", max_val);
27 }
28
29 static ssize_t regmap_name_read_file(struct file *file,
30                                      char __user *user_buf, size_t count,
31                                      loff_t *ppos)
32 {
33         struct regmap *map = file->private_data;
34         int ret;
35         char *buf;
36
37         buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
38         if (!buf)
39                 return -ENOMEM;
40
41         ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name);
42         if (ret < 0) {
43                 kfree(buf);
44                 return ret;
45         }
46
47         ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
48         kfree(buf);
49         return ret;
50 }
51
52 static const struct file_operations regmap_name_fops = {
53         .open = simple_open,
54         .read = regmap_name_read_file,
55         .llseek = default_llseek,
56 };
57
58 static void regmap_debugfs_free_dump_cache(struct regmap *map)
59 {
60         struct regmap_debugfs_off_cache *c;
61
62         while (!list_empty(&map->debugfs_off_cache)) {
63                 c = list_first_entry(&map->debugfs_off_cache,
64                                      struct regmap_debugfs_off_cache,
65                                      list);
66                 list_del(&c->list);
67                 kfree(c);
68         }
69 }
70
71 /*
72  * Work out where the start offset maps into register numbers, bearing
73  * in mind that we suppress hidden registers.
74  */
75 static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
76                                                   unsigned int base,
77                                                   loff_t from,
78                                                   loff_t *pos)
79 {
80         struct regmap_debugfs_off_cache *c = NULL;
81         loff_t p = 0;
82         unsigned int i, ret;
83         unsigned int fpos_offset;
84         unsigned int reg_offset;
85
86         /*
87          * If we don't have a cache build one so we don't have to do a
88          * linear scan each time.
89          */
90         mutex_lock(&map->cache_lock);
91         i = base;
92         if (list_empty(&map->debugfs_off_cache)) {
93                 for (; i <= map->max_register; i += map->reg_stride) {
94                         /* Skip unprinted registers, closing off cache entry */
95                         if (!regmap_readable(map, i) ||
96                             regmap_precious(map, i)) {
97                                 if (c) {
98                                         c->max = p - 1;
99                                         c->max_reg = i - map->reg_stride;
100                                         list_add_tail(&c->list,
101                                                       &map->debugfs_off_cache);
102                                         c = NULL;
103                                 }
104
105                                 continue;
106                         }
107
108                         /* No cache entry?  Start a new one */
109                         if (!c) {
110                                 c = kzalloc(sizeof(*c), GFP_KERNEL);
111                                 if (!c) {
112                                         regmap_debugfs_free_dump_cache(map);
113                                         mutex_unlock(&map->cache_lock);
114                                         return base;
115                                 }
116                                 c->min = p;
117                                 c->base_reg = i;
118                         }
119
120                         p += map->debugfs_tot_len;
121                 }
122         }
123
124         /* Close the last entry off if we didn't scan beyond it */
125         if (c) {
126                 c->max = p - 1;
127                 c->max_reg = i - map->reg_stride;
128                 list_add_tail(&c->list,
129                               &map->debugfs_off_cache);
130         }
131
132         /*
133          * This should never happen; we return above if we fail to
134          * allocate and we should never be in this code if there are
135          * no registers at all.
136          */
137         WARN_ON(list_empty(&map->debugfs_off_cache));
138         ret = base;
139
140         /* Find the relevant block:offset */
141         list_for_each_entry(c, &map->debugfs_off_cache, list) {
142                 if (from >= c->min && from <= c->max) {
143                         fpos_offset = from - c->min;
144                         reg_offset = fpos_offset / map->debugfs_tot_len;
145                         *pos = c->min + (reg_offset * map->debugfs_tot_len);
146                         mutex_unlock(&map->cache_lock);
147                         return c->base_reg + reg_offset;
148                 }
149
150                 *pos = c->max;
151                 ret = c->max_reg;
152         }
153         mutex_unlock(&map->cache_lock);
154
155         return ret;
156 }
157
158 static inline void regmap_calc_tot_len(struct regmap *map,
159                                        void *buf, size_t count)
160 {
161         /* Calculate the length of a fixed format  */
162         if (!map->debugfs_tot_len) {
163                 map->debugfs_reg_len = regmap_calc_reg_len(map->max_register,
164                                                            buf, count);
165                 map->debugfs_val_len = 2 * map->format.val_bytes;
166                 map->debugfs_tot_len = map->debugfs_reg_len +
167                         map->debugfs_val_len + 3;      /* : \n */
168         }
169 }
170
171 static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
172                                    unsigned int to, char __user *user_buf,
173                                    size_t count, loff_t *ppos)
174 {
175         size_t buf_pos = 0;
176         loff_t p = *ppos;
177         ssize_t ret;
178         int i;
179         char *buf;
180         unsigned int val, start_reg;
181
182         if (*ppos < 0 || !count)
183                 return -EINVAL;
184
185         buf = kmalloc(count, GFP_KERNEL);
186         if (!buf)
187                 return -ENOMEM;
188
189         regmap_calc_tot_len(map, buf, count);
190
191         /* Work out which register we're starting at */
192         start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p);
193
194         for (i = start_reg; i <= to; i += map->reg_stride) {
195                 if (!regmap_readable(map, i))
196                         continue;
197
198                 if (regmap_precious(map, i))
199                         continue;
200
201                 /* If we're in the region the user is trying to read */
202                 if (p >= *ppos) {
203                         /* ...but not beyond it */
204                         if (buf_pos + map->debugfs_tot_len > count)
205                                 break;
206
207                         /* Format the register */
208                         snprintf(buf + buf_pos, count - buf_pos, "%.*x: ",
209                                  map->debugfs_reg_len, i - from);
210                         buf_pos += map->debugfs_reg_len + 2;
211
212                         /* Format the value, write all X if we can't read */
213                         ret = regmap_read(map, i, &val);
214                         if (ret == 0)
215                                 snprintf(buf + buf_pos, count - buf_pos,
216                                          "%.*x", map->debugfs_val_len, val);
217                         else
218                                 memset(buf + buf_pos, 'X',
219                                        map->debugfs_val_len);
220                         buf_pos += 2 * map->format.val_bytes;
221
222                         buf[buf_pos++] = '\n';
223                 }
224                 p += map->debugfs_tot_len;
225         }
226
227         ret = buf_pos;
228
229         if (copy_to_user(user_buf, buf, buf_pos)) {
230                 ret = -EFAULT;
231                 goto out;
232         }
233
234         *ppos += buf_pos;
235
236 out:
237         kfree(buf);
238         return ret;
239 }
240
241 static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
242                                     size_t count, loff_t *ppos)
243 {
244         struct regmap *map = file->private_data;
245
246         return regmap_read_debugfs(map, 0, map->max_register, user_buf,
247                                    count, ppos);
248 }
249
250 #undef REGMAP_ALLOW_WRITE_DEBUGFS
251 #ifdef REGMAP_ALLOW_WRITE_DEBUGFS
252 /*
253  * This can be dangerous especially when we have clients such as
254  * PMICs, therefore don't provide any real compile time configuration option
255  * for this feature, people who want to use this will need to modify
256  * the source code directly.
257  */
258 static ssize_t regmap_map_write_file(struct file *file,
259                                      const char __user *user_buf,
260                                      size_t count, loff_t *ppos)
261 {
262         char buf[32];
263         size_t buf_size;
264         char *start = buf;
265         unsigned long reg, value;
266         struct regmap *map = file->private_data;
267         int ret;
268
269         buf_size = min(count, (sizeof(buf)-1));
270         if (copy_from_user(buf, user_buf, buf_size))
271                 return -EFAULT;
272         buf[buf_size] = 0;
273
274         while (*start == ' ')
275                 start++;
276         reg = simple_strtoul(start, &start, 16);
277         while (*start == ' ')
278                 start++;
279         if (strict_strtoul(start, 16, &value))
280                 return -EINVAL;
281
282         /* Userspace has been fiddling around behind the kernel's back */
283         add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
284
285         ret = regmap_write(map, reg, value);
286         if (ret < 0)
287                 return ret;
288         return buf_size;
289 }
290 #else
291 #define regmap_map_write_file NULL
292 #endif
293
294 static const struct file_operations regmap_map_fops = {
295         .open = simple_open,
296         .read = regmap_map_read_file,
297         .write = regmap_map_write_file,
298         .llseek = default_llseek,
299 };
300
301 static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf,
302                                       size_t count, loff_t *ppos)
303 {
304         struct regmap_range_node *range = file->private_data;
305         struct regmap *map = range->map;
306
307         return regmap_read_debugfs(map, range->range_min, range->range_max,
308                                    user_buf, count, ppos);
309 }
310
311 static const struct file_operations regmap_range_fops = {
312         .open = simple_open,
313         .read = regmap_range_read_file,
314         .llseek = default_llseek,
315 };
316
317 static ssize_t regmap_reg_ranges_read_file(struct file *file,
318                                            char __user *user_buf, size_t count,
319                                            loff_t *ppos)
320 {
321         struct regmap *map = file->private_data;
322         struct regmap_debugfs_off_cache *c;
323         loff_t p = 0;
324         size_t buf_pos = 0;
325         char *buf;
326         char *entry;
327         int ret;
328
329         if (*ppos < 0 || !count)
330                 return -EINVAL;
331
332         buf = kmalloc(count, GFP_KERNEL);
333         if (!buf)
334                 return -ENOMEM;
335
336         entry = kmalloc(PAGE_SIZE, GFP_KERNEL);
337         if (!entry) {
338                 kfree(buf);
339                 return -ENOMEM;
340         }
341
342         /* While we are at it, build the register dump cache
343          * now so the read() operation on the `registers' file
344          * can benefit from using the cache.  We do not care
345          * about the file position information that is contained
346          * in the cache, just about the actual register blocks */
347         regmap_calc_tot_len(map, buf, count);
348         regmap_debugfs_get_dump_start(map, 0, *ppos, &p);
349
350         /* Reset file pointer as the fixed-format of the `registers'
351          * file is not compatible with the `range' file */
352         p = 0;
353         mutex_lock(&map->cache_lock);
354         list_for_each_entry(c, &map->debugfs_off_cache, list) {
355                 snprintf(entry, PAGE_SIZE, "%x-%x",
356                          c->base_reg, c->max_reg);
357                 if (p >= *ppos) {
358                         if (buf_pos + 1 + strlen(entry) > count)
359                                 break;
360                         snprintf(buf + buf_pos, count - buf_pos,
361                                  "%s", entry);
362                         buf_pos += strlen(entry);
363                         buf[buf_pos] = '\n';
364                         buf_pos++;
365                 }
366                 p += strlen(entry) + 1;
367         }
368         mutex_unlock(&map->cache_lock);
369
370         kfree(entry);
371         ret = buf_pos;
372
373         if (copy_to_user(user_buf, buf, buf_pos)) {
374                 ret = -EFAULT;
375                 goto out_buf;
376         }
377
378         *ppos += buf_pos;
379 out_buf:
380         kfree(buf);
381         return ret;
382 }
383
384 static const struct file_operations regmap_reg_ranges_fops = {
385         .open = simple_open,
386         .read = regmap_reg_ranges_read_file,
387         .llseek = default_llseek,
388 };
389
390 static ssize_t regmap_access_read_file(struct file *file,
391                                        char __user *user_buf, size_t count,
392                                        loff_t *ppos)
393 {
394         int reg_len, tot_len;
395         size_t buf_pos = 0;
396         loff_t p = 0;
397         ssize_t ret;
398         int i;
399         struct regmap *map = file->private_data;
400         char *buf;
401
402         if (*ppos < 0 || !count)
403                 return -EINVAL;
404
405         buf = kmalloc(count, GFP_KERNEL);
406         if (!buf)
407                 return -ENOMEM;
408
409         /* Calculate the length of a fixed format  */
410         reg_len = regmap_calc_reg_len(map->max_register, buf, count);
411         tot_len = reg_len + 10; /* ': R W V P\n' */
412
413         for (i = 0; i <= map->max_register; i += map->reg_stride) {
414                 /* Ignore registers which are neither readable nor writable */
415                 if (!regmap_readable(map, i) && !regmap_writeable(map, i))
416                         continue;
417
418                 /* If we're in the region the user is trying to read */
419                 if (p >= *ppos) {
420                         /* ...but not beyond it */
421                         if (buf_pos + tot_len + 1 >= count)
422                                 break;
423
424                         /* Format the register */
425                         snprintf(buf + buf_pos, count - buf_pos,
426                                  "%.*x: %c %c %c %c\n",
427                                  reg_len, i,
428                                  regmap_readable(map, i) ? 'y' : 'n',
429                                  regmap_writeable(map, i) ? 'y' : 'n',
430                                  regmap_volatile(map, i) ? 'y' : 'n',
431                                  regmap_precious(map, i) ? 'y' : 'n');
432
433                         buf_pos += tot_len;
434                 }
435                 p += tot_len;
436         }
437
438         ret = buf_pos;
439
440         if (copy_to_user(user_buf, buf, buf_pos)) {
441                 ret = -EFAULT;
442                 goto out;
443         }
444
445         *ppos += buf_pos;
446
447 out:
448         kfree(buf);
449         return ret;
450 }
451
452 static const struct file_operations regmap_access_fops = {
453         .open = simple_open,
454         .read = regmap_access_read_file,
455         .llseek = default_llseek,
456 };
457
458 void regmap_debugfs_init(struct regmap *map, const char *name)
459 {
460         struct rb_node *next;
461         struct regmap_range_node *range_node;
462         const char *devname = "dummy";
463
464         INIT_LIST_HEAD(&map->debugfs_off_cache);
465         mutex_init(&map->cache_lock);
466
467         if (map->dev)
468                 devname = dev_name(map->dev);
469
470         if (name) {
471                 map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
472                                               devname, name);
473                 name = map->debugfs_name;
474         } else {
475                 name = devname;
476         }
477
478         map->debugfs = debugfs_create_dir(name, regmap_debugfs_root);
479         if (!map->debugfs) {
480                 dev_warn(map->dev, "Failed to create debugfs directory\n");
481                 return;
482         }
483
484         debugfs_create_file("name", 0400, map->debugfs,
485                             map, &regmap_name_fops);
486
487         debugfs_create_file("range", 0400, map->debugfs,
488                             map, &regmap_reg_ranges_fops);
489
490         if (map->max_register) {
491                 debugfs_create_file("registers", 0400, map->debugfs,
492                                     map, &regmap_map_fops);
493                 debugfs_create_file("access", 0400, map->debugfs,
494                                     map, &regmap_access_fops);
495         }
496
497         if (map->cache_type) {
498                 debugfs_create_bool("cache_only", 0400, map->debugfs,
499                                     &map->cache_only);
500                 debugfs_create_bool("cache_dirty", 0400, map->debugfs,
501                                     &map->cache_dirty);
502                 debugfs_create_bool("cache_bypass", 0400, map->debugfs,
503                                     &map->cache_bypass);
504         }
505
506         next = rb_first(&map->range_tree);
507         while (next) {
508                 range_node = rb_entry(next, struct regmap_range_node, node);
509
510                 if (range_node->name)
511                         debugfs_create_file(range_node->name, 0400,
512                                             map->debugfs, range_node,
513                                             &regmap_range_fops);
514
515                 next = rb_next(&range_node->node);
516         }
517 }
518
519 void regmap_debugfs_exit(struct regmap *map)
520 {
521         debugfs_remove_recursive(map->debugfs);
522         mutex_lock(&map->cache_lock);
523         regmap_debugfs_free_dump_cache(map);
524         mutex_unlock(&map->cache_lock);
525         kfree(map->debugfs_name);
526 }
527
528 void regmap_debugfs_initcall(void)
529 {
530         regmap_debugfs_root = debugfs_create_dir("regmap", NULL);
531         if (!regmap_debugfs_root) {
532                 pr_warn("regmap: Failed to create debugfs root\n");
533                 return;
534         }
535 }