aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2016-02-02 07:16:51 -0500
committerMark Brown <broonie@kernel.org>2016-02-02 12:58:22 -0500
commit3245d460a1eb55b5c3ca31dde7b5c5ac71546edf (patch)
tree656fb73fa195f877a5e09f37ea60c145b67c56ef
parentbb2bb45d1be28987e6cb50f50e4819795537ab83 (diff)
regmap: cache: Fall back to register by register read for cache defaults
If we are unable to read the cache defaults for a regmap then fall back on attempting to read them word by word. This is going to be painfully slow for large regmaps but might be adequate for smaller ones. Signed-off-by: Mark Brown <broonie@kernel.org> [maciej: Use cache_bypass around read and skipping of unreadable regs] Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com> Tested-by: Fabio Estevam <fabio.estevam@nxp.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/base/regmap/regcache.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 348be3a35410..cccceb599b02 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -30,7 +30,7 @@ static int regcache_hw_init(struct regmap *map)
30 int i, j; 30 int i, j;
31 int ret; 31 int ret;
32 int count; 32 int count;
33 unsigned int val; 33 unsigned int reg, val;
34 void *tmp_buf; 34 void *tmp_buf;
35 35
36 if (!map->num_reg_defaults_raw) 36 if (!map->num_reg_defaults_raw)
@@ -67,27 +67,46 @@ static int regcache_hw_init(struct regmap *map)
67 ret = regmap_raw_read(map, 0, tmp_buf, 67 ret = regmap_raw_read(map, 0, tmp_buf,
68 map->num_reg_defaults_raw); 68 map->num_reg_defaults_raw);
69 map->cache_bypass = cache_bypass; 69 map->cache_bypass = cache_bypass;
70 if (ret < 0) 70 if (ret == 0) {
71 goto err_cache_free; 71 map->reg_defaults_raw = tmp_buf;
72 72 map->cache_free = 1;
73 map->reg_defaults_raw = tmp_buf; 73 } else {
74 map->cache_free = 1; 74 kfree(tmp_buf);
75 }
75 } 76 }
76 77
77 /* fill the reg_defaults */ 78 /* fill the reg_defaults */
78 for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { 79 for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
79 if (regmap_volatile(map, i * map->reg_stride)) 80 reg = i * map->reg_stride;
81
82 if (!regmap_readable(map, reg))
80 continue; 83 continue;
81 val = regcache_get_val(map, map->reg_defaults_raw, i); 84
82 map->reg_defaults[j].reg = i * map->reg_stride; 85 if (regmap_volatile(map, reg))
86 continue;
87
88 if (map->reg_defaults_raw) {
89 val = regcache_get_val(map, map->reg_defaults_raw, i);
90 } else {
91 bool cache_bypass = map->cache_bypass;
92
93 map->cache_bypass = true;
94 ret = regmap_read(map, reg, &val);
95 map->cache_bypass = cache_bypass;
96 if (ret != 0) {
97 dev_err(map->dev, "Failed to read %d: %d\n",
98 reg, ret);
99 goto err_free;
100 }
101 }
102
103 map->reg_defaults[j].reg = reg;
83 map->reg_defaults[j].def = val; 104 map->reg_defaults[j].def = val;
84 j++; 105 j++;
85 } 106 }
86 107
87 return 0; 108 return 0;
88 109
89err_cache_free:
90 kfree(tmp_buf);
91err_free: 110err_free:
92 kfree(map->reg_defaults); 111 kfree(map->reg_defaults);
93 112