aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2014-11-21 06:32:35 -0500
committerMark Brown <broonie@kernel.org>2014-11-21 06:32:35 -0500
commitc6efe576183a86d0ce637f259b5ea3a7653f8f76 (patch)
tree3dcdf1d77eef8efc040ce268c49f2cc2ff734ca3 /drivers/base
parent28176ab6d0c3def4d5c1f3c37e560b0093c58547 (diff)
parent3d7e9cecc829bd85e18519602048bc705b93a560 (diff)
Merge remote-tracking branch 'regmap/topic/cache' into regmap-next
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regcache.c55
1 files changed, 30 insertions, 25 deletions
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 44e6a48019a5..d815929ba745 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -36,6 +36,23 @@ static int regcache_hw_init(struct regmap *map)
36 if (!map->num_reg_defaults_raw) 36 if (!map->num_reg_defaults_raw)
37 return -EINVAL; 37 return -EINVAL;
38 38
39 /* calculate the size of reg_defaults */
40 for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++)
41 if (!regmap_volatile(map, i * map->reg_stride))
42 count++;
43
44 /* all registers are volatile, so just bypass */
45 if (!count) {
46 map->cache_bypass = true;
47 return 0;
48 }
49
50 map->num_reg_defaults = count;
51 map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default),
52 GFP_KERNEL);
53 if (!map->reg_defaults)
54 return -ENOMEM;
55
39 if (!map->reg_defaults_raw) { 56 if (!map->reg_defaults_raw) {
40 u32 cache_bypass = map->cache_bypass; 57 u32 cache_bypass = map->cache_bypass;
41 dev_warn(map->dev, "No cache defaults, reading back from HW\n"); 58 dev_warn(map->dev, "No cache defaults, reading back from HW\n");
@@ -43,40 +60,25 @@ static int regcache_hw_init(struct regmap *map)
43 /* Bypass the cache access till data read from HW*/ 60 /* Bypass the cache access till data read from HW*/
44 map->cache_bypass = 1; 61 map->cache_bypass = 1;
45 tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); 62 tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL);
46 if (!tmp_buf) 63 if (!tmp_buf) {
47 return -ENOMEM; 64 ret = -ENOMEM;
65 goto err_free;
66 }
48 ret = regmap_raw_read(map, 0, tmp_buf, 67 ret = regmap_raw_read(map, 0, tmp_buf,
49 map->num_reg_defaults_raw); 68 map->num_reg_defaults_raw);
50 map->cache_bypass = cache_bypass; 69 map->cache_bypass = cache_bypass;
51 if (ret < 0) { 70 if (ret < 0)
52 kfree(tmp_buf); 71 goto err_cache_free;
53 return ret; 72
54 }
55 map->reg_defaults_raw = tmp_buf; 73 map->reg_defaults_raw = tmp_buf;
56 map->cache_free = 1; 74 map->cache_free = 1;
57 } 75 }
58 76
59 /* calculate the size of reg_defaults */
60 for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) {
61 val = regcache_get_val(map, map->reg_defaults_raw, i);
62 if (regmap_volatile(map, i * map->reg_stride))
63 continue;
64 count++;
65 }
66
67 map->reg_defaults = kmalloc(count * sizeof(struct reg_default),
68 GFP_KERNEL);
69 if (!map->reg_defaults) {
70 ret = -ENOMEM;
71 goto err_free;
72 }
73
74 /* fill the reg_defaults */ 77 /* fill the reg_defaults */
75 map->num_reg_defaults = count;
76 for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { 78 for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
77 val = regcache_get_val(map, map->reg_defaults_raw, i);
78 if (regmap_volatile(map, i * map->reg_stride)) 79 if (regmap_volatile(map, i * map->reg_stride))
79 continue; 80 continue;
81 val = regcache_get_val(map, map->reg_defaults_raw, i);
80 map->reg_defaults[j].reg = i * map->reg_stride; 82 map->reg_defaults[j].reg = i * map->reg_stride;
81 map->reg_defaults[j].def = val; 83 map->reg_defaults[j].def = val;
82 j++; 84 j++;
@@ -84,9 +86,10 @@ static int regcache_hw_init(struct regmap *map)
84 86
85 return 0; 87 return 0;
86 88
89err_cache_free:
90 kfree(tmp_buf);
87err_free: 91err_free:
88 if (map->cache_free) 92 kfree(map->reg_defaults);
89 kfree(map->reg_defaults_raw);
90 93
91 return ret; 94 return ret;
92} 95}
@@ -150,6 +153,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
150 ret = regcache_hw_init(map); 153 ret = regcache_hw_init(map);
151 if (ret < 0) 154 if (ret < 0)
152 return ret; 155 return ret;
156 if (map->cache_bypass)
157 return 0;
153 } 158 }
154 159
155 if (!map->max_register) 160 if (!map->max_register)