aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-01-14 23:20:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-01-14 23:20:44 -0500
commit7dea1ff3b7b48356c02cb00d6a4e8d5aaf680830 (patch)
tree49129bb8f272fed7979d70bb2599fc470d57b9e2 /drivers/base
parent2ac1e664a963fb1047baabe1c04f3869a153889b (diff)
parente8d6539c8a94b88fc7ca5d6bdd9eeb0e64b434e4 (diff)
Merge tag 'regmap-debugfs-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap debugfs optimisation fixes from Mark Brown: "The debugfs optimisations merged in v3.8 weren't my finest hour, there were a number of cases that the more complex algorithm made worse especially around the error handling. This patch series should address those issues." * tag 'regmap-debugfs-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regmap: debugfs: Make sure we store the last entry in the offset cache regmap: debugfs: Ensure a correct return value for empty caches regmap: debugfs: Discard the cache if we fail to allocate an entry regmap: debugfs: Fix check for block start in cached seeks regmap: debugfs: Fix attempts to read nonexistant register blocks
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regmap-debugfs.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 07aad786f817..46a213a596e2 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -56,6 +56,19 @@ static const struct file_operations regmap_name_fops = {
56 .llseek = default_llseek, 56 .llseek = default_llseek,
57}; 57};
58 58
59static void regmap_debugfs_free_dump_cache(struct regmap *map)
60{
61 struct regmap_debugfs_off_cache *c;
62
63 while (!list_empty(&map->debugfs_off_cache)) {
64 c = list_first_entry(&map->debugfs_off_cache,
65 struct regmap_debugfs_off_cache,
66 list);
67 list_del(&c->list);
68 kfree(c);
69 }
70}
71
59/* 72/*
60 * Work out where the start offset maps into register numbers, bearing 73 * Work out where the start offset maps into register numbers, bearing
61 * in mind that we suppress hidden registers. 74 * in mind that we suppress hidden registers.
@@ -91,8 +104,10 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
91 /* No cache entry? Start a new one */ 104 /* No cache entry? Start a new one */
92 if (!c) { 105 if (!c) {
93 c = kzalloc(sizeof(*c), GFP_KERNEL); 106 c = kzalloc(sizeof(*c), GFP_KERNEL);
94 if (!c) 107 if (!c) {
95 break; 108 regmap_debugfs_free_dump_cache(map);
109 return base;
110 }
96 c->min = p; 111 c->min = p;
97 c->base_reg = i; 112 c->base_reg = i;
98 } 113 }
@@ -101,14 +116,34 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
101 } 116 }
102 } 117 }
103 118
119 /* Close the last entry off if we didn't scan beyond it */
120 if (c) {
121 c->max = p - 1;
122 list_add_tail(&c->list,
123 &map->debugfs_off_cache);
124 } else {
125 return base;
126 }
127
128 /*
129 * This should never happen; we return above if we fail to
130 * allocate and we should never be in this code if there are
131 * no registers at all.
132 */
133 if (list_empty(&map->debugfs_off_cache)) {
134 WARN_ON(list_empty(&map->debugfs_off_cache));
135 return base;
136 }
137
104 /* Find the relevant block */ 138 /* Find the relevant block */
105 list_for_each_entry(c, &map->debugfs_off_cache, list) { 139 list_for_each_entry(c, &map->debugfs_off_cache, list) {
106 if (*pos >= c->min && *pos <= c->max) { 140 if (from >= c->min && from <= c->max) {
107 *pos = c->min; 141 *pos = c->min;
108 return c->base_reg; 142 return c->base_reg;
109 } 143 }
110 144
111 ret = c->max; 145 *pos = c->min;
146 ret = c->base_reg;
112 } 147 }
113 148
114 return ret; 149 return ret;
@@ -387,16 +422,8 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
387 422
388void regmap_debugfs_exit(struct regmap *map) 423void regmap_debugfs_exit(struct regmap *map)
389{ 424{
390 struct regmap_debugfs_off_cache *c;
391
392 debugfs_remove_recursive(map->debugfs); 425 debugfs_remove_recursive(map->debugfs);
393 while (!list_empty(&map->debugfs_off_cache)) { 426 regmap_debugfs_free_dump_cache(map);
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 }
400 kfree(map->debugfs_name); 427 kfree(map->debugfs_name);
401} 428}
402 429