mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
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>
This commit is contained in:
parent
d8dfad3876
commit
b6752123cc
1 changed files with 14 additions and 11 deletions
|
@ -325,8 +325,8 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
|
|||
|
||||
if (i != map->rd_table->n_yes_ranges) {
|
||||
range = &map->rd_table->yes_ranges[i];
|
||||
rbnode->blklen = range->range_max - range->range_min
|
||||
+ 1;
|
||||
rbnode->blklen = (range->range_max - range->range_min) /
|
||||
map->reg_stride + 1;
|
||||
rbnode->base_reg = range->range_min;
|
||||
}
|
||||
}
|
||||
|
@ -418,30 +418,33 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
|
|||
struct regcache_rbtree_ctx *rbtree_ctx;
|
||||
struct rb_node *node;
|
||||
struct regcache_rbtree_node *rbnode;
|
||||
unsigned int base_reg, top_reg;
|
||||
unsigned int start, end;
|
||||
int ret;
|
||||
int base, end;
|
||||
|
||||
rbtree_ctx = map->cache;
|
||||
for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(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;
|
||||
if (rbnode->base_reg + rbnode->blklen < min)
|
||||
if (top_reg < min)
|
||||
continue;
|
||||
|
||||
if (min > rbnode->base_reg)
|
||||
base = min - rbnode->base_reg;
|
||||
if (min > base_reg)
|
||||
start = (min - base_reg) / map->reg_stride;
|
||||
else
|
||||
base = 0;
|
||||
start = 0;
|
||||
|
||||
if (max < rbnode->base_reg + rbnode->blklen)
|
||||
end = max - rbnode->base_reg + 1;
|
||||
if (max < top_reg)
|
||||
end = (max - base_reg) / map->reg_stride + 1;
|
||||
else
|
||||
end = rbnode->blklen;
|
||||
|
||||
ret = regcache_sync_block(map, rbnode->block, rbnode->base_reg,
|
||||
base, end);
|
||||
start, end);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue