aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 19:31:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 19:31:26 -0400
commit7b053842b95914119f132fdac294fb2591b2e9a8 (patch)
tree9d17379a2ed7c8a3119489168adf695a44543960
parent5415ba99c229105a6939a7f9effe21045b8b2e5b (diff)
parent38a817965d2d624b0db68f3bf5ae783ad7f2087a (diff)
Merge tag 'regmap-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown: "In user visible terms just a couple of enhancements here, though there was a moderate amount of refactoring required in order to support the register cache sync performance improvements. - Support for block and asynchronous I/O during register cache syncing; this provides a use case dependant performance improvement. - Additional debugfs information on the memory consuption and register set" * tag 'regmap-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: (23 commits) regmap: don't corrupt work buffer in _regmap_raw_write() regmap: cache: Fix format specifier in dev_dbg regmap: cache: Make regcache_sync_block_raw static regmap: cache: Write consecutive registers in a single block write regmap: cache: Split raw and non-raw syncs regmap: cache: Factor out block sync regmap: cache: Factor out reg_present support from rbtree cache regmap: cache: Use raw I/O to sync rbtrees if we can regmap: core: Provide regmap_can_raw_write() operation regmap: cache: Provide a get address of value operation regmap: Cut down on the average # of nodes in the rbtree cache regmap: core: Make raw write available to regcache regmap: core: Warn on invalid operation combinations regmap: irq: Clarify error message when we fail to request primary IRQ regmap: rbtree Expose total memory consumption in the rbtree debugfs entry regmap: debugfs: Add a registers `range' file regmap: debugfs: Simplify calculation of `c->max_reg' regmap: cache: Store caches in native register format where possible regmap: core: Split out in place value parsing regmap: cache: Use regcache_get_value() to check if we updated ...
-rw-r--r--drivers/base/regmap/internal.h40
-rw-r--r--drivers/base/regmap/regcache-lzo.c6
-rw-r--r--drivers/base/regmap/regcache-rbtree.c100
-rw-r--r--drivers/base/regmap/regcache.c196
-rw-r--r--drivers/base/regmap/regmap-debugfs.c94
-rw-r--r--drivers/base/regmap/regmap-irq.c3
-rw-r--r--drivers/base/regmap/regmap.c92
-rw-r--r--include/linux/regmap.h1
-rw-r--r--include/trace/events/regmap.h48
9 files changed, 462 insertions, 118 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 5a22bd33ce3d..c130536e0ab0 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -38,7 +38,8 @@ struct regmap_format {
38 unsigned int reg, unsigned int val); 38 unsigned int reg, unsigned int val);
39 void (*format_reg)(void *buf, unsigned int reg, unsigned int shift); 39 void (*format_reg)(void *buf, unsigned int reg, unsigned int shift);
40 void (*format_val)(void *buf, unsigned int val, unsigned int shift); 40 void (*format_val)(void *buf, unsigned int val, unsigned int shift);
41 unsigned int (*parse_val)(void *buf); 41 unsigned int (*parse_val)(const void *buf);
42 void (*parse_inplace)(void *buf);
42}; 43};
43 44
44struct regmap_async { 45struct regmap_async {
@@ -76,6 +77,7 @@ struct regmap {
76 unsigned int debugfs_tot_len; 77 unsigned int debugfs_tot_len;
77 78
78 struct list_head debugfs_off_cache; 79 struct list_head debugfs_off_cache;
80 struct mutex cache_lock;
79#endif 81#endif
80 82
81 unsigned int max_register; 83 unsigned int max_register;
@@ -125,6 +127,9 @@ struct regmap {
125 void *cache; 127 void *cache;
126 u32 cache_dirty; 128 u32 cache_dirty;
127 129
130 unsigned long *cache_present;
131 unsigned int cache_present_nbits;
132
128 struct reg_default *patch; 133 struct reg_default *patch;
129 int patch_regs; 134 int patch_regs;
130 135
@@ -187,12 +192,35 @@ int regcache_read(struct regmap *map,
187int regcache_write(struct regmap *map, 192int regcache_write(struct regmap *map,
188 unsigned int reg, unsigned int value); 193 unsigned int reg, unsigned int value);
189int regcache_sync(struct regmap *map); 194int regcache_sync(struct regmap *map);
190 195int regcache_sync_block(struct regmap *map, void *block,
191unsigned int regcache_get_val(const void *base, unsigned int idx, 196 unsigned int block_base, unsigned int start,
192 unsigned int word_size); 197 unsigned int end);
193bool regcache_set_val(void *base, unsigned int idx, 198
194 unsigned int val, unsigned int word_size); 199static inline const void *regcache_get_val_addr(struct regmap *map,
200 const void *base,
201 unsigned int idx)
202{
203 return base + (map->cache_word_size * idx);
204}
205
206unsigned int regcache_get_val(struct regmap *map, const void *base,
207 unsigned int idx);
208bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
209 unsigned int val);
195int regcache_lookup_reg(struct regmap *map, unsigned int reg); 210int regcache_lookup_reg(struct regmap *map, unsigned int reg);
211int regcache_set_reg_present(struct regmap *map, unsigned int reg);
212
213static inline bool regcache_reg_present(struct regmap *map, unsigned int reg)
214{
215 if (!map->cache_present)
216 return true;
217 if (reg > map->cache_present_nbits)
218 return false;
219 return map->cache_present[BIT_WORD(reg)] & BIT_MASK(reg);
220}
221
222int _regmap_raw_write(struct regmap *map, unsigned int reg,
223 const void *val, size_t val_len, bool async);
196 224
197void regmap_async_complete_cb(struct regmap_async *async, int ret); 225void regmap_async_complete_cb(struct regmap_async *async, int ret);
198 226
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c
index afd6aa91a0df..e210a6d1406a 100644
--- a/drivers/base/regmap/regcache-lzo.c
+++ b/drivers/base/regmap/regcache-lzo.c
@@ -260,8 +260,7 @@ static int regcache_lzo_read(struct regmap *map,
260 ret = regcache_lzo_decompress_cache_block(map, lzo_block); 260 ret = regcache_lzo_decompress_cache_block(map, lzo_block);
261 if (ret >= 0) 261 if (ret >= 0)
262 /* fetch the value from the cache */ 262 /* fetch the value from the cache */
263 *value = regcache_get_val(lzo_block->dst, blkpos, 263 *value = regcache_get_val(map, lzo_block->dst, blkpos);
264 map->cache_word_size);
265 264
266 kfree(lzo_block->dst); 265 kfree(lzo_block->dst);
267 /* restore the pointer and length of the compressed block */ 266 /* restore the pointer and length of the compressed block */
@@ -304,8 +303,7 @@ static int regcache_lzo_write(struct regmap *map,
304 } 303 }
305 304
306 /* write the new value to the cache */ 305 /* write the new value to the cache */
307 if (regcache_set_val(lzo_block->dst, blkpos, value, 306 if (regcache_set_val(map, lzo_block->dst, blkpos, value)) {
308 map->cache_word_size)) {
309 kfree(lzo_block->dst); 307 kfree(lzo_block->dst);
310 goto out; 308 goto out;
311 } 309 }
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 79f4fca9877a..aa0875f6f1b7 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -47,22 +47,21 @@ static inline void regcache_rbtree_get_base_top_reg(
47 *top = rbnode->base_reg + ((rbnode->blklen - 1) * map->reg_stride); 47 *top = rbnode->base_reg + ((rbnode->blklen - 1) * map->reg_stride);
48} 48}
49 49
50static unsigned int regcache_rbtree_get_register( 50static unsigned int regcache_rbtree_get_register(struct regmap *map,
51 struct regcache_rbtree_node *rbnode, unsigned int idx, 51 struct regcache_rbtree_node *rbnode, unsigned int idx)
52 unsigned int word_size)
53{ 52{
54 return regcache_get_val(rbnode->block, idx, word_size); 53 return regcache_get_val(map, rbnode->block, idx);
55} 54}
56 55
57static void regcache_rbtree_set_register(struct regcache_rbtree_node *rbnode, 56static void regcache_rbtree_set_register(struct regmap *map,
58 unsigned int idx, unsigned int val, 57 struct regcache_rbtree_node *rbnode,
59 unsigned int word_size) 58 unsigned int idx, unsigned int val)
60{ 59{
61 regcache_set_val(rbnode->block, idx, val, word_size); 60 regcache_set_val(map, rbnode->block, idx, val);
62} 61}
63 62
64static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map, 63static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map,
65 unsigned int reg) 64 unsigned int reg)
66{ 65{
67 struct regcache_rbtree_ctx *rbtree_ctx = map->cache; 66 struct regcache_rbtree_ctx *rbtree_ctx = map->cache;
68 struct rb_node *node; 67 struct rb_node *node;
@@ -139,15 +138,21 @@ static int rbtree_show(struct seq_file *s, void *ignored)
139 struct regcache_rbtree_node *n; 138 struct regcache_rbtree_node *n;
140 struct rb_node *node; 139 struct rb_node *node;
141 unsigned int base, top; 140 unsigned int base, top;
141 size_t mem_size;
142 int nodes = 0; 142 int nodes = 0;
143 int registers = 0; 143 int registers = 0;
144 int this_registers, average; 144 int this_registers, average;
145 145
146 map->lock(map); 146 map->lock(map);
147 147
148 mem_size = sizeof(*rbtree_ctx);
149 mem_size += BITS_TO_LONGS(map->cache_present_nbits) * sizeof(long);
150
148 for (node = rb_first(&rbtree_ctx->root); node != NULL; 151 for (node = rb_first(&rbtree_ctx->root); node != NULL;
149 node = rb_next(node)) { 152 node = rb_next(node)) {
150 n = container_of(node, struct regcache_rbtree_node, node); 153 n = container_of(node, struct regcache_rbtree_node, node);
154 mem_size += sizeof(*n);
155 mem_size += (n->blklen * map->cache_word_size);
151 156
152 regcache_rbtree_get_base_top_reg(map, n, &base, &top); 157 regcache_rbtree_get_base_top_reg(map, n, &base, &top);
153 this_registers = ((top - base) / map->reg_stride) + 1; 158 this_registers = ((top - base) / map->reg_stride) + 1;
@@ -162,8 +167,8 @@ static int rbtree_show(struct seq_file *s, void *ignored)
162 else 167 else
163 average = 0; 168 average = 0;
164 169
165 seq_printf(s, "%d nodes, %d registers, average %d registers\n", 170 seq_printf(s, "%d nodes, %d registers, average %d registers, used %zu bytes\n",
166 nodes, registers, average); 171 nodes, registers, average, mem_size);
167 172
168 map->unlock(map); 173 map->unlock(map);
169 174
@@ -260,8 +265,9 @@ static int regcache_rbtree_read(struct regmap *map,
260 rbnode = regcache_rbtree_lookup(map, reg); 265 rbnode = regcache_rbtree_lookup(map, reg);
261 if (rbnode) { 266 if (rbnode) {
262 reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; 267 reg_tmp = (reg - rbnode->base_reg) / map->reg_stride;
263 *value = regcache_rbtree_get_register(rbnode, reg_tmp, 268 if (!regcache_reg_present(map, reg))
264 map->cache_word_size); 269 return -ENOENT;
270 *value = regcache_rbtree_get_register(map, rbnode, reg_tmp);
265 } else { 271 } else {
266 return -ENOENT; 272 return -ENOENT;
267 } 273 }
@@ -270,21 +276,23 @@ static int regcache_rbtree_read(struct regmap *map,
270} 276}
271 277
272 278
273static int regcache_rbtree_insert_to_block(struct regcache_rbtree_node *rbnode, 279static int regcache_rbtree_insert_to_block(struct regmap *map,
280 struct regcache_rbtree_node *rbnode,
274 unsigned int pos, unsigned int reg, 281 unsigned int pos, unsigned int reg,
275 unsigned int value, unsigned int word_size) 282 unsigned int value)
276{ 283{
277 u8 *blk; 284 u8 *blk;
278 285
279 blk = krealloc(rbnode->block, 286 blk = krealloc(rbnode->block,
280 (rbnode->blklen + 1) * word_size, GFP_KERNEL); 287 (rbnode->blklen + 1) * map->cache_word_size,
288 GFP_KERNEL);
281 if (!blk) 289 if (!blk)
282 return -ENOMEM; 290 return -ENOMEM;
283 291
284 /* insert the register value in the correct place in the rbnode block */ 292 /* insert the register value in the correct place in the rbnode block */
285 memmove(blk + (pos + 1) * word_size, 293 memmove(blk + (pos + 1) * map->cache_word_size,
286 blk + pos * word_size, 294 blk + pos * map->cache_word_size,
287 (rbnode->blklen - pos) * word_size); 295 (rbnode->blklen - pos) * map->cache_word_size);
288 296
289 /* update the rbnode block, its size and the base register */ 297 /* update the rbnode block, its size and the base register */
290 rbnode->block = blk; 298 rbnode->block = blk;
@@ -292,7 +300,7 @@ static int regcache_rbtree_insert_to_block(struct regcache_rbtree_node *rbnode,
292 if (!pos) 300 if (!pos)
293 rbnode->base_reg = reg; 301 rbnode->base_reg = reg;
294 302
295 regcache_rbtree_set_register(rbnode, pos, value, word_size); 303 regcache_rbtree_set_register(map, rbnode, pos, value);
296 return 0; 304 return 0;
297} 305}
298 306
@@ -302,25 +310,24 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
302 struct regcache_rbtree_ctx *rbtree_ctx; 310 struct regcache_rbtree_ctx *rbtree_ctx;
303 struct regcache_rbtree_node *rbnode, *rbnode_tmp; 311 struct regcache_rbtree_node *rbnode, *rbnode_tmp;
304 struct rb_node *node; 312 struct rb_node *node;
305 unsigned int val;
306 unsigned int reg_tmp; 313 unsigned int reg_tmp;
307 unsigned int pos; 314 unsigned int pos;
308 int i; 315 int i;
309 int ret; 316 int ret;
310 317
311 rbtree_ctx = map->cache; 318 rbtree_ctx = map->cache;
319 /* update the reg_present bitmap, make space if necessary */
320 ret = regcache_set_reg_present(map, reg);
321 if (ret < 0)
322 return ret;
323
312 /* if we can't locate it in the cached rbnode we'll have 324 /* if we can't locate it in the cached rbnode we'll have
313 * to traverse the rbtree looking for it. 325 * to traverse the rbtree looking for it.
314 */ 326 */
315 rbnode = regcache_rbtree_lookup(map, reg); 327 rbnode = regcache_rbtree_lookup(map, reg);
316 if (rbnode) { 328 if (rbnode) {
317 reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; 329 reg_tmp = (reg - rbnode->base_reg) / map->reg_stride;
318 val = regcache_rbtree_get_register(rbnode, reg_tmp, 330 regcache_rbtree_set_register(map, rbnode, reg_tmp, value);
319 map->cache_word_size);
320 if (val == value)
321 return 0;
322 regcache_rbtree_set_register(rbnode, reg_tmp, value,
323 map->cache_word_size);
324 } else { 331 } else {
325 /* look for an adjacent register to the one we are about to add */ 332 /* look for an adjacent register to the one we are about to add */
326 for (node = rb_first(&rbtree_ctx->root); node; 333 for (node = rb_first(&rbtree_ctx->root); node;
@@ -337,9 +344,10 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
337 pos = i + 1; 344 pos = i + 1;
338 else 345 else
339 pos = i; 346 pos = i;
340 ret = regcache_rbtree_insert_to_block(rbnode_tmp, pos, 347 ret = regcache_rbtree_insert_to_block(map,
341 reg, value, 348 rbnode_tmp,
342 map->cache_word_size); 349 pos, reg,
350 value);
343 if (ret) 351 if (ret)
344 return ret; 352 return ret;
345 rbtree_ctx->cached_rbnode = rbnode_tmp; 353 rbtree_ctx->cached_rbnode = rbnode_tmp;
@@ -354,7 +362,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
354 rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL); 362 rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
355 if (!rbnode) 363 if (!rbnode)
356 return -ENOMEM; 364 return -ENOMEM;
357 rbnode->blklen = 1; 365 rbnode->blklen = sizeof(*rbnode);
358 rbnode->base_reg = reg; 366 rbnode->base_reg = reg;
359 rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size, 367 rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size,
360 GFP_KERNEL); 368 GFP_KERNEL);
@@ -362,7 +370,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
362 kfree(rbnode); 370 kfree(rbnode);
363 return -ENOMEM; 371 return -ENOMEM;
364 } 372 }
365 regcache_rbtree_set_register(rbnode, 0, value, map->cache_word_size); 373 regcache_rbtree_set_register(map, rbnode, 0, value);
366 regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); 374 regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode);
367 rbtree_ctx->cached_rbnode = rbnode; 375 rbtree_ctx->cached_rbnode = rbnode;
368 } 376 }
@@ -376,10 +384,8 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
376 struct regcache_rbtree_ctx *rbtree_ctx; 384 struct regcache_rbtree_ctx *rbtree_ctx;
377 struct rb_node *node; 385 struct rb_node *node;
378 struct regcache_rbtree_node *rbnode; 386 struct regcache_rbtree_node *rbnode;
379 unsigned int regtmp;
380 unsigned int val;
381 int ret; 387 int ret;
382 int i, base, end; 388 int base, end;
383 389
384 rbtree_ctx = map->cache; 390 rbtree_ctx = map->cache;
385 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { 391 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
@@ -402,27 +408,13 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
402 else 408 else
403 end = rbnode->blklen; 409 end = rbnode->blklen;
404 410
405 for (i = base; i < end; i++) { 411 ret = regcache_sync_block(map, rbnode->block, rbnode->base_reg,
406 regtmp = rbnode->base_reg + (i * map->reg_stride); 412 base, end);
407 val = regcache_rbtree_get_register(rbnode, i, 413 if (ret != 0)
408 map->cache_word_size); 414 return ret;
409
410 /* Is this the hardware default? If so skip. */
411 ret = regcache_lookup_reg(map, regtmp);
412 if (ret >= 0 && val == map->reg_defaults[ret].def)
413 continue;
414
415 map->cache_bypass = 1;
416 ret = _regmap_write(map, regtmp, val);
417 map->cache_bypass = 0;
418 if (ret)
419 return ret;
420 dev_dbg(map->dev, "Synced register %#x, value %#x\n",
421 regtmp, val);
422 }
423 } 415 }
424 416
425 return 0; 417 return regmap_async_complete(map);
426} 418}
427 419
428struct regcache_ops regcache_rbtree_ops = { 420struct regcache_ops regcache_rbtree_ops = {
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index e69ff3e4742c..75923f2396bd 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -45,8 +45,8 @@ static int regcache_hw_init(struct regmap *map)
45 tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); 45 tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL);
46 if (!tmp_buf) 46 if (!tmp_buf)
47 return -EINVAL; 47 return -EINVAL;
48 ret = regmap_bulk_read(map, 0, tmp_buf, 48 ret = regmap_raw_read(map, 0, tmp_buf,
49 map->num_reg_defaults_raw); 49 map->num_reg_defaults_raw);
50 map->cache_bypass = cache_bypass; 50 map->cache_bypass = cache_bypass;
51 if (ret < 0) { 51 if (ret < 0) {
52 kfree(tmp_buf); 52 kfree(tmp_buf);
@@ -58,8 +58,7 @@ static int regcache_hw_init(struct regmap *map)
58 58
59 /* calculate the size of reg_defaults */ 59 /* calculate the size of reg_defaults */
60 for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { 60 for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) {
61 val = regcache_get_val(map->reg_defaults_raw, 61 val = regcache_get_val(map, map->reg_defaults_raw, i);
62 i, map->cache_word_size);
63 if (regmap_volatile(map, i * map->reg_stride)) 62 if (regmap_volatile(map, i * map->reg_stride))
64 continue; 63 continue;
65 count++; 64 count++;
@@ -75,8 +74,7 @@ static int regcache_hw_init(struct regmap *map)
75 /* fill the reg_defaults */ 74 /* fill the reg_defaults */
76 map->num_reg_defaults = count; 75 map->num_reg_defaults = count;
77 for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { 76 for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
78 val = regcache_get_val(map->reg_defaults_raw, 77 val = regcache_get_val(map, map->reg_defaults_raw, i);
79 i, map->cache_word_size);
80 if (regmap_volatile(map, i * map->reg_stride)) 78 if (regmap_volatile(map, i * map->reg_stride))
81 continue; 79 continue;
82 map->reg_defaults[j].reg = i * map->reg_stride; 80 map->reg_defaults[j].reg = i * map->reg_stride;
@@ -123,6 +121,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
123 map->reg_defaults_raw = config->reg_defaults_raw; 121 map->reg_defaults_raw = config->reg_defaults_raw;
124 map->cache_word_size = DIV_ROUND_UP(config->val_bits, 8); 122 map->cache_word_size = DIV_ROUND_UP(config->val_bits, 8);
125 map->cache_size_raw = map->cache_word_size * config->num_reg_defaults_raw; 123 map->cache_size_raw = map->cache_word_size * config->num_reg_defaults_raw;
124 map->cache_present = NULL;
125 map->cache_present_nbits = 0;
126 126
127 map->cache = NULL; 127 map->cache = NULL;
128 map->cache_ops = cache_types[i]; 128 map->cache_ops = cache_types[i];
@@ -181,6 +181,7 @@ void regcache_exit(struct regmap *map)
181 181
182 BUG_ON(!map->cache_ops); 182 BUG_ON(!map->cache_ops);
183 183
184 kfree(map->cache_present);
184 kfree(map->reg_defaults); 185 kfree(map->reg_defaults);
185 if (map->cache_free) 186 if (map->cache_free)
186 kfree(map->reg_defaults_raw); 187 kfree(map->reg_defaults_raw);
@@ -417,28 +418,68 @@ void regcache_cache_bypass(struct regmap *map, bool enable)
417} 418}
418EXPORT_SYMBOL_GPL(regcache_cache_bypass); 419EXPORT_SYMBOL_GPL(regcache_cache_bypass);
419 420
420bool regcache_set_val(void *base, unsigned int idx, 421int regcache_set_reg_present(struct regmap *map, unsigned int reg)
421 unsigned int val, unsigned int word_size)
422{ 422{
423 switch (word_size) { 423 unsigned long *cache_present;
424 unsigned int cache_present_size;
425 unsigned int nregs;
426 int i;
427
428 nregs = reg + 1;
429 cache_present_size = BITS_TO_LONGS(nregs);
430 cache_present_size *= sizeof(long);
431
432 if (!map->cache_present) {
433 cache_present = kmalloc(cache_present_size, GFP_KERNEL);
434 if (!cache_present)
435 return -ENOMEM;
436 bitmap_zero(cache_present, nregs);
437 map->cache_present = cache_present;
438 map->cache_present_nbits = nregs;
439 }
440
441 if (nregs > map->cache_present_nbits) {
442 cache_present = krealloc(map->cache_present,
443 cache_present_size, GFP_KERNEL);
444 if (!cache_present)
445 return -ENOMEM;
446 for (i = 0; i < nregs; i++)
447 if (i >= map->cache_present_nbits)
448 clear_bit(i, cache_present);
449 map->cache_present = cache_present;
450 map->cache_present_nbits = nregs;
451 }
452
453 set_bit(reg, map->cache_present);
454 return 0;
455}
456
457bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
458 unsigned int val)
459{
460 if (regcache_get_val(map, base, idx) == val)
461 return true;
462
463 /* Use device native format if possible */
464 if (map->format.format_val) {
465 map->format.format_val(base + (map->cache_word_size * idx),
466 val, 0);
467 return false;
468 }
469
470 switch (map->cache_word_size) {
424 case 1: { 471 case 1: {
425 u8 *cache = base; 472 u8 *cache = base;
426 if (cache[idx] == val)
427 return true;
428 cache[idx] = val; 473 cache[idx] = val;
429 break; 474 break;
430 } 475 }
431 case 2: { 476 case 2: {
432 u16 *cache = base; 477 u16 *cache = base;
433 if (cache[idx] == val)
434 return true;
435 cache[idx] = val; 478 cache[idx] = val;
436 break; 479 break;
437 } 480 }
438 case 4: { 481 case 4: {
439 u32 *cache = base; 482 u32 *cache = base;
440 if (cache[idx] == val)
441 return true;
442 cache[idx] = val; 483 cache[idx] = val;
443 break; 484 break;
444 } 485 }
@@ -448,13 +489,18 @@ bool regcache_set_val(void *base, unsigned int idx,
448 return false; 489 return false;
449} 490}
450 491
451unsigned int regcache_get_val(const void *base, unsigned int idx, 492unsigned int regcache_get_val(struct regmap *map, const void *base,
452 unsigned int word_size) 493 unsigned int idx)
453{ 494{
454 if (!base) 495 if (!base)
455 return -EINVAL; 496 return -EINVAL;
456 497
457 switch (word_size) { 498 /* Use device native format if possible */
499 if (map->format.parse_val)
500 return map->format.parse_val(regcache_get_val_addr(map, base,
501 idx));
502
503 switch (map->cache_word_size) {
458 case 1: { 504 case 1: {
459 const u8 *cache = base; 505 const u8 *cache = base;
460 return cache[idx]; 506 return cache[idx];
@@ -498,3 +544,117 @@ int regcache_lookup_reg(struct regmap *map, unsigned int reg)
498 else 544 else
499 return -ENOENT; 545 return -ENOENT;
500} 546}
547
548static int regcache_sync_block_single(struct regmap *map, void *block,
549 unsigned int block_base,
550 unsigned int start, unsigned int end)
551{
552 unsigned int i, regtmp, val;
553 int ret;
554
555 for (i = start; i < end; i++) {
556 regtmp = block_base + (i * map->reg_stride);
557
558 if (!regcache_reg_present(map, regtmp))
559 continue;
560
561 val = regcache_get_val(map, block, i);
562
563 /* Is this the hardware default? If so skip. */
564 ret = regcache_lookup_reg(map, regtmp);
565 if (ret >= 0 && val == map->reg_defaults[ret].def)
566 continue;
567
568 map->cache_bypass = 1;
569
570 ret = _regmap_write(map, regtmp, val);
571
572 map->cache_bypass = 0;
573 if (ret != 0)
574 return ret;
575 dev_dbg(map->dev, "Synced register %#x, value %#x\n",
576 regtmp, val);
577 }
578
579 return 0;
580}
581
582static int regcache_sync_block_raw_flush(struct regmap *map, const void **data,
583 unsigned int base, unsigned int cur)
584{
585 size_t val_bytes = map->format.val_bytes;
586 int ret, count;
587
588 if (*data == NULL)
589 return 0;
590
591 count = cur - base;
592
593 dev_dbg(map->dev, "Writing %zu bytes for %d registers from 0x%x-0x%x\n",
594 count * val_bytes, count, base, cur - 1);
595
596 map->cache_bypass = 1;
597
598 ret = _regmap_raw_write(map, base, *data, count * val_bytes,
599 false);
600
601 map->cache_bypass = 0;
602
603 *data = NULL;
604
605 return ret;
606}
607
608static int regcache_sync_block_raw(struct regmap *map, void *block,
609 unsigned int block_base, unsigned int start,
610 unsigned int end)
611{
612 unsigned int i, val;
613 unsigned int regtmp = 0;
614 unsigned int base = 0;
615 const void *data = NULL;
616 int ret;
617
618 for (i = start; i < end; i++) {
619 regtmp = block_base + (i * map->reg_stride);
620
621 if (!regcache_reg_present(map, regtmp)) {
622 ret = regcache_sync_block_raw_flush(map, &data,
623 base, regtmp);
624 if (ret != 0)
625 return ret;
626 continue;
627 }
628
629 val = regcache_get_val(map, block, i);
630
631 /* Is this the hardware default? If so skip. */
632 ret = regcache_lookup_reg(map, regtmp);
633 if (ret >= 0 && val == map->reg_defaults[ret].def) {
634 ret = regcache_sync_block_raw_flush(map, &data,
635 base, regtmp);
636 if (ret != 0)
637 return ret;
638 continue;
639 }
640
641 if (!data) {
642 data = regcache_get_val_addr(map, block, i);
643 base = regtmp;
644 }
645 }
646
647 return regcache_sync_block_raw_flush(map, &data, base, regtmp);
648}
649
650int regcache_sync_block(struct regmap *map, void *block,
651 unsigned int block_base, unsigned int start,
652 unsigned int end)
653{
654 if (regmap_can_raw_write(map))
655 return regcache_sync_block_raw(map, block, block_base,
656 start, end);
657 else
658 return regcache_sync_block_single(map, block, block_base,
659 start, end);
660}
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 81d6f605c92e..23b701f5fd2f 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -88,16 +88,16 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
88 * 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
89 * linear scan each time. 89 * linear scan each time.
90 */ 90 */
91 mutex_lock(&map->cache_lock);
92 i = base;
91 if (list_empty(&map->debugfs_off_cache)) { 93 if (list_empty(&map->debugfs_off_cache)) {
92 for (i = base; i <= map->max_register; i += map->reg_stride) { 94 for (; i <= map->max_register; i += map->reg_stride) {
93 /* Skip unprinted registers, closing off cache entry */ 95 /* Skip unprinted registers, closing off cache entry */
94 if (!regmap_readable(map, i) || 96 if (!regmap_readable(map, i) ||
95 regmap_precious(map, i)) { 97 regmap_precious(map, i)) {
96 if (c) { 98 if (c) {
97 c->max = p - 1; 99 c->max = p - 1;
98 fpos_offset = c->max - c->min; 100 c->max_reg = i - map->reg_stride;
99 reg_offset = fpos_offset / map->debugfs_tot_len;
100 c->max_reg = c->base_reg + reg_offset;
101 list_add_tail(&c->list, 101 list_add_tail(&c->list,
102 &map->debugfs_off_cache); 102 &map->debugfs_off_cache);
103 c = NULL; 103 c = NULL;
@@ -111,6 +111,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
111 c = kzalloc(sizeof(*c), GFP_KERNEL); 111 c = kzalloc(sizeof(*c), GFP_KERNEL);
112 if (!c) { 112 if (!c) {
113 regmap_debugfs_free_dump_cache(map); 113 regmap_debugfs_free_dump_cache(map);
114 mutex_unlock(&map->cache_lock);
114 return base; 115 return base;
115 } 116 }
116 c->min = p; 117 c->min = p;
@@ -124,9 +125,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
124 /* Close the last entry off if we didn't scan beyond it */ 125 /* Close the last entry off if we didn't scan beyond it */
125 if (c) { 126 if (c) {
126 c->max = p - 1; 127 c->max = p - 1;
127 fpos_offset = c->max - c->min; 128 c->max_reg = i - map->reg_stride;
128 reg_offset = fpos_offset / map->debugfs_tot_len;
129 c->max_reg = c->base_reg + reg_offset;
130 list_add_tail(&c->list, 129 list_add_tail(&c->list,
131 &map->debugfs_off_cache); 130 &map->debugfs_off_cache);
132 } 131 }
@@ -145,12 +144,14 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
145 fpos_offset = from - c->min; 144 fpos_offset = from - c->min;
146 reg_offset = fpos_offset / map->debugfs_tot_len; 145 reg_offset = fpos_offset / map->debugfs_tot_len;
147 *pos = c->min + (reg_offset * map->debugfs_tot_len); 146 *pos = c->min + (reg_offset * map->debugfs_tot_len);
147 mutex_unlock(&map->cache_lock);
148 return c->base_reg + reg_offset; 148 return c->base_reg + reg_offset;
149 } 149 }
150 150
151 *pos = c->max; 151 *pos = c->max;
152 ret = c->max_reg; 152 ret = c->max_reg;
153 } 153 }
154 mutex_unlock(&map->cache_lock);
154 155
155 return ret; 156 return ret;
156} 157}
@@ -311,6 +312,79 @@ static const struct file_operations regmap_range_fops = {
311 .llseek = default_llseek, 312 .llseek = default_llseek,
312}; 313};
313 314
315static ssize_t regmap_reg_ranges_read_file(struct file *file,
316 char __user *user_buf, size_t count,
317 loff_t *ppos)
318{
319 struct regmap *map = file->private_data;
320 struct regmap_debugfs_off_cache *c;
321 loff_t p = 0;
322 size_t buf_pos = 0;
323 char *buf;
324 char *entry;
325 int ret;
326
327 if (*ppos < 0 || !count)
328 return -EINVAL;
329
330 buf = kmalloc(count, GFP_KERNEL);
331 if (!buf)
332 return -ENOMEM;
333
334 entry = kmalloc(PAGE_SIZE, GFP_KERNEL);
335 if (!entry) {
336 kfree(buf);
337 return -ENOMEM;
338 }
339
340 /* While we are at it, build the register dump cache
341 * now so the read() operation on the `registers' file
342 * can benefit from using the cache. We do not care
343 * about the file position information that is contained
344 * in the cache, just about the actual register blocks */
345 regmap_calc_tot_len(map, buf, count);
346 regmap_debugfs_get_dump_start(map, 0, *ppos, &p);
347
348 /* Reset file pointer as the fixed-format of the `registers'
349 * file is not compatible with the `range' file */
350 p = 0;
351 mutex_lock(&map->cache_lock);
352 list_for_each_entry(c, &map->debugfs_off_cache, list) {
353 snprintf(entry, PAGE_SIZE, "%x-%x",
354 c->base_reg, c->max_reg);
355 if (p >= *ppos) {
356 if (buf_pos + 1 + strlen(entry) > count)
357 break;
358 snprintf(buf + buf_pos, count - buf_pos,
359 "%s", entry);
360 buf_pos += strlen(entry);
361 buf[buf_pos] = '\n';
362 buf_pos++;
363 }
364 p += strlen(entry) + 1;
365 }
366 mutex_unlock(&map->cache_lock);
367
368 kfree(entry);
369 ret = buf_pos;
370
371 if (copy_to_user(user_buf, buf, buf_pos)) {
372 ret = -EFAULT;
373 goto out_buf;
374 }
375
376 *ppos += buf_pos;
377out_buf:
378 kfree(buf);
379 return ret;
380}
381
382static const struct file_operations regmap_reg_ranges_fops = {
383 .open = simple_open,
384 .read = regmap_reg_ranges_read_file,
385 .llseek = default_llseek,
386};
387
314static ssize_t regmap_access_read_file(struct file *file, 388static ssize_t regmap_access_read_file(struct file *file,
315 char __user *user_buf, size_t count, 389 char __user *user_buf, size_t count,
316 loff_t *ppos) 390 loff_t *ppos)
@@ -385,6 +459,7 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
385 struct regmap_range_node *range_node; 459 struct regmap_range_node *range_node;
386 460
387 INIT_LIST_HEAD(&map->debugfs_off_cache); 461 INIT_LIST_HEAD(&map->debugfs_off_cache);
462 mutex_init(&map->cache_lock);
388 463
389 if (name) { 464 if (name) {
390 map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", 465 map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
@@ -403,6 +478,9 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
403 debugfs_create_file("name", 0400, map->debugfs, 478 debugfs_create_file("name", 0400, map->debugfs,
404 map, &regmap_name_fops); 479 map, &regmap_name_fops);
405 480
481 debugfs_create_file("range", 0400, map->debugfs,
482 map, &regmap_reg_ranges_fops);
483
406 if (map->max_register) { 484 if (map->max_register) {
407 debugfs_create_file("registers", 0400, map->debugfs, 485 debugfs_create_file("registers", 0400, map->debugfs,
408 map, &regmap_map_fops); 486 map, &regmap_map_fops);
@@ -435,7 +513,9 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
435void regmap_debugfs_exit(struct regmap *map) 513void regmap_debugfs_exit(struct regmap *map)
436{ 514{
437 debugfs_remove_recursive(map->debugfs); 515 debugfs_remove_recursive(map->debugfs);
516 mutex_lock(&map->cache_lock);
438 regmap_debugfs_free_dump_cache(map); 517 regmap_debugfs_free_dump_cache(map);
518 mutex_unlock(&map->cache_lock);
439 kfree(map->debugfs_name); 519 kfree(map->debugfs_name);
440} 520}
441 521
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 020ea2b9fd2f..1643e889bafc 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -460,7 +460,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
460 ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags, 460 ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags,
461 chip->name, d); 461 chip->name, d);
462 if (ret != 0) { 462 if (ret != 0) {
463 dev_err(map->dev, "Failed to request IRQ %d: %d\n", irq, ret); 463 dev_err(map->dev, "Failed to request IRQ %d for %s: %d\n",
464 irq, chip->name, ret);
464 goto err_domain; 465 goto err_domain;
465 } 466 }
466 467
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 58cfb3232428..a941dcfe7590 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -228,30 +228,39 @@ static void regmap_format_32_native(void *buf, unsigned int val,
228 *(u32 *)buf = val << shift; 228 *(u32 *)buf = val << shift;
229} 229}
230 230
231static unsigned int regmap_parse_8(void *buf) 231static void regmap_parse_inplace_noop(void *buf)
232{ 232{
233 u8 *b = buf; 233}
234
235static unsigned int regmap_parse_8(const void *buf)
236{
237 const u8 *b = buf;
234 238
235 return b[0]; 239 return b[0];
236} 240}
237 241
238static unsigned int regmap_parse_16_be(void *buf) 242static unsigned int regmap_parse_16_be(const void *buf)
243{
244 const __be16 *b = buf;
245
246 return be16_to_cpu(b[0]);
247}
248
249static void regmap_parse_16_be_inplace(void *buf)
239{ 250{
240 __be16 *b = buf; 251 __be16 *b = buf;
241 252
242 b[0] = be16_to_cpu(b[0]); 253 b[0] = be16_to_cpu(b[0]);
243
244 return b[0];
245} 254}
246 255
247static unsigned int regmap_parse_16_native(void *buf) 256static unsigned int regmap_parse_16_native(const void *buf)
248{ 257{
249 return *(u16 *)buf; 258 return *(u16 *)buf;
250} 259}
251 260
252static unsigned int regmap_parse_24(void *buf) 261static unsigned int regmap_parse_24(const void *buf)
253{ 262{
254 u8 *b = buf; 263 const u8 *b = buf;
255 unsigned int ret = b[2]; 264 unsigned int ret = b[2];
256 ret |= ((unsigned int)b[1]) << 8; 265 ret |= ((unsigned int)b[1]) << 8;
257 ret |= ((unsigned int)b[0]) << 16; 266 ret |= ((unsigned int)b[0]) << 16;
@@ -259,16 +268,21 @@ static unsigned int regmap_parse_24(void *buf)
259 return ret; 268 return ret;
260} 269}
261 270
262static unsigned int regmap_parse_32_be(void *buf) 271static unsigned int regmap_parse_32_be(const void *buf)
272{
273 const __be32 *b = buf;
274
275 return be32_to_cpu(b[0]);
276}
277
278static void regmap_parse_32_be_inplace(void *buf)
263{ 279{
264 __be32 *b = buf; 280 __be32 *b = buf;
265 281
266 b[0] = be32_to_cpu(b[0]); 282 b[0] = be32_to_cpu(b[0]);
267
268 return b[0];
269} 283}
270 284
271static unsigned int regmap_parse_32_native(void *buf) 285static unsigned int regmap_parse_32_native(const void *buf)
272{ 286{
273 return *(u32 *)buf; 287 return *(u32 *)buf;
274} 288}
@@ -555,16 +569,21 @@ struct regmap *regmap_init(struct device *dev,
555 goto err_map; 569 goto err_map;
556 } 570 }
557 571
572 if (val_endian == REGMAP_ENDIAN_NATIVE)
573 map->format.parse_inplace = regmap_parse_inplace_noop;
574
558 switch (config->val_bits) { 575 switch (config->val_bits) {
559 case 8: 576 case 8:
560 map->format.format_val = regmap_format_8; 577 map->format.format_val = regmap_format_8;
561 map->format.parse_val = regmap_parse_8; 578 map->format.parse_val = regmap_parse_8;
579 map->format.parse_inplace = regmap_parse_inplace_noop;
562 break; 580 break;
563 case 16: 581 case 16:
564 switch (val_endian) { 582 switch (val_endian) {
565 case REGMAP_ENDIAN_BIG: 583 case REGMAP_ENDIAN_BIG:
566 map->format.format_val = regmap_format_16_be; 584 map->format.format_val = regmap_format_16_be;
567 map->format.parse_val = regmap_parse_16_be; 585 map->format.parse_val = regmap_parse_16_be;
586 map->format.parse_inplace = regmap_parse_16_be_inplace;
568 break; 587 break;
569 case REGMAP_ENDIAN_NATIVE: 588 case REGMAP_ENDIAN_NATIVE:
570 map->format.format_val = regmap_format_16_native; 589 map->format.format_val = regmap_format_16_native;
@@ -585,6 +604,7 @@ struct regmap *regmap_init(struct device *dev,
585 case REGMAP_ENDIAN_BIG: 604 case REGMAP_ENDIAN_BIG:
586 map->format.format_val = regmap_format_32_be; 605 map->format.format_val = regmap_format_32_be;
587 map->format.parse_val = regmap_parse_32_be; 606 map->format.parse_val = regmap_parse_32_be;
607 map->format.parse_inplace = regmap_parse_32_be_inplace;
588 break; 608 break;
589 case REGMAP_ENDIAN_NATIVE: 609 case REGMAP_ENDIAN_NATIVE:
590 map->format.format_val = regmap_format_32_native; 610 map->format.format_val = regmap_format_32_native;
@@ -917,8 +937,8 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
917 return 0; 937 return 0;
918} 938}
919 939
920static int _regmap_raw_write(struct regmap *map, unsigned int reg, 940int _regmap_raw_write(struct regmap *map, unsigned int reg,
921 const void *val, size_t val_len, bool async) 941 const void *val, size_t val_len, bool async)
922{ 942{
923 struct regmap_range_node *range; 943 struct regmap_range_node *range;
924 unsigned long flags; 944 unsigned long flags;
@@ -930,7 +950,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
930 size_t len; 950 size_t len;
931 int i; 951 int i;
932 952
933 BUG_ON(!map->bus); 953 WARN_ON(!map->bus);
934 954
935 /* Check for unwritable registers before we start */ 955 /* Check for unwritable registers before we start */
936 if (map->writeable_reg) 956 if (map->writeable_reg)
@@ -943,8 +963,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
943 unsigned int ival; 963 unsigned int ival;
944 int val_bytes = map->format.val_bytes; 964 int val_bytes = map->format.val_bytes;
945 for (i = 0; i < val_len / val_bytes; i++) { 965 for (i = 0; i < val_len / val_bytes; i++) {
946 memcpy(map->work_buf, val + (i * val_bytes), val_bytes); 966 ival = map->format.parse_val(val + (i * val_bytes));
947 ival = map->format.parse_val(map->work_buf);
948 ret = regcache_write(map, reg + (i * map->reg_stride), 967 ret = regcache_write(map, reg + (i * map->reg_stride),
949 ival); 968 ival);
950 if (ret) { 969 if (ret) {
@@ -999,6 +1018,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
999 if (!async) 1018 if (!async)
1000 return -ENOMEM; 1019 return -ENOMEM;
1001 1020
1021 trace_regmap_async_write_start(map->dev, reg, val_len);
1022
1002 async->work_buf = kzalloc(map->format.buf_size, 1023 async->work_buf = kzalloc(map->format.buf_size,
1003 GFP_KERNEL | GFP_DMA); 1024 GFP_KERNEL | GFP_DMA);
1004 if (!async->work_buf) { 1025 if (!async->work_buf) {
@@ -1079,6 +1100,17 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
1079 return ret; 1100 return ret;
1080} 1101}
1081 1102
1103/**
1104 * regmap_can_raw_write - Test if regmap_raw_write() is supported
1105 *
1106 * @map: Map to check.
1107 */
1108bool regmap_can_raw_write(struct regmap *map)
1109{
1110 return map->bus && map->format.format_val && map->format.format_reg;
1111}
1112EXPORT_SYMBOL_GPL(regmap_can_raw_write);
1113
1082static int _regmap_bus_formatted_write(void *context, unsigned int reg, 1114static int _regmap_bus_formatted_write(void *context, unsigned int reg,
1083 unsigned int val) 1115 unsigned int val)
1084{ 1116{
@@ -1086,7 +1118,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
1086 struct regmap_range_node *range; 1118 struct regmap_range_node *range;
1087 struct regmap *map = context; 1119 struct regmap *map = context;
1088 1120
1089 BUG_ON(!map->bus || !map->format.format_write); 1121 WARN_ON(!map->bus || !map->format.format_write);
1090 1122
1091 range = _regmap_range_lookup(map, reg); 1123 range = _regmap_range_lookup(map, reg);
1092 if (range) { 1124 if (range) {
@@ -1112,7 +1144,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
1112{ 1144{
1113 struct regmap *map = context; 1145 struct regmap *map = context;
1114 1146
1115 BUG_ON(!map->bus || !map->format.format_val); 1147 WARN_ON(!map->bus || !map->format.format_val);
1116 1148
1117 map->format.format_val(map->work_buf + map->format.reg_bytes 1149 map->format.format_val(map->work_buf + map->format.reg_bytes
1118 + map->format.pad_bytes, val, 0); 1150 + map->format.pad_bytes, val, 0);
@@ -1202,12 +1234,10 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
1202{ 1234{
1203 int ret; 1235 int ret;
1204 1236
1205 if (!map->bus) 1237 if (!regmap_can_raw_write(map))
1206 return -EINVAL; 1238 return -EINVAL;
1207 if (val_len % map->format.val_bytes) 1239 if (val_len % map->format.val_bytes)
1208 return -EINVAL; 1240 return -EINVAL;
1209 if (reg % map->reg_stride)
1210 return -EINVAL;
1211 1241
1212 map->lock(map->lock_arg); 1242 map->lock(map->lock_arg);
1213 1243
@@ -1242,7 +1272,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1242 1272
1243 if (!map->bus) 1273 if (!map->bus)
1244 return -EINVAL; 1274 return -EINVAL;
1245 if (!map->format.parse_val) 1275 if (!map->format.parse_inplace)
1246 return -EINVAL; 1276 return -EINVAL;
1247 if (reg % map->reg_stride) 1277 if (reg % map->reg_stride)
1248 return -EINVAL; 1278 return -EINVAL;
@@ -1260,7 +1290,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1260 goto out; 1290 goto out;
1261 } 1291 }
1262 for (i = 0; i < val_count * val_bytes; i += val_bytes) 1292 for (i = 0; i < val_count * val_bytes; i += val_bytes)
1263 map->format.parse_val(wval + i); 1293 map->format.parse_inplace(wval + i);
1264 } 1294 }
1265 /* 1295 /*
1266 * Some devices does not support bulk write, for 1296 * Some devices does not support bulk write, for
@@ -1338,7 +1368,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1338 u8 *u8 = map->work_buf; 1368 u8 *u8 = map->work_buf;
1339 int ret; 1369 int ret;
1340 1370
1341 BUG_ON(!map->bus); 1371 WARN_ON(!map->bus);
1342 1372
1343 range = _regmap_range_lookup(map, reg); 1373 range = _regmap_range_lookup(map, reg);
1344 if (range) { 1374 if (range) {
@@ -1393,7 +1423,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
1393 int ret; 1423 int ret;
1394 void *context = _regmap_map_get_context(map); 1424 void *context = _regmap_map_get_context(map);
1395 1425
1396 BUG_ON(!map->reg_read); 1426 WARN_ON(!map->reg_read);
1397 1427
1398 if (!map->cache_bypass) { 1428 if (!map->cache_bypass) {
1399 ret = regcache_read(map, reg, val); 1429 ret = regcache_read(map, reg, val);
@@ -1521,7 +1551,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
1521 1551
1522 if (!map->bus) 1552 if (!map->bus)
1523 return -EINVAL; 1553 return -EINVAL;
1524 if (!map->format.parse_val) 1554 if (!map->format.parse_inplace)
1525 return -EINVAL; 1555 return -EINVAL;
1526 if (reg % map->reg_stride) 1556 if (reg % map->reg_stride)
1527 return -EINVAL; 1557 return -EINVAL;
@@ -1548,7 +1578,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
1548 } 1578 }
1549 1579
1550 for (i = 0; i < val_count * val_bytes; i += val_bytes) 1580 for (i = 0; i < val_count * val_bytes; i += val_bytes)
1551 map->format.parse_val(val + i); 1581 map->format.parse_inplace(val + i);
1552 } else { 1582 } else {
1553 for (i = 0; i < val_count; i++) { 1583 for (i = 0; i < val_count; i++) {
1554 unsigned int ival; 1584 unsigned int ival;
@@ -1642,6 +1672,8 @@ void regmap_async_complete_cb(struct regmap_async *async, int ret)
1642 struct regmap *map = async->map; 1672 struct regmap *map = async->map;
1643 bool wake; 1673 bool wake;
1644 1674
1675 trace_regmap_async_io_complete(map->dev);
1676
1645 spin_lock(&map->async_lock); 1677 spin_lock(&map->async_lock);
1646 1678
1647 list_del(&async->list); 1679 list_del(&async->list);
@@ -1688,6 +1720,8 @@ int regmap_async_complete(struct regmap *map)
1688 if (!map->bus->async_write) 1720 if (!map->bus->async_write)
1689 return 0; 1721 return 0;
1690 1722
1723 trace_regmap_async_complete_start(map->dev);
1724
1691 wait_event(map->async_waitq, regmap_async_is_done(map)); 1725 wait_event(map->async_waitq, regmap_async_is_done(map));
1692 1726
1693 spin_lock_irqsave(&map->async_lock, flags); 1727 spin_lock_irqsave(&map->async_lock, flags);
@@ -1695,6 +1729,8 @@ int regmap_async_complete(struct regmap *map)
1695 map->async_ret = 0; 1729 map->async_ret = 0;
1696 spin_unlock_irqrestore(&map->async_lock, flags); 1730 spin_unlock_irqrestore(&map->async_lock, flags);
1697 1731
1732 trace_regmap_async_complete_done(map->dev);
1733
1698 return ret; 1734 return ret;
1699} 1735}
1700EXPORT_SYMBOL_GPL(regmap_async_complete); 1736EXPORT_SYMBOL_GPL(regmap_async_complete);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index bf77dfdabef9..02d84e24b7c2 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -389,6 +389,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
389 bool *change); 389 bool *change);
390int regmap_get_val_bytes(struct regmap *map); 390int regmap_get_val_bytes(struct regmap *map);
391int regmap_async_complete(struct regmap *map); 391int regmap_async_complete(struct regmap *map);
392bool regmap_can_raw_write(struct regmap *map);
392 393
393int regcache_sync(struct regmap *map); 394int regcache_sync(struct regmap *map);
394int regcache_sync_region(struct regmap *map, unsigned int min, 395int regcache_sync_region(struct regmap *map, unsigned int min,
diff --git a/include/trace/events/regmap.h b/include/trace/events/regmap.h
index 41a7dbd570e2..a43a2f67bd8e 100644
--- a/include/trace/events/regmap.h
+++ b/include/trace/events/regmap.h
@@ -175,6 +175,54 @@ DEFINE_EVENT(regmap_bool, regmap_cache_bypass,
175 175
176); 176);
177 177
178DECLARE_EVENT_CLASS(regmap_async,
179
180 TP_PROTO(struct device *dev),
181
182 TP_ARGS(dev),
183
184 TP_STRUCT__entry(
185 __string( name, dev_name(dev) )
186 ),
187
188 TP_fast_assign(
189 __assign_str(name, dev_name(dev));
190 ),
191
192 TP_printk("%s", __get_str(name))
193);
194
195DEFINE_EVENT(regmap_block, regmap_async_write_start,
196
197 TP_PROTO(struct device *dev, unsigned int reg, int count),
198
199 TP_ARGS(dev, reg, count)
200);
201
202DEFINE_EVENT(regmap_async, regmap_async_io_complete,
203
204 TP_PROTO(struct device *dev),
205
206 TP_ARGS(dev)
207
208);
209
210DEFINE_EVENT(regmap_async, regmap_async_complete_start,
211
212 TP_PROTO(struct device *dev),
213
214 TP_ARGS(dev)
215
216);
217
218DEFINE_EVENT(regmap_async, regmap_async_complete_done,
219
220 TP_PROTO(struct device *dev),
221
222 TP_ARGS(dev)
223
224);
225
178#endif /* _TRACE_REGMAP_H */ 226#endif /* _TRACE_REGMAP_H */
179 227
180/* This part must be outside protection */ 228/* This part must be outside protection */