aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-14 12:11:06 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-14 12:11:06 -0500
commit43280026c842c44a8505a1b909378e62f754ecfe (patch)
tree5184f1d8844a0018f776906d637ba46a926455fa
parent3689cf7fd17ea50850f9036f398bd56e08c8806d (diff)
parent4dd7c5531d3b046574da39096b1a66c738aca102 (diff)
Merge remote-tracking branch 'regmap/topic/debugfs' into regmap-next
-rw-r--r--drivers/base/regmap/internal.h1
-rw-r--r--drivers/base/regmap/regmap-debugfs.c50
2 files changed, 33 insertions, 18 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 202518641779..2cad787fa548 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -26,6 +26,7 @@ struct regmap_debugfs_off_cache {
26 off_t min; 26 off_t min;
27 off_t max; 27 off_t max;
28 unsigned int base_reg; 28 unsigned int base_reg;
29 unsigned int max_reg;
29}; 30};
30 31
31struct regmap_format { 32struct regmap_format {
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index d9a6c94ce423..78d5f20c5f5b 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -81,6 +81,8 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
81 struct regmap_debugfs_off_cache *c = NULL; 81 struct regmap_debugfs_off_cache *c = NULL;
82 loff_t p = 0; 82 loff_t p = 0;
83 unsigned int i, ret; 83 unsigned int i, ret;
84 unsigned int fpos_offset;
85 unsigned int reg_offset;
84 86
85 /* 87 /*
86 * If we don't have a cache build one so we don't have to do a 88 * If we don't have a cache build one so we don't have to do a
@@ -93,6 +95,9 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
93 regmap_precious(map, i)) { 95 regmap_precious(map, i)) {
94 if (c) { 96 if (c) {
95 c->max = p - 1; 97 c->max = p - 1;
98 fpos_offset = c->max - c->min;
99 reg_offset = fpos_offset / map->debugfs_tot_len;
100 c->max_reg = c->base_reg + reg_offset;
96 list_add_tail(&c->list, 101 list_add_tail(&c->list,
97 &map->debugfs_off_cache); 102 &map->debugfs_off_cache);
98 c = NULL; 103 c = NULL;
@@ -119,6 +124,9 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
119 /* Close the last entry off if we didn't scan beyond it */ 124 /* Close the last entry off if we didn't scan beyond it */
120 if (c) { 125 if (c) {
121 c->max = p - 1; 126 c->max = p - 1;
127 fpos_offset = c->max - c->min;
128 reg_offset = fpos_offset / map->debugfs_tot_len;
129 c->max_reg = c->base_reg + reg_offset;
122 list_add_tail(&c->list, 130 list_add_tail(&c->list,
123 &map->debugfs_off_cache); 131 &map->debugfs_off_cache);
124 } 132 }
@@ -128,25 +136,38 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
128 * allocate and we should never be in this code if there are 136 * allocate and we should never be in this code if there are
129 * no registers at all. 137 * no registers at all.
130 */ 138 */
131 if (list_empty(&map->debugfs_off_cache)) { 139 WARN_ON(list_empty(&map->debugfs_off_cache));
132 WARN_ON(list_empty(&map->debugfs_off_cache)); 140 ret = base;
133 return base;
134 }
135 141
136 /* Find the relevant block */ 142 /* Find the relevant block:offset */
137 list_for_each_entry(c, &map->debugfs_off_cache, list) { 143 list_for_each_entry(c, &map->debugfs_off_cache, list) {
138 if (from >= c->min && from <= c->max) { 144 if (from >= c->min && from <= c->max) {
139 *pos = c->min; 145 fpos_offset = from - c->min;
140 return c->base_reg; 146 reg_offset = fpos_offset / map->debugfs_tot_len;
147 *pos = c->min + (reg_offset * map->debugfs_tot_len);
148 return c->base_reg + reg_offset;
141 } 149 }
142 150
143 *pos = c->min; 151 *pos = c->max;
144 ret = c->base_reg; 152 ret = c->max_reg;
145 } 153 }
146 154
147 return ret; 155 return ret;
148} 156}
149 157
158static 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
150static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from, 171static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
151 unsigned int to, char __user *user_buf, 172 unsigned int to, char __user *user_buf,
152 size_t count, loff_t *ppos) 173 size_t count, loff_t *ppos)
@@ -165,14 +186,7 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
165 if (!buf) 186 if (!buf)
166 return -ENOMEM; 187 return -ENOMEM;
167 188
168 /* Calculate the length of a fixed format */ 189 regmap_calc_tot_len(map, buf, count);
169 if (!map->debugfs_tot_len) {
170 map->debugfs_reg_len = regmap_calc_reg_len(map->max_register,
171 buf, count);
172 map->debugfs_val_len = 2 * map->format.val_bytes;
173 map->debugfs_tot_len = map->debugfs_reg_len +
174 map->debugfs_val_len + 3; /* : \n */
175 }
176 190
177 /* Work out which register we're starting at */ 191 /* Work out which register we're starting at */
178 start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p); 192 start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p);
@@ -187,7 +201,7 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
187 /* If we're in the region the user is trying to read */ 201 /* If we're in the region the user is trying to read */
188 if (p >= *ppos) { 202 if (p >= *ppos) {
189 /* ...but not beyond it */ 203 /* ...but not beyond it */
190 if (buf_pos + 1 + map->debugfs_tot_len >= count) 204 if (buf_pos + map->debugfs_tot_len > count)
191 break; 205 break;
192 206
193 /* Format the register */ 207 /* Format the register */