summaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regcache-rbtree.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-29 20:18:59 +0100
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-30 14:49:17 +0100
commit78493f2d7b51d6f6d03982cee559c62dfab4c292 (patch)
tree7b7360e51d4e245a0fa2ac611eecc252ea5030fc /drivers/base/regmap/regcache-rbtree.c
parentregmap: cache: Use raw I/O to sync rbtrees if we can (diff)
downloadlinux-78493f2d7b51d6f6d03982cee559c62dfab4c292.tar.xz
linux-78493f2d7b51d6f6d03982cee559c62dfab4c292.zip
regmap: cache: Factor out reg_present support from rbtree cache
The idea of maintaining a bitmap of present registers is something that can usefully be used by other cache types that maintain blocks of cached registers so move the code out of the rbtree cache and into the generic regcache code. Refactor the interface slightly as we go to wrap the set bit and enlarge bitmap operations (since we never do one without the other) and make it more robust for reads of uncached registers by bounds checking before we look at the bitmap. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Reviewed-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base/regmap/regcache-rbtree.c')
-rw-r--r--drivers/base/regmap/regcache-rbtree.c60
1 files changed, 2 insertions, 58 deletions
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 382a6deb3ca8..00c3506f542f 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -36,8 +36,6 @@ struct regcache_rbtree_node {
struct regcache_rbtree_ctx {
struct rb_root root;
struct regcache_rbtree_node *cached_rbnode;
- unsigned long *reg_present;
- unsigned int reg_present_nbits;
};
static inline void regcache_rbtree_get_base_top_reg(
@@ -154,7 +152,7 @@ static int rbtree_show(struct seq_file *s, void *ignored)
map->lock(map);
mem_size = sizeof(*rbtree_ctx);
- mem_size += BITS_TO_LONGS(rbtree_ctx->reg_present_nbits) * sizeof(long);
+ mem_size += BITS_TO_LONGS(map->cache_present_nbits) * sizeof(long);
for (node = rb_first(&rbtree_ctx->root); node != NULL;
node = rb_next(node)) {
@@ -205,44 +203,6 @@ static void rbtree_debugfs_init(struct regmap *map)
}
#endif
-static int enlarge_reg_present_bitmap(struct regmap *map, unsigned int reg)
-{
- struct regcache_rbtree_ctx *rbtree_ctx;
- unsigned long *reg_present;
- unsigned int reg_present_size;
- unsigned int nregs;
- int i;
-
- rbtree_ctx = map->cache;
- nregs = reg + 1;
- reg_present_size = BITS_TO_LONGS(nregs);
- reg_present_size *= sizeof(long);
-
- if (!rbtree_ctx->reg_present) {
- reg_present = kmalloc(reg_present_size, GFP_KERNEL);
- if (!reg_present)
- return -ENOMEM;
- bitmap_zero(reg_present, nregs);
- rbtree_ctx->reg_present = reg_present;
- rbtree_ctx->reg_present_nbits = nregs;
- return 0;
- }
-
- if (nregs > rbtree_ctx->reg_present_nbits) {
- reg_present = krealloc(rbtree_ctx->reg_present,
- reg_present_size, GFP_KERNEL);
- if (!reg_present)
- return -ENOMEM;
- for (i = 0; i < nregs; i++)
- if (i >= rbtree_ctx->reg_present_nbits)
- clear_bit(i, reg_present);
- rbtree_ctx->reg_present = reg_present;
- rbtree_ctx->reg_present_nbits = nregs;
- }
-
- return 0;
-}
-
static int regcache_rbtree_init(struct regmap *map)
{
struct regcache_rbtree_ctx *rbtree_ctx;
@@ -256,8 +216,6 @@ static int regcache_rbtree_init(struct regmap *map)
rbtree_ctx = map->cache;
rbtree_ctx->root = RB_ROOT;
rbtree_ctx->cached_rbnode = NULL;
- rbtree_ctx->reg_present = NULL;
- rbtree_ctx->reg_present_nbits = 0;
for (i = 0; i < map->num_reg_defaults; i++) {
ret = regcache_rbtree_write(map,
@@ -287,8 +245,6 @@ static int regcache_rbtree_exit(struct regmap *map)
if (!rbtree_ctx)
return 0;
- kfree(rbtree_ctx->reg_present);
-
/* free up the rbtree */
next = rb_first(&rbtree_ctx->root);
while (next) {
@@ -306,17 +262,6 @@ static int regcache_rbtree_exit(struct regmap *map)
return 0;
}
-static int regcache_reg_present(struct regmap *map, unsigned int reg)
-{
- struct regcache_rbtree_ctx *rbtree_ctx;
-
- rbtree_ctx = map->cache;
- if (!(rbtree_ctx->reg_present[BIT_WORD(reg)] & BIT_MASK(reg)))
- return 0;
- return 1;
-
-}
-
static int regcache_rbtree_read(struct regmap *map,
unsigned int reg, unsigned int *value)
{
@@ -378,10 +323,9 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
rbtree_ctx = map->cache;
/* update the reg_present bitmap, make space if necessary */
- ret = enlarge_reg_present_bitmap(map, reg);
+ ret = regcache_set_reg_present(map, reg);
if (ret < 0)
return ret;
- set_bit(reg, rbtree_ctx->reg_present);
/* if we can't locate it in the cached rbnode we'll have
* to traverse the rbtree looking for it.