Skip to content

Commit

Permalink
regmap: cache: Fall back to register by register read for cache defaults
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Brown committed Feb 2, 2016
1 parent bb2bb45 commit 3245d46
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions drivers/base/regmap/regcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static int regcache_hw_init(struct regmap *map)
int i, j;
int ret;
int count;
unsigned int val;
unsigned int reg, val;
void *tmp_buf;

if (!map->num_reg_defaults_raw)
Expand Down Expand Up @@ -67,27 +67,46 @@ static int regcache_hw_init(struct regmap *map)
ret = regmap_raw_read(map, 0, tmp_buf,
map->num_reg_defaults_raw);
map->cache_bypass = cache_bypass;
if (ret < 0)
goto err_cache_free;

map->reg_defaults_raw = tmp_buf;
map->cache_free = 1;
if (ret == 0) {
map->reg_defaults_raw = tmp_buf;
map->cache_free = 1;
} else {
kfree(tmp_buf);
}
}

/* fill the reg_defaults */
for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
if (regmap_volatile(map, i * map->reg_stride))
reg = i * map->reg_stride;

if (!regmap_readable(map, reg))
continue;
val = regcache_get_val(map, map->reg_defaults_raw, i);
map->reg_defaults[j].reg = i * map->reg_stride;

if (regmap_volatile(map, reg))
continue;

if (map->reg_defaults_raw) {
val = regcache_get_val(map, map->reg_defaults_raw, i);
} else {
bool cache_bypass = map->cache_bypass;

map->cache_bypass = true;
ret = regmap_read(map, reg, &val);
map->cache_bypass = cache_bypass;
if (ret != 0) {
dev_err(map->dev, "Failed to read %d: %d\n",
reg, ret);
goto err_free;
}
}

map->reg_defaults[j].reg = reg;
map->reg_defaults[j].def = val;
j++;
}

return 0;

err_cache_free:
kfree(tmp_buf);
err_free:
kfree(map->reg_defaults);

Expand Down

0 comments on commit 3245d46

Please sign in to comment.