aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 13:07:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 13:07:40 -0400
commit8243b7f5dc1dced123145566291015704f2b4ba7 (patch)
treefb055c876bb35f90632dbef3563173436e736ec5 /drivers/base
parentfc6d0b037678f50014ef409c92c5bedc01208fcd (diff)
parent365c9ee0731de96046cc7749b46a5e7a0b0ceb65 (diff)
Merge tag 'regmap-v3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown: "A quiet release for regmap, some cleanups, fixes and: - Improved node coalescing for rbtree, reducing memory usage and improving performance during syncs. - Support for registering multiple register patches. - A quirk for handling interrupts that need to be clear when masked in regmap-irq" * tag 'regmap-v3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regmap: rbtree: Make cache_present bitmap per node regmap: rbtree: Reduce number of nodes, take 2 regmap: rbtree: Simplify adjacent node look-up regmap: debugfs: Fix continued read from registers file regcache-rbtree: Fix reg_stride != 1 regmap: Allow multiple patches to be registered regmap: regcache: allow read-only regs to be cached regmap: fix regcache_reg_present() for empty cache regmap: core: allow a virtual range to cover its own data window regmap: irq: document mask/wake_invert flags regmap: irq: make flags bool and put them in a bitfield regmap: irq: Allow to acknowledge masked interrupts during initialization regmap: Provide __acquires/__releases annotations
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/internal.h14
-rw-r--r--drivers/base/regmap/regcache-rbtree.c181
-rw-r--r--drivers/base/regmap/regcache.c75
-rw-r--r--drivers/base/regmap/regmap-debugfs.c4
-rw-r--r--drivers/base/regmap/regmap-irq.c25
-rw-r--r--drivers/base/regmap/regmap.c26
6 files changed, 194 insertions, 131 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 29c83160ca29..57f777835d97 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -128,9 +128,6 @@ struct regmap {
128 void *cache; 128 void *cache;
129 u32 cache_dirty; 129 u32 cache_dirty;
130 130
131 unsigned long *cache_present;
132 unsigned int cache_present_nbits;
133
134 struct reg_default *patch; 131 struct reg_default *patch;
135 int patch_regs; 132 int patch_regs;
136 133
@@ -203,6 +200,7 @@ int regcache_write(struct regmap *map,
203 unsigned int reg, unsigned int value); 200 unsigned int reg, unsigned int value);
204int regcache_sync(struct regmap *map); 201int regcache_sync(struct regmap *map);
205int regcache_sync_block(struct regmap *map, void *block, 202int regcache_sync_block(struct regmap *map, void *block,
203 unsigned long *cache_present,
206 unsigned int block_base, unsigned int start, 204 unsigned int block_base, unsigned int start,
207 unsigned int end); 205 unsigned int end);
208 206
@@ -218,16 +216,6 @@ unsigned int regcache_get_val(struct regmap *map, const void *base,
218bool regcache_set_val(struct regmap *map, void *base, unsigned int idx, 216bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
219 unsigned int val); 217 unsigned int val);
220int regcache_lookup_reg(struct regmap *map, unsigned int reg); 218int regcache_lookup_reg(struct regmap *map, unsigned int reg);
221int regcache_set_reg_present(struct regmap *map, unsigned int reg);
222
223static inline bool regcache_reg_present(struct regmap *map, unsigned int reg)
224{
225 if (!map->cache_present)
226 return true;
227 if (reg > map->cache_present_nbits)
228 return false;
229 return map->cache_present[BIT_WORD(reg)] & BIT_MASK(reg);
230}
231 219
232int _regmap_raw_write(struct regmap *map, unsigned int reg, 220int _regmap_raw_write(struct regmap *map, unsigned int reg,
233 const void *val, size_t val_len, bool async); 221 const void *val, size_t val_len, bool async);
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 0fccc99881fd..930cad4e5df8 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -29,6 +29,8 @@ struct regcache_rbtree_node {
29 unsigned int base_reg; 29 unsigned int base_reg;
30 /* block of adjacent registers */ 30 /* block of adjacent registers */
31 void *block; 31 void *block;
32 /* Which registers are present */
33 long *cache_present;
32 /* number of registers available in the block */ 34 /* number of registers available in the block */
33 unsigned int blklen; 35 unsigned int blklen;
34} __attribute__ ((packed)); 36} __attribute__ ((packed));
@@ -57,6 +59,7 @@ static void regcache_rbtree_set_register(struct regmap *map,
57 struct regcache_rbtree_node *rbnode, 59 struct regcache_rbtree_node *rbnode,
58 unsigned int idx, unsigned int val) 60 unsigned int idx, unsigned int val)
59{ 61{
62 set_bit(idx, rbnode->cache_present);
60 regcache_set_val(map, rbnode->block, idx, val); 63 regcache_set_val(map, rbnode->block, idx, val);
61} 64}
62 65
@@ -146,13 +149,13 @@ static int rbtree_show(struct seq_file *s, void *ignored)
146 map->lock(map->lock_arg); 149 map->lock(map->lock_arg);
147 150
148 mem_size = sizeof(*rbtree_ctx); 151 mem_size = sizeof(*rbtree_ctx);
149 mem_size += BITS_TO_LONGS(map->cache_present_nbits) * sizeof(long);
150 152
151 for (node = rb_first(&rbtree_ctx->root); node != NULL; 153 for (node = rb_first(&rbtree_ctx->root); node != NULL;
152 node = rb_next(node)) { 154 node = rb_next(node)) {
153 n = container_of(node, struct regcache_rbtree_node, node); 155 n = container_of(node, struct regcache_rbtree_node, node);
154 mem_size += sizeof(*n); 156 mem_size += sizeof(*n);
155 mem_size += (n->blklen * map->cache_word_size); 157 mem_size += (n->blklen * map->cache_word_size);
158 mem_size += BITS_TO_LONGS(n->blklen) * sizeof(long);
156 159
157 regcache_rbtree_get_base_top_reg(map, n, &base, &top); 160 regcache_rbtree_get_base_top_reg(map, n, &base, &top);
158 this_registers = ((top - base) / map->reg_stride) + 1; 161 this_registers = ((top - base) / map->reg_stride) + 1;
@@ -245,6 +248,7 @@ static int regcache_rbtree_exit(struct regmap *map)
245 rbtree_node = rb_entry(next, struct regcache_rbtree_node, node); 248 rbtree_node = rb_entry(next, struct regcache_rbtree_node, node);
246 next = rb_next(&rbtree_node->node); 249 next = rb_next(&rbtree_node->node);
247 rb_erase(&rbtree_node->node, &rbtree_ctx->root); 250 rb_erase(&rbtree_node->node, &rbtree_ctx->root);
251 kfree(rbtree_node->cache_present);
248 kfree(rbtree_node->block); 252 kfree(rbtree_node->block);
249 kfree(rbtree_node); 253 kfree(rbtree_node);
250 } 254 }
@@ -265,7 +269,7 @@ static int regcache_rbtree_read(struct regmap *map,
265 rbnode = regcache_rbtree_lookup(map, reg); 269 rbnode = regcache_rbtree_lookup(map, reg);
266 if (rbnode) { 270 if (rbnode) {
267 reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; 271 reg_tmp = (reg - rbnode->base_reg) / map->reg_stride;
268 if (!regcache_reg_present(map, reg)) 272 if (!test_bit(reg_tmp, rbnode->cache_present))
269 return -ENOENT; 273 return -ENOENT;
270 *value = regcache_rbtree_get_register(map, rbnode, reg_tmp); 274 *value = regcache_rbtree_get_register(map, rbnode, reg_tmp);
271 } else { 275 } else {
@@ -278,27 +282,45 @@ static int regcache_rbtree_read(struct regmap *map,
278 282
279static int regcache_rbtree_insert_to_block(struct regmap *map, 283static int regcache_rbtree_insert_to_block(struct regmap *map,
280 struct regcache_rbtree_node *rbnode, 284 struct regcache_rbtree_node *rbnode,
281 unsigned int pos, unsigned int reg, 285 unsigned int base_reg,
286 unsigned int top_reg,
287 unsigned int reg,
282 unsigned int value) 288 unsigned int value)
283{ 289{
290 unsigned int blklen;
291 unsigned int pos, offset;
292 unsigned long *present;
284 u8 *blk; 293 u8 *blk;
285 294
295 blklen = (top_reg - base_reg) / map->reg_stride + 1;
296 pos = (reg - base_reg) / map->reg_stride;
297 offset = (rbnode->base_reg - base_reg) / map->reg_stride;
298
286 blk = krealloc(rbnode->block, 299 blk = krealloc(rbnode->block,
287 (rbnode->blklen + 1) * map->cache_word_size, 300 blklen * map->cache_word_size,
288 GFP_KERNEL); 301 GFP_KERNEL);
289 if (!blk) 302 if (!blk)
290 return -ENOMEM; 303 return -ENOMEM;
291 304
305 present = krealloc(rbnode->cache_present,
306 BITS_TO_LONGS(blklen) * sizeof(*present), GFP_KERNEL);
307 if (!present) {
308 kfree(blk);
309 return -ENOMEM;
310 }
311
292 /* insert the register value in the correct place in the rbnode block */ 312 /* insert the register value in the correct place in the rbnode block */
293 memmove(blk + (pos + 1) * map->cache_word_size, 313 if (pos == 0) {
294 blk + pos * map->cache_word_size, 314 memmove(blk + offset * map->cache_word_size,
295 (rbnode->blklen - pos) * map->cache_word_size); 315 blk, rbnode->blklen * map->cache_word_size);
316 bitmap_shift_right(present, present, offset, blklen);
317 }
296 318
297 /* update the rbnode block, its size and the base register */ 319 /* update the rbnode block, its size and the base register */
298 rbnode->block = blk; 320 rbnode->block = blk;
299 rbnode->blklen++; 321 rbnode->blklen = blklen;
300 if (!pos) 322 rbnode->base_reg = base_reg;
301 rbnode->base_reg = reg; 323 rbnode->cache_present = present;
302 324
303 regcache_rbtree_set_register(map, rbnode, pos, value); 325 regcache_rbtree_set_register(map, rbnode, pos, value);
304 return 0; 326 return 0;
@@ -325,8 +347,8 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
325 347
326 if (i != map->rd_table->n_yes_ranges) { 348 if (i != map->rd_table->n_yes_ranges) {
327 range = &map->rd_table->yes_ranges[i]; 349 range = &map->rd_table->yes_ranges[i];
328 rbnode->blklen = range->range_max - range->range_min 350 rbnode->blklen = (range->range_max - range->range_min) /
329 + 1; 351 map->reg_stride + 1;
330 rbnode->base_reg = range->range_min; 352 rbnode->base_reg = range->range_min;
331 } 353 }
332 } 354 }
@@ -338,12 +360,21 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
338 360
339 rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size, 361 rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size,
340 GFP_KERNEL); 362 GFP_KERNEL);
341 if (!rbnode->block) { 363 if (!rbnode->block)
342 kfree(rbnode); 364 goto err_free;
343 return NULL; 365
344 } 366 rbnode->cache_present = kzalloc(BITS_TO_LONGS(rbnode->blklen) *
367 sizeof(*rbnode->cache_present), GFP_KERNEL);
368 if (!rbnode->cache_present)
369 goto err_free_block;
345 370
346 return rbnode; 371 return rbnode;
372
373err_free_block:
374 kfree(rbnode->block);
375err_free:
376 kfree(rbnode);
377 return NULL;
347} 378}
348 379
349static int regcache_rbtree_write(struct regmap *map, unsigned int reg, 380static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
@@ -353,15 +384,9 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
353 struct regcache_rbtree_node *rbnode, *rbnode_tmp; 384 struct regcache_rbtree_node *rbnode, *rbnode_tmp;
354 struct rb_node *node; 385 struct rb_node *node;
355 unsigned int reg_tmp; 386 unsigned int reg_tmp;
356 unsigned int pos;
357 int i;
358 int ret; 387 int ret;
359 388
360 rbtree_ctx = map->cache; 389 rbtree_ctx = map->cache;
361 /* update the reg_present bitmap, make space if necessary */
362 ret = regcache_set_reg_present(map, reg);
363 if (ret < 0)
364 return ret;
365 390
366 /* if we can't locate it in the cached rbnode we'll have 391 /* if we can't locate it in the cached rbnode we'll have
367 * to traverse the rbtree looking for it. 392 * to traverse the rbtree looking for it.
@@ -371,30 +396,43 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
371 reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; 396 reg_tmp = (reg - rbnode->base_reg) / map->reg_stride;
372 regcache_rbtree_set_register(map, rbnode, reg_tmp, value); 397 regcache_rbtree_set_register(map, rbnode, reg_tmp, value);
373 } else { 398 } else {
399 unsigned int base_reg, top_reg;
400 unsigned int new_base_reg, new_top_reg;
401 unsigned int min, max;
402 unsigned int max_dist;
403
404 max_dist = map->reg_stride * sizeof(*rbnode_tmp) /
405 map->cache_word_size;
406 if (reg < max_dist)
407 min = 0;
408 else
409 min = reg - max_dist;
410 max = reg + max_dist;
411
374 /* look for an adjacent register to the one we are about to add */ 412 /* look for an adjacent register to the one we are about to add */
375 for (node = rb_first(&rbtree_ctx->root); node; 413 for (node = rb_first(&rbtree_ctx->root); node;
376 node = rb_next(node)) { 414 node = rb_next(node)) {
377 rbnode_tmp = rb_entry(node, struct regcache_rbtree_node, 415 rbnode_tmp = rb_entry(node, struct regcache_rbtree_node,
378 node); 416 node);
379 for (i = 0; i < rbnode_tmp->blklen; i++) { 417
380 reg_tmp = rbnode_tmp->base_reg + 418 regcache_rbtree_get_base_top_reg(map, rbnode_tmp,
381 (i * map->reg_stride); 419 &base_reg, &top_reg);
382 if (abs(reg_tmp - reg) != map->reg_stride) 420
383 continue; 421 if (base_reg <= max && top_reg >= min) {
384 /* decide where in the block to place our register */ 422 new_base_reg = min(reg, base_reg);
385 if (reg_tmp + map->reg_stride == reg) 423 new_top_reg = max(reg, top_reg);
386 pos = i + 1; 424 } else {
387 else 425 continue;
388 pos = i;
389 ret = regcache_rbtree_insert_to_block(map,
390 rbnode_tmp,
391 pos, reg,
392 value);
393 if (ret)
394 return ret;
395 rbtree_ctx->cached_rbnode = rbnode_tmp;
396 return 0;
397 } 426 }
427
428 ret = regcache_rbtree_insert_to_block(map, rbnode_tmp,
429 new_base_reg,
430 new_top_reg, reg,
431 value);
432 if (ret)
433 return ret;
434 rbtree_ctx->cached_rbnode = rbnode_tmp;
435 return 0;
398 } 436 }
399 437
400 /* We did not manage to find a place to insert it in 438 /* We did not manage to find a place to insert it in
@@ -418,30 +456,34 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
418 struct regcache_rbtree_ctx *rbtree_ctx; 456 struct regcache_rbtree_ctx *rbtree_ctx;
419 struct rb_node *node; 457 struct rb_node *node;
420 struct regcache_rbtree_node *rbnode; 458 struct regcache_rbtree_node *rbnode;
459 unsigned int base_reg, top_reg;
460 unsigned int start, end;
421 int ret; 461 int ret;
422 int base, end;
423 462
424 rbtree_ctx = map->cache; 463 rbtree_ctx = map->cache;
425 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { 464 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
426 rbnode = rb_entry(node, struct regcache_rbtree_node, node); 465 rbnode = rb_entry(node, struct regcache_rbtree_node, node);
427 466
428 if (rbnode->base_reg > max) 467 regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg,
468 &top_reg);
469 if (base_reg > max)
429 break; 470 break;
430 if (rbnode->base_reg + rbnode->blklen < min) 471 if (top_reg < min)
431 continue; 472 continue;
432 473
433 if (min > rbnode->base_reg) 474 if (min > base_reg)
434 base = min - rbnode->base_reg; 475 start = (min - base_reg) / map->reg_stride;
435 else 476 else
436 base = 0; 477 start = 0;
437 478
438 if (max < rbnode->base_reg + rbnode->blklen) 479 if (max < top_reg)
439 end = max - rbnode->base_reg + 1; 480 end = (max - base_reg) / map->reg_stride + 1;
440 else 481 else
441 end = rbnode->blklen; 482 end = rbnode->blklen;
442 483
443 ret = regcache_sync_block(map, rbnode->block, rbnode->base_reg, 484 ret = regcache_sync_block(map, rbnode->block,
444 base, end); 485 rbnode->cache_present,
486 rbnode->base_reg, start, end);
445 if (ret != 0) 487 if (ret != 0)
446 return ret; 488 return ret;
447 } 489 }
@@ -449,6 +491,42 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
449 return regmap_async_complete(map); 491 return regmap_async_complete(map);
450} 492}
451 493
494static int regcache_rbtree_drop(struct regmap *map, unsigned int min,
495 unsigned int max)
496{
497 struct regcache_rbtree_ctx *rbtree_ctx;
498 struct regcache_rbtree_node *rbnode;
499 struct rb_node *node;
500 unsigned int base_reg, top_reg;
501 unsigned int start, end;
502
503 rbtree_ctx = map->cache;
504 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
505 rbnode = rb_entry(node, struct regcache_rbtree_node, node);
506
507 regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg,
508 &top_reg);
509 if (base_reg > max)
510 break;
511 if (top_reg < min)
512 continue;
513
514 if (min > base_reg)
515 start = (min - base_reg) / map->reg_stride;
516 else
517 start = 0;
518
519 if (max < top_reg)
520 end = (max - base_reg) / map->reg_stride + 1;
521 else
522 end = rbnode->blklen;
523
524 bitmap_clear(rbnode->cache_present, start, end - start);
525 }
526
527 return 0;
528}
529
452struct regcache_ops regcache_rbtree_ops = { 530struct regcache_ops regcache_rbtree_ops = {
453 .type = REGCACHE_RBTREE, 531 .type = REGCACHE_RBTREE,
454 .name = "rbtree", 532 .name = "rbtree",
@@ -456,5 +534,6 @@ struct regcache_ops regcache_rbtree_ops = {
456 .exit = regcache_rbtree_exit, 534 .exit = regcache_rbtree_exit,
457 .read = regcache_rbtree_read, 535 .read = regcache_rbtree_read,
458 .write = regcache_rbtree_write, 536 .write = regcache_rbtree_write,
459 .sync = regcache_rbtree_sync 537 .sync = regcache_rbtree_sync,
538 .drop = regcache_rbtree_drop,
460}; 539};
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 3455f833e473..d6c2d691b6e8 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -121,8 +121,6 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
121 map->reg_defaults_raw = config->reg_defaults_raw; 121 map->reg_defaults_raw = config->reg_defaults_raw;
122 map->cache_word_size = DIV_ROUND_UP(config->val_bits, 8); 122 map->cache_word_size = DIV_ROUND_UP(config->val_bits, 8);
123 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 124
127 map->cache = NULL; 125 map->cache = NULL;
128 map->cache_ops = cache_types[i]; 126 map->cache_ops = cache_types[i];
@@ -181,7 +179,6 @@ void regcache_exit(struct regmap *map)
181 179
182 BUG_ON(!map->cache_ops); 180 BUG_ON(!map->cache_ops);
183 181
184 kfree(map->cache_present);
185 kfree(map->reg_defaults); 182 kfree(map->reg_defaults);
186 if (map->cache_free) 183 if (map->cache_free)
187 kfree(map->reg_defaults_raw); 184 kfree(map->reg_defaults_raw);
@@ -241,9 +238,6 @@ int regcache_write(struct regmap *map,
241 238
242 BUG_ON(!map->cache_ops); 239 BUG_ON(!map->cache_ops);
243 240
244 if (!regmap_writeable(map, reg))
245 return -EIO;
246
247 if (!regmap_volatile(map, reg)) 241 if (!regmap_volatile(map, reg))
248 return map->cache_ops->write(map, reg, value); 242 return map->cache_ops->write(map, reg, value);
249 243
@@ -410,22 +404,16 @@ EXPORT_SYMBOL_GPL(regcache_sync_region);
410int regcache_drop_region(struct regmap *map, unsigned int min, 404int regcache_drop_region(struct regmap *map, unsigned int min,
411 unsigned int max) 405 unsigned int max)
412{ 406{
413 unsigned int reg;
414 int ret = 0; 407 int ret = 0;
415 408
416 if (!map->cache_present && !(map->cache_ops && map->cache_ops->drop)) 409 if (!map->cache_ops || !map->cache_ops->drop)
417 return -EINVAL; 410 return -EINVAL;
418 411
419 map->lock(map->lock_arg); 412 map->lock(map->lock_arg);
420 413
421 trace_regcache_drop_region(map->dev, min, max); 414 trace_regcache_drop_region(map->dev, min, max);
422 415
423 if (map->cache_present) 416 ret = map->cache_ops->drop(map, min, max);
424 for (reg = min; reg < max + 1; reg++)
425 clear_bit(reg, map->cache_present);
426
427 if (map->cache_ops && map->cache_ops->drop)
428 ret = map->cache_ops->drop(map, min, max);
429 417
430 map->unlock(map->lock_arg); 418 map->unlock(map->lock_arg);
431 419
@@ -493,42 +481,6 @@ void regcache_cache_bypass(struct regmap *map, bool enable)
493} 481}
494EXPORT_SYMBOL_GPL(regcache_cache_bypass); 482EXPORT_SYMBOL_GPL(regcache_cache_bypass);
495 483
496int regcache_set_reg_present(struct regmap *map, unsigned int reg)
497{
498 unsigned long *cache_present;
499 unsigned int cache_present_size;
500 unsigned int nregs;
501 int i;
502
503 nregs = reg + 1;
504 cache_present_size = BITS_TO_LONGS(nregs);
505 cache_present_size *= sizeof(long);
506
507 if (!map->cache_present) {
508 cache_present = kmalloc(cache_present_size, GFP_KERNEL);
509 if (!cache_present)
510 return -ENOMEM;
511 bitmap_zero(cache_present, nregs);
512 map->cache_present = cache_present;
513 map->cache_present_nbits = nregs;
514 }
515
516 if (nregs > map->cache_present_nbits) {
517 cache_present = krealloc(map->cache_present,
518 cache_present_size, GFP_KERNEL);
519 if (!cache_present)
520 return -ENOMEM;
521 for (i = 0; i < nregs; i++)
522 if (i >= map->cache_present_nbits)
523 clear_bit(i, cache_present);
524 map->cache_present = cache_present;
525 map->cache_present_nbits = nregs;
526 }
527
528 set_bit(reg, map->cache_present);
529 return 0;
530}
531
532bool regcache_set_val(struct regmap *map, void *base, unsigned int idx, 484bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
533 unsigned int val) 485 unsigned int val)
534{ 486{
@@ -620,7 +572,16 @@ int regcache_lookup_reg(struct regmap *map, unsigned int reg)
620 return -ENOENT; 572 return -ENOENT;
621} 573}
622 574
575static bool regcache_reg_present(unsigned long *cache_present, unsigned int idx)
576{
577 if (!cache_present)
578 return true;
579
580 return test_bit(idx, cache_present);
581}
582
623static int regcache_sync_block_single(struct regmap *map, void *block, 583static int regcache_sync_block_single(struct regmap *map, void *block,
584 unsigned long *cache_present,
624 unsigned int block_base, 585 unsigned int block_base,
625 unsigned int start, unsigned int end) 586 unsigned int start, unsigned int end)
626{ 587{
@@ -630,7 +591,7 @@ static int regcache_sync_block_single(struct regmap *map, void *block,
630 for (i = start; i < end; i++) { 591 for (i = start; i < end; i++) {
631 regtmp = block_base + (i * map->reg_stride); 592 regtmp = block_base + (i * map->reg_stride);
632 593
633 if (!regcache_reg_present(map, regtmp)) 594 if (!regcache_reg_present(cache_present, i))
634 continue; 595 continue;
635 596
636 val = regcache_get_val(map, block, i); 597 val = regcache_get_val(map, block, i);
@@ -681,6 +642,7 @@ static int regcache_sync_block_raw_flush(struct regmap *map, const void **data,
681} 642}
682 643
683static int regcache_sync_block_raw(struct regmap *map, void *block, 644static int regcache_sync_block_raw(struct regmap *map, void *block,
645 unsigned long *cache_present,
684 unsigned int block_base, unsigned int start, 646 unsigned int block_base, unsigned int start,
685 unsigned int end) 647 unsigned int end)
686{ 648{
@@ -693,7 +655,7 @@ static int regcache_sync_block_raw(struct regmap *map, void *block,
693 for (i = start; i < end; i++) { 655 for (i = start; i < end; i++) {
694 regtmp = block_base + (i * map->reg_stride); 656 regtmp = block_base + (i * map->reg_stride);
695 657
696 if (!regcache_reg_present(map, regtmp)) { 658 if (!regcache_reg_present(cache_present, i)) {
697 ret = regcache_sync_block_raw_flush(map, &data, 659 ret = regcache_sync_block_raw_flush(map, &data,
698 base, regtmp); 660 base, regtmp);
699 if (ret != 0) 661 if (ret != 0)
@@ -724,13 +686,14 @@ static int regcache_sync_block_raw(struct regmap *map, void *block,
724} 686}
725 687
726int regcache_sync_block(struct regmap *map, void *block, 688int regcache_sync_block(struct regmap *map, void *block,
689 unsigned long *cache_present,
727 unsigned int block_base, unsigned int start, 690 unsigned int block_base, unsigned int start,
728 unsigned int end) 691 unsigned int end)
729{ 692{
730 if (regmap_can_raw_write(map)) 693 if (regmap_can_raw_write(map))
731 return regcache_sync_block_raw(map, block, block_base, 694 return regcache_sync_block_raw(map, block, cache_present,
732 start, end); 695 block_base, start, end);
733 else 696 else
734 return regcache_sync_block_single(map, block, block_base, 697 return regcache_sync_block_single(map, block, cache_present,
735 start, end); 698 block_base, start, end);
736} 699}
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 53495753fbdb..6c2652a8ad50 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -85,8 +85,8 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
85 unsigned int reg_offset; 85 unsigned int reg_offset;
86 86
87 /* Suppress the cache if we're using a subrange */ 87 /* Suppress the cache if we're using a subrange */
88 if (from) 88 if (base)
89 return from; 89 return base;
90 90
91 /* 91 /*
92 * If we don't have a cache build one so we don't have to do a 92 * If we don't have a cache build one so we don't have to do a
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 1643e889bafc..d10456ffd811 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -418,6 +418,31 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
418 reg, ret); 418 reg, ret);
419 goto err_alloc; 419 goto err_alloc;
420 } 420 }
421
422 if (!chip->init_ack_masked)
423 continue;
424
425 /* Ack masked but set interrupts */
426 reg = chip->status_base +
427 (i * map->reg_stride * d->irq_reg_stride);
428 ret = regmap_read(map, reg, &d->status_buf[i]);
429 if (ret != 0) {
430 dev_err(map->dev, "Failed to read IRQ status: %d\n",
431 ret);
432 goto err_alloc;
433 }
434
435 if (d->status_buf[i] && chip->ack_base) {
436 reg = chip->ack_base +
437 (i * map->reg_stride * d->irq_reg_stride);
438 ret = regmap_write(map, reg,
439 d->status_buf[i] & d->mask_buf[i]);
440 if (ret != 0) {
441 dev_err(map->dev, "Failed to ack 0x%x: %d\n",
442 reg, ret);
443 goto err_alloc;
444 }
445 }
421 } 446 }
422 447
423 /* Wake is disabled by default */ 448 /* Wake is disabled by default */
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index e0d0c7d8a5c5..7d689a15c500 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -303,6 +303,7 @@ static void regmap_unlock_mutex(void *__map)
303} 303}
304 304
305static void regmap_lock_spinlock(void *__map) 305static void regmap_lock_spinlock(void *__map)
306__acquires(&map->spinlock)
306{ 307{
307 struct regmap *map = __map; 308 struct regmap *map = __map;
308 unsigned long flags; 309 unsigned long flags;
@@ -312,6 +313,7 @@ static void regmap_lock_spinlock(void *__map)
312} 313}
313 314
314static void regmap_unlock_spinlock(void *__map) 315static void regmap_unlock_spinlock(void *__map)
316__releases(&map->spinlock)
315{ 317{
316 struct regmap *map = __map; 318 struct regmap *map = __map;
317 spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags); 319 spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags);
@@ -687,6 +689,10 @@ skip_format_initialization:
687 unsigned win_max = win_min + 689 unsigned win_max = win_min +
688 config->ranges[j].window_len - 1; 690 config->ranges[j].window_len - 1;
689 691
692 /* Allow data window inside its own virtual range */
693 if (j == i)
694 continue;
695
690 if (range_cfg->range_min <= sel_reg && 696 if (range_cfg->range_min <= sel_reg &&
691 sel_reg <= range_cfg->range_max) { 697 sel_reg <= range_cfg->range_max) {
692 dev_err(map->dev, 698 dev_err(map->dev,
@@ -1261,6 +1267,9 @@ int _regmap_write(struct regmap *map, unsigned int reg,
1261 int ret; 1267 int ret;
1262 void *context = _regmap_map_get_context(map); 1268 void *context = _regmap_map_get_context(map);
1263 1269
1270 if (!regmap_writeable(map, reg))
1271 return -EIO;
1272
1264 if (!map->cache_bypass && !map->defer_caching) { 1273 if (!map->cache_bypass && !map->defer_caching) {
1265 ret = regcache_write(map, reg, val); 1274 ret = regcache_write(map, reg, val);
1266 if (ret != 0) 1275 if (ret != 0)
@@ -1888,13 +1897,10 @@ EXPORT_SYMBOL_GPL(regmap_async_complete);
1888int regmap_register_patch(struct regmap *map, const struct reg_default *regs, 1897int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
1889 int num_regs) 1898 int num_regs)
1890{ 1899{
1900 struct reg_default *p;
1891 int i, ret; 1901 int i, ret;
1892 bool bypass; 1902 bool bypass;
1893 1903
1894 /* If needed the implementation can be extended to support this */
1895 if (map->patch)
1896 return -EBUSY;
1897
1898 map->lock(map->lock_arg); 1904 map->lock(map->lock_arg);
1899 1905
1900 bypass = map->cache_bypass; 1906 bypass = map->cache_bypass;
@@ -1911,11 +1917,13 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
1911 } 1917 }
1912 } 1918 }
1913 1919
1914 map->patch = kcalloc(num_regs, sizeof(struct reg_default), GFP_KERNEL); 1920 p = krealloc(map->patch,
1915 if (map->patch != NULL) { 1921 sizeof(struct reg_default) * (map->patch_regs + num_regs),
1916 memcpy(map->patch, regs, 1922 GFP_KERNEL);
1917 num_regs * sizeof(struct reg_default)); 1923 if (p) {
1918 map->patch_regs = num_regs; 1924 memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
1925 map->patch = p;
1926 map->patch_regs += num_regs;
1919 } else { 1927 } else {
1920 ret = -ENOMEM; 1928 ret = -ENOMEM;
1921 } 1929 }