regmap: cache: Split raw and non-raw syncs
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 29 Mar 2013 20:12:21 +0000 (20:12 +0000)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Sat, 30 Mar 2013 13:52:31 +0000 (13:52 +0000)
For code clarity after implementing block writes split out the raw and
non-raw I/O sync implementations.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Reviewed-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
drivers/base/regmap/regcache.c

index bb317db6818ffac9ecbdde730c47bc1fd9d8579f..da4d9843520f995642777898cdfc7bfdcf5bef19 100644 (file)
@@ -545,9 +545,43 @@ int regcache_lookup_reg(struct regmap *map, unsigned int reg)
                return -ENOENT;
 }
 
-int regcache_sync_block(struct regmap *map, void *block,
-                       unsigned int block_base, unsigned int start,
-                       unsigned int end)
+static int regcache_sync_block_single(struct regmap *map, void *block,
+                                     unsigned int block_base,
+                                     unsigned int start, unsigned int end)
+{
+       unsigned int i, regtmp, val;
+       int ret;
+
+       for (i = start; i < end; i++) {
+               regtmp = block_base + (i * map->reg_stride);
+
+               if (!regcache_reg_present(map, regtmp))
+                       continue;
+
+               val = regcache_get_val(map, block, i);
+
+               /* Is this the hardware default?  If so skip. */
+               ret = regcache_lookup_reg(map, regtmp);
+               if (ret >= 0 && val == map->reg_defaults[ret].def)
+                       continue;
+
+               map->cache_bypass = 1;
+
+               ret = _regmap_write(map, regtmp, val);
+
+               map->cache_bypass = 0;
+               if (ret != 0)
+                       return ret;
+               dev_dbg(map->dev, "Synced register %#x, value %#x\n",
+                       regtmp, val);
+       }
+
+       return 0;
+}
+
+int regcache_sync_block_raw(struct regmap *map, void *block,
+                           unsigned int block_base, unsigned int start,
+                           unsigned int end)
 {
        unsigned int i, regtmp, val;
        const void *addr;
@@ -568,14 +602,10 @@ int regcache_sync_block(struct regmap *map, void *block,
 
                map->cache_bypass = 1;
 
-               if (regmap_can_raw_write(map)) {
-                       addr = regcache_get_val_addr(map, block, i);
-                       ret = _regmap_raw_write(map, regtmp, addr,
-                                               map->format.val_bytes,
-                                               false);
-               } else {
-                       ret = _regmap_write(map, regtmp, val);
-               }
+               addr = regcache_get_val_addr(map, block, i);
+               ret = _regmap_raw_write(map, regtmp, addr,
+                                       map->format.val_bytes,
+                                       false);
 
                map->cache_bypass = 0;
                if (ret != 0)
@@ -586,3 +616,15 @@ int regcache_sync_block(struct regmap *map, void *block,
 
        return 0;
 }
+
+int regcache_sync_block(struct regmap *map, void *block,
+                       unsigned int block_base, unsigned int start,
+                       unsigned int end)
+{
+       if (regmap_can_raw_write(map))
+               return regcache_sync_block_raw(map, block, block_base,
+                                              start, end);
+       else
+               return regcache_sync_block_single(map, block, block_base,
+                                                 start, end);
+}