|
@@ -39,11 +39,12 @@ struct regcache_rbtree_ctx {
|
|
|
};
|
|
|
|
|
|
static inline void regcache_rbtree_get_base_top_reg(
|
|
|
+ struct regmap *map,
|
|
|
struct regcache_rbtree_node *rbnode,
|
|
|
unsigned int *base, unsigned int *top)
|
|
|
{
|
|
|
*base = rbnode->base_reg;
|
|
|
- *top = rbnode->base_reg + rbnode->blklen - 1;
|
|
|
+ *top = rbnode->base_reg + ((rbnode->blklen - 1) * map->reg_stride);
|
|
|
}
|
|
|
|
|
|
static unsigned int regcache_rbtree_get_register(
|
|
@@ -70,7 +71,8 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map,
|
|
|
|
|
|
rbnode = rbtree_ctx->cached_rbnode;
|
|
|
if (rbnode) {
|
|
|
- regcache_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
|
|
|
+ regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg,
|
|
|
+ &top_reg);
|
|
|
if (reg >= base_reg && reg <= top_reg)
|
|
|
return rbnode;
|
|
|
}
|
|
@@ -78,7 +80,8 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map,
|
|
|
node = rbtree_ctx->root.rb_node;
|
|
|
while (node) {
|
|
|
rbnode = container_of(node, struct regcache_rbtree_node, node);
|
|
|
- regcache_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
|
|
|
+ regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg,
|
|
|
+ &top_reg);
|
|
|
if (reg >= base_reg && reg <= top_reg) {
|
|
|
rbtree_ctx->cached_rbnode = rbnode;
|
|
|
return rbnode;
|
|
@@ -92,7 +95,7 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-static int regcache_rbtree_insert(struct rb_root *root,
|
|
|
+static int regcache_rbtree_insert(struct regmap *map, struct rb_root *root,
|
|
|
struct regcache_rbtree_node *rbnode)
|
|
|
{
|
|
|
struct rb_node **new, *parent;
|
|
@@ -106,7 +109,7 @@ static int regcache_rbtree_insert(struct rb_root *root,
|
|
|
rbnode_tmp = container_of(*new, struct regcache_rbtree_node,
|
|
|
node);
|
|
|
/* base and top registers of the current rbnode */
|
|
|
- regcache_rbtree_get_base_top_reg(rbnode_tmp, &base_reg_tmp,
|
|
|
+ regcache_rbtree_get_base_top_reg(map, rbnode_tmp, &base_reg_tmp,
|
|
|
&top_reg_tmp);
|
|
|
/* base register of the rbnode to be added */
|
|
|
base_reg = rbnode->base_reg;
|
|
@@ -138,7 +141,7 @@ static int rbtree_show(struct seq_file *s, void *ignored)
|
|
|
unsigned int base, top;
|
|
|
int nodes = 0;
|
|
|
int registers = 0;
|
|
|
- int average;
|
|
|
+ int this_registers, average;
|
|
|
|
|
|
map->lock(map);
|
|
|
|
|
@@ -146,11 +149,12 @@ static int rbtree_show(struct seq_file *s, void *ignored)
|
|
|
node = rb_next(node)) {
|
|
|
n = container_of(node, struct regcache_rbtree_node, node);
|
|
|
|
|
|
- regcache_rbtree_get_base_top_reg(n, &base, &top);
|
|
|
- seq_printf(s, "%x-%x (%d)\n", base, top, top - base + 1);
|
|
|
+ regcache_rbtree_get_base_top_reg(map, n, &base, &top);
|
|
|
+ this_registers = ((top - base) / map->reg_stride) + 1;
|
|
|
+ seq_printf(s, "%x-%x (%d)\n", base, top, this_registers);
|
|
|
|
|
|
nodes++;
|
|
|
- registers += top - base + 1;
|
|
|
+ registers += this_registers;
|
|
|
}
|
|
|
|
|
|
if (nodes)
|
|
@@ -255,7 +259,7 @@ static int regcache_rbtree_read(struct regmap *map,
|
|
|
|
|
|
rbnode = regcache_rbtree_lookup(map, reg);
|
|
|
if (rbnode) {
|
|
|
- reg_tmp = reg - rbnode->base_reg;
|
|
|
+ reg_tmp = (reg - rbnode->base_reg) / map->reg_stride;
|
|
|
*value = regcache_rbtree_get_register(rbnode, reg_tmp,
|
|
|
map->cache_word_size);
|
|
|
} else {
|
|
@@ -310,7 +314,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
|
|
|
*/
|
|
|
rbnode = regcache_rbtree_lookup(map, reg);
|
|
|
if (rbnode) {
|
|
|
- reg_tmp = reg - rbnode->base_reg;
|
|
|
+ reg_tmp = (reg - rbnode->base_reg) / map->reg_stride;
|
|
|
val = regcache_rbtree_get_register(rbnode, reg_tmp,
|
|
|
map->cache_word_size);
|
|
|
if (val == value)
|
|
@@ -321,13 +325,15 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
|
|
|
/* look for an adjacent register to the one we are about to add */
|
|
|
for (node = rb_first(&rbtree_ctx->root); node;
|
|
|
node = rb_next(node)) {
|
|
|
- rbnode_tmp = rb_entry(node, struct regcache_rbtree_node, node);
|
|
|
+ rbnode_tmp = rb_entry(node, struct regcache_rbtree_node,
|
|
|
+ node);
|
|
|
for (i = 0; i < rbnode_tmp->blklen; i++) {
|
|
|
- reg_tmp = rbnode_tmp->base_reg + i;
|
|
|
- if (abs(reg_tmp - reg) != 1)
|
|
|
+ reg_tmp = rbnode_tmp->base_reg +
|
|
|
+ (i * map->reg_stride);
|
|
|
+ if (abs(reg_tmp - reg) != map->reg_stride)
|
|
|
continue;
|
|
|
/* decide where in the block to place our register */
|
|
|
- if (reg_tmp + 1 == reg)
|
|
|
+ if (reg_tmp + map->reg_stride == reg)
|
|
|
pos = i + 1;
|
|
|
else
|
|
|
pos = i;
|
|
@@ -357,7 +363,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
regcache_rbtree_set_register(rbnode, 0, value, map->cache_word_size);
|
|
|
- regcache_rbtree_insert(&rbtree_ctx->root, rbnode);
|
|
|
+ regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode);
|
|
|
rbtree_ctx->cached_rbnode = rbnode;
|
|
|
}
|
|
|
|
|
@@ -397,7 +403,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
|
|
|
end = rbnode->blklen;
|
|
|
|
|
|
for (i = base; i < end; i++) {
|
|
|
- regtmp = rbnode->base_reg + i;
|
|
|
+ regtmp = rbnode->base_reg + (i * map->reg_stride);
|
|
|
val = regcache_rbtree_get_register(rbnode, i,
|
|
|
map->cache_word_size);
|
|
|
|