diff options
author | Mark Brown <broonie@kernel.org> | 2014-11-21 06:32:35 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-11-21 06:32:35 -0500 |
commit | c6efe576183a86d0ce637f259b5ea3a7653f8f76 (patch) | |
tree | 3dcdf1d77eef8efc040ce268c49f2cc2ff734ca3 /drivers/base | |
parent | 28176ab6d0c3def4d5c1f3c37e560b0093c58547 (diff) | |
parent | 3d7e9cecc829bd85e18519602048bc705b93a560 (diff) |
Merge remote-tracking branch 'regmap/topic/cache' into regmap-next
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/regmap/regcache.c | 55 |
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 | ||
89 | err_cache_free: | ||
90 | kfree(tmp_buf); | ||
87 | err_free: | 91 | err_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) |