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>
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 85bffdd..bf441db 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -482,8 +482,14 @@
 		    size_t val_len)
 {
 	int ret;
+	int i;
+	bool vol = true;
 
-	WARN_ON(map->cache_type != REGCACHE_NONE);
+	for (i = 0; i < val_len / map->format.val_bytes; i++)
+		if (!regmap_volatile(map, reg + i))
+			vol = false;
+
+	WARN_ON(!vol && map->cache_type != REGCACHE_NONE);
 
 	mutex_lock(&map->lock);
 
@@ -511,18 +517,30 @@
 {
 	int ret, i;
 	size_t val_bytes = map->format.val_bytes;
-
-	WARN_ON(map->cache_type != REGCACHE_NONE);
+	bool vol = true;
 
 	if (!map->format.parse_val)
 		return -EINVAL;
 
-	ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
-	if (ret != 0)
-		return ret;
+	/* Is this a block of volatile registers? */
+	for (i = 0; i < val_count; i++)
+		if (!regmap_volatile(map, reg + i))
+			vol = false;
 
-	for (i = 0; i < val_count * val_bytes; i += val_bytes)
-		map->format.parse_val(val + i);
+	if (vol || map->cache_type == REGCACHE_NONE) {
+		ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
+		if (ret != 0)
+			return ret;
+
+		for (i = 0; i < val_count * val_bytes; i += val_bytes)
+			map->format.parse_val(val + i);
+	} else {
+		for (i = 0; i < val_count; i++) {
+			ret = regmap_read(map, reg + i, val + (i * val_bytes));
+			if (ret != 0)
+				return ret;
+		}
+	}
 
 	return 0;
 }