aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regcache-rbtree.c
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-06-30 07:40:01 -0400
committerMark Brown <broonie@linaro.org>2013-06-30 07:40:01 -0400
commitfeff98f5507f98c0422252caec41c3be9e6b6399 (patch)
treed014206d6ecc095ceb8e03ea2b17b42bf1ce786a /drivers/base/regmap/regcache-rbtree.c
parent9e895ace5d82df8929b16f58e9f515f6d54ab82d (diff)
parentd6814a7dafa590ec5fe0597922ea76354f9bec59 (diff)
Merge remote-tracking branch 'regmap/topic/cache' into regmap-next
Diffstat (limited to 'drivers/base/regmap/regcache-rbtree.c')
-rw-r--r--drivers/base/regmap/regcache-rbtree.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 02f490bad30f..5c1435c4e210 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -304,6 +304,48 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
304 return 0; 304 return 0;
305} 305}
306 306
307static struct regcache_rbtree_node *
308regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
309{
310 struct regcache_rbtree_node *rbnode;
311 const struct regmap_range *range;
312 int i;
313
314 rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL);
315 if (!rbnode)
316 return NULL;
317
318 /* If there is a read table then use it to guess at an allocation */
319 if (map->rd_table) {
320 for (i = 0; i < map->rd_table->n_yes_ranges; i++) {
321 if (regmap_reg_in_range(reg,
322 &map->rd_table->yes_ranges[i]))
323 break;
324 }
325
326 if (i != map->rd_table->n_yes_ranges) {
327 range = &map->rd_table->yes_ranges[i];
328 rbnode->blklen = range->range_max - range->range_min
329 + 1;
330 rbnode->base_reg = range->range_min;
331 }
332 }
333
334 if (!rbnode->blklen) {
335 rbnode->blklen = sizeof(*rbnode);
336 rbnode->base_reg = reg;
337 }
338
339 rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size,
340 GFP_KERNEL);
341 if (!rbnode->block) {
342 kfree(rbnode);
343 return NULL;
344 }
345
346 return rbnode;
347}
348
307static int regcache_rbtree_write(struct regmap *map, unsigned int reg, 349static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
308 unsigned int value) 350 unsigned int value)
309{ 351{
@@ -354,23 +396,15 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
354 return 0; 396 return 0;
355 } 397 }
356 } 398 }
357 /* we did not manage to find a place to insert it in an existing 399
358 * block so create a new rbnode with a single register in its block. 400 /* We did not manage to find a place to insert it in
359 * This block will get populated further if any other adjacent 401 * an existing block so create a new rbnode.
360 * registers get modified in the future.
361 */ 402 */
362 rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL); 403 rbnode = regcache_rbtree_node_alloc(map, reg);
363 if (!rbnode) 404 if (!rbnode)
364 return -ENOMEM; 405 return -ENOMEM;
365 rbnode->blklen = sizeof(*rbnode); 406 regcache_rbtree_set_register(map, rbnode,
366 rbnode->base_reg = reg; 407 reg - rbnode->base_reg, value);
367 rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size,
368 GFP_KERNEL);
369 if (!rbnode->block) {
370 kfree(rbnode);
371 return -ENOMEM;
372 }
373 regcache_rbtree_set_register(map, rbnode, 0, value);
374 regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); 408 regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode);
375 rbtree_ctx->cached_rbnode = rbnode; 409 rbtree_ctx->cached_rbnode = rbnode;
376 } 410 }