void *cache;
u32 cache_dirty;
+ unsigned long *cache_present;
+ unsigned int cache_present_nbits;
+
struct reg_default *patch;
int patch_regs;
bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
unsigned int val);
int regcache_lookup_reg(struct regmap *map, unsigned int reg);
+int regcache_set_reg_present(struct regmap *map, unsigned int reg);
+
+static inline bool regcache_reg_present(struct regmap *map, unsigned int reg)
+{
+ if (!map->cache_present)
+ return true;
+ if (reg > map->cache_present_nbits)
+ return false;
+ return map->cache_present[BIT_WORD(reg)] & BIT_MASK(reg);
+}
int _regmap_raw_write(struct regmap *map, unsigned int reg,
const void *val, size_t val_len, bool async);
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(
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)) {
}
#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;
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,
if (!rbtree_ctx)
return 0;
- kfree(rbtree_ctx->reg_present);
-
/* free up the rbtree */
next = rb_first(&rbtree_ctx->root);
while (next) {
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)
{
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.
map->reg_defaults_raw = config->reg_defaults_raw;
map->cache_word_size = DIV_ROUND_UP(config->val_bits, 8);
map->cache_size_raw = map->cache_word_size * config->num_reg_defaults_raw;
+ map->cache_present = NULL;
+ map->cache_present_nbits = 0;
map->cache = NULL;
map->cache_ops = cache_types[i];
BUG_ON(!map->cache_ops);
+ kfree(map->cache_present);
kfree(map->reg_defaults);
if (map->cache_free)
kfree(map->reg_defaults_raw);
}
EXPORT_SYMBOL_GPL(regcache_cache_bypass);
+int regcache_set_reg_present(struct regmap *map, unsigned int reg)
+{
+ unsigned long *cache_present;
+ unsigned int cache_present_size;
+ unsigned int nregs;
+ int i;
+
+ nregs = reg + 1;
+ cache_present_size = BITS_TO_LONGS(nregs);
+ cache_present_size *= sizeof(long);
+
+ if (!map->cache_present) {
+ cache_present = kmalloc(cache_present_size, GFP_KERNEL);
+ if (!cache_present)
+ return -ENOMEM;
+ bitmap_zero(cache_present, nregs);
+ map->cache_present = cache_present;
+ map->cache_present_nbits = nregs;
+ }
+
+ if (nregs > map->cache_present_nbits) {
+ cache_present = krealloc(map->cache_present,
+ cache_present_size, GFP_KERNEL);
+ if (!cache_present)
+ return -ENOMEM;
+ for (i = 0; i < nregs; i++)
+ if (i >= map->cache_present_nbits)
+ clear_bit(i, cache_present);
+ map->cache_present = cache_present;
+ map->cache_present_nbits = nregs;
+ }
+
+ set_bit(reg, map->cache_present);
+ return 0;
+}
+
bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
unsigned int val)
{