aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-10-10 08:24:52 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-10-13 06:41:54 -0400
commitde2d808f4de091321978d05a85ef0819e8f3561a (patch)
treed2b3d27de79f9cd7d7092a886c8a9479588a5428 /drivers/base
parent8528bdd450d34687b380c0f87992d105bdf54ca3 (diff)
regmap: Support some block operations on cached devices
Support raw reads if all the registers being read are volatile, the cache will have no impact for tem. Support bulk reads either directly (if all the registers are volatile) or by falling back to iterating over single register reads otherwise. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regmap.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 85bffddda530..bf441db1ee90 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -482,8 +482,14 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
482 size_t val_len) 482 size_t val_len)
483{ 483{
484 int ret; 484 int ret;
485 int i;
486 bool vol = true;
485 487
486 WARN_ON(map->cache_type != REGCACHE_NONE); 488 for (i = 0; i < val_len / map->format.val_bytes; i++)
489 if (!regmap_volatile(map, reg + i))
490 vol = false;
491
492 WARN_ON(!vol && map->cache_type != REGCACHE_NONE);
487 493
488 mutex_lock(&map->lock); 494 mutex_lock(&map->lock);
489 495
@@ -511,18 +517,30 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
511{ 517{
512 int ret, i; 518 int ret, i;
513 size_t val_bytes = map->format.val_bytes; 519 size_t val_bytes = map->format.val_bytes;
514 520 bool vol = true;
515 WARN_ON(map->cache_type != REGCACHE_NONE);
516 521
517 if (!map->format.parse_val) 522 if (!map->format.parse_val)
518 return -EINVAL; 523 return -EINVAL;
519 524
520 ret = regmap_raw_read(map, reg, val, val_bytes * val_count); 525 /* Is this a block of volatile registers? */
521 if (ret != 0) 526 for (i = 0; i < val_count; i++)
522 return ret; 527 if (!regmap_volatile(map, reg + i))
528 vol = false;
523 529
524 for (i = 0; i < val_count * val_bytes; i += val_bytes) 530 if (vol || map->cache_type == REGCACHE_NONE) {
525 map->format.parse_val(val + i); 531 ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
532 if (ret != 0)
533 return ret;
534
535 for (i = 0; i < val_count * val_bytes; i += val_bytes)
536 map->format.parse_val(val + i);
537 } else {
538 for (i = 0; i < val_count; i++) {
539 ret = regmap_read(map, reg + i, val + (i * val_bytes));
540 if (ret != 0)
541 return ret;
542 }
543 }
526 544
527 return 0; 545 return 0;
528} 546}