aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-23 14:31:04 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-24 09:52:40 -0500
commitac8d91c801905a061ca883dca427a5e19602a1e7 (patch)
tree3b715a8aa18db4ed553811595c113ef95e1c5f75 /drivers/base
parent6ff7373809a9b4eb644d83e2e299da297e1cbffa (diff)
regmap: Supply ranges to the sync operations
In order to allow us to support partial sync operations add minimum and maximum register arguments to the sync operation and update the rbtree and lzo caches to use this new information. The LZO implementation is obviously not good, we could exit the iteration earlier, but there may be room for more wide reaching optimisation there. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/internal.h2
-rw-r--r--drivers/base/regmap/regcache-lzo.c10
-rw-r--r--drivers/base/regmap/regcache-rbtree.c25
-rw-r--r--drivers/base/regmap/regcache.c2
4 files changed, 32 insertions, 7 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index d141b80479b5..9c1d62e3e15c 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -87,7 +87,7 @@ struct regcache_ops {
87 int (*exit)(struct regmap *map); 87 int (*exit)(struct regmap *map);
88 int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); 88 int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
89 int (*write)(struct regmap *map, unsigned int reg, unsigned int value); 89 int (*write)(struct regmap *map, unsigned int reg, unsigned int value);
90 int (*sync)(struct regmap *map); 90 int (*sync)(struct regmap *map, unsigned int min, unsigned int max);
91}; 91};
92 92
93bool regmap_writeable(struct regmap *map, unsigned int reg); 93bool regmap_writeable(struct regmap *map, unsigned int reg);
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c
index b7d16143edeb..5e964e9b2bab 100644
--- a/drivers/base/regmap/regcache-lzo.c
+++ b/drivers/base/regmap/regcache-lzo.c
@@ -331,7 +331,8 @@ out:
331 return ret; 331 return ret;
332} 332}
333 333
334static int regcache_lzo_sync(struct regmap *map) 334static int regcache_lzo_sync(struct regmap *map, unsigned int min,
335 unsigned int max)
335{ 336{
336 struct regcache_lzo_ctx **lzo_blocks; 337 struct regcache_lzo_ctx **lzo_blocks;
337 unsigned int val; 338 unsigned int val;
@@ -339,7 +340,12 @@ static int regcache_lzo_sync(struct regmap *map)
339 int ret; 340 int ret;
340 341
341 lzo_blocks = map->cache; 342 lzo_blocks = map->cache;
342 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { 343 i = min;
344 for_each_set_bit_from(i, lzo_blocks[0]->sync_bmp,
345 lzo_blocks[0]->sync_bmp_nbits) {
346 if (i > max)
347 continue;
348
343 ret = regcache_read(map, i, &val); 349 ret = regcache_read(map, i, &val);
344 if (ret) 350 if (ret)
345 return ret; 351 return ret;
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 32620c4f1683..bae183c6bcb1 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -357,7 +357,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
357 return 0; 357 return 0;
358} 358}
359 359
360static int regcache_rbtree_sync(struct regmap *map) 360static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
361 unsigned int max)
361{ 362{
362 struct regcache_rbtree_ctx *rbtree_ctx; 363 struct regcache_rbtree_ctx *rbtree_ctx;
363 struct rb_node *node; 364 struct rb_node *node;
@@ -365,12 +366,30 @@ static int regcache_rbtree_sync(struct regmap *map)
365 unsigned int regtmp; 366 unsigned int regtmp;
366 unsigned int val; 367 unsigned int val;
367 int ret; 368 int ret;
368 int i; 369 int i, base, end;
369 370
370 rbtree_ctx = map->cache; 371 rbtree_ctx = map->cache;
371 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { 372 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
372 rbnode = rb_entry(node, struct regcache_rbtree_node, node); 373 rbnode = rb_entry(node, struct regcache_rbtree_node, node);
373 for (i = 0; i < rbnode->blklen; i++) { 374
375 if (rbnode->base_reg < min)
376 continue;
377 if (rbnode->base_reg > max)
378 break;
379 if (rbnode->base_reg + rbnode->blklen < min)
380 continue;
381
382 if (min < rbnode->base_reg + rbnode->blklen)
383 base = min - rbnode->base_reg;
384 else
385 base = 0;
386
387 if (max < rbnode->base_reg + rbnode->blklen)
388 end = rbnode->base_reg + rbnode->blklen - max;
389 else
390 end = rbnode->blklen;
391
392 for (i = base; i < end; i++) {
374 regtmp = rbnode->base_reg + i; 393 regtmp = rbnode->base_reg + i;
375 val = regcache_rbtree_get_register(rbnode, i, 394 val = regcache_rbtree_get_register(rbnode, i,
376 map->cache_word_size); 395 map->cache_word_size);
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 46c42d3a4655..aec5a7486a29 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -283,7 +283,7 @@ int regcache_sync(struct regmap *map)
283 } 283 }
284 map->cache_bypass = 0; 284 map->cache_bypass = 0;
285 285
286 ret = map->cache_ops->sync(map); 286 ret = map->cache_ops->sync(map, 0, map->max_register);
287 287
288 if (ret == 0) 288 if (ret == 0)
289 map->cache_dirty = false; 289 map->cache_dirty = false;