aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-08-27 07:03:03 -0400
committerMark Brown <broonie@linaro.org>2013-08-27 11:23:00 -0400
commitb6752123ccef4eec3c70c20dbdfc05d1674319c5 (patch)
treeeac40c4ea69182004640ad13488c58e77c560ef8 /drivers/base/regmap
parentd8dfad3876e4386666b759da3c833d62fb8b2267 (diff)
regcache-rbtree: Fix reg_stride != 1
There are a couple of calculations, which convert between register addresses and block indices, in regcache_rbtree_sync() and regcache_rbtree_node_alloc() which assume that reg_stride is 1. This will break the rb cache for configurations which do not use a reg_stride of 1. Also rename 'base' in regcache_rbtree_sync() to 'start' to avoid confusion with 'base_reg'. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/base/regmap')
-rw-r--r--drivers/base/regmap/regcache-rbtree.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 5c1435c4e210..f2384a816cc4 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -325,8 +325,8 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
325 325
326 if (i != map->rd_table->n_yes_ranges) { 326 if (i != map->rd_table->n_yes_ranges) {
327 range = &map->rd_table->yes_ranges[i]; 327 range = &map->rd_table->yes_ranges[i];
328 rbnode->blklen = range->range_max - range->range_min 328 rbnode->blklen = (range->range_max - range->range_min) /
329 + 1; 329 map->reg_stride + 1;
330 rbnode->base_reg = range->range_min; 330 rbnode->base_reg = range->range_min;
331 } 331 }
332 } 332 }
@@ -418,30 +418,33 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
418 struct regcache_rbtree_ctx *rbtree_ctx; 418 struct regcache_rbtree_ctx *rbtree_ctx;
419 struct rb_node *node; 419 struct rb_node *node;
420 struct regcache_rbtree_node *rbnode; 420 struct regcache_rbtree_node *rbnode;
421 unsigned int base_reg, top_reg;
422 unsigned int start, end;
421 int ret; 423 int ret;
422 int base, end;
423 424
424 rbtree_ctx = map->cache; 425 rbtree_ctx = map->cache;
425 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { 426 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
426 rbnode = rb_entry(node, struct regcache_rbtree_node, node); 427 rbnode = rb_entry(node, struct regcache_rbtree_node, node);
427 428
428 if (rbnode->base_reg > max) 429 regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg,
430 &top_reg);
431 if (base_reg > max)
429 break; 432 break;
430 if (rbnode->base_reg + rbnode->blklen < min) 433 if (top_reg < min)
431 continue; 434 continue;
432 435
433 if (min > rbnode->base_reg) 436 if (min > base_reg)
434 base = min - rbnode->base_reg; 437 start = (min - base_reg) / map->reg_stride;
435 else 438 else
436 base = 0; 439 start = 0;
437 440
438 if (max < rbnode->base_reg + rbnode->blklen) 441 if (max < top_reg)
439 end = max - rbnode->base_reg + 1; 442 end = (max - base_reg) / map->reg_stride + 1;
440 else 443 else
441 end = rbnode->blklen; 444 end = rbnode->blklen;
442 445
443 ret = regcache_sync_block(map, rbnode->block, rbnode->base_reg, 446 ret = regcache_sync_block(map, rbnode->block, rbnode->base_reg,
444 base, end); 447 start, end);
445 if (ret != 0) 448 if (ret != 0)
446 return ret; 449 return ret;
447 } 450 }