Commit b6752123 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Mark Brown

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: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent d8dfad38
...@@ -325,8 +325,8 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg) ...@@ -325,8 +325,8 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
if (i != map->rd_table->n_yes_ranges) { if (i != map->rd_table->n_yes_ranges) {
range = &map->rd_table->yes_ranges[i]; range = &map->rd_table->yes_ranges[i];
rbnode->blklen = range->range_max - range->range_min rbnode->blklen = (range->range_max - range->range_min) /
+ 1; map->reg_stride + 1;
rbnode->base_reg = range->range_min; rbnode->base_reg = range->range_min;
} }
} }
...@@ -418,30 +418,33 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, ...@@ -418,30 +418,33 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
struct regcache_rbtree_ctx *rbtree_ctx; struct regcache_rbtree_ctx *rbtree_ctx;
struct rb_node *node; struct rb_node *node;
struct regcache_rbtree_node *rbnode; struct regcache_rbtree_node *rbnode;
unsigned int base_reg, top_reg;
unsigned int start, end;
int ret; int ret;
int base, end;
rbtree_ctx = map->cache; rbtree_ctx = map->cache;
for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
rbnode = rb_entry(node, struct regcache_rbtree_node, node); rbnode = rb_entry(node, struct regcache_rbtree_node, node);
if (rbnode->base_reg > max) regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg,
&top_reg);
if (base_reg > max)
break; break;
if (rbnode->base_reg + rbnode->blklen < min) if (top_reg < min)
continue; continue;
if (min > rbnode->base_reg) if (min > base_reg)
base = min - rbnode->base_reg; start = (min - base_reg) / map->reg_stride;
else else
base = 0; start = 0;
if (max < rbnode->base_reg + rbnode->blklen) if (max < top_reg)
end = max - rbnode->base_reg + 1; end = (max - base_reg) / map->reg_stride + 1;
else else
end = rbnode->blklen; end = rbnode->blklen;
ret = regcache_sync_block(map, rbnode->block, rbnode->base_reg, ret = regcache_sync_block(map, rbnode->block, rbnode->base_reg,
base, end); start, end);
if (ret != 0) if (ret != 0)
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment