aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regmap-debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/regmap/regmap-debugfs.c')
-rw-r--r--drivers/base/regmap/regmap-debugfs.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 749a1dc5bbfb..07aad786f817 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -65,25 +65,53 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
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 70 unsigned int i, ret;
71 for (i = base; i <= map->max_register; i += map->reg_stride) { 71
72 if (!regmap_readable(map, i)) 72 /*
73 continue; 73 * If we don't have a cache build one so we don't have to do a
74 74 * linear scan each time.
75 if (regmap_precious(map, i)) 75 */
76 continue; 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 }
87
88 continue;
89 }
90
91 /* No cache entry? Start a new one */
92 if (!c) {
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;
101 }
102 }
77 103
78 if (i >= from) { 104 /* Find the relevant block */
79 *pos = p; 105 list_for_each_entry(c, &map->debugfs_off_cache, list) {
80 return i; 106 if (*pos >= c->min && *pos <= c->max) {
107 *pos = c->min;
108 return c->base_reg;
81 } 109 }
82 110
83 p += map->debugfs_tot_len; 111 ret = c->max;
84 } 112 }
85 113
86 return base; 114 return ret;
87} 115}
88 116
89static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from, 117static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
@@ -309,6 +337,8 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
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);
@@ -357,7 +387,16 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
357 387
358void regmap_debugfs_exit(struct regmap *map) 388void 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