Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3245d460 authored by Mark Brown's avatar Mark Brown
Browse files

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: default avatarMark Brown <broonie@kernel.org>
[maciej: Use cache_bypass around read and skipping of unreadable regs]
Signed-off-by: default avatarMaciej S. Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: default avatarFabio Estevam <fabio.estevam@nxp.com>
Tested-by: default avatarFabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent bb2bb45d
Loading
Loading
Loading
Loading
+30 −11
Original line number Diff line number Diff line
@@ -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)
@@ -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;

		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;

		if (regmap_volatile(map, reg))
			continue;

		if (map->reg_defaults_raw) {
			val = regcache_get_val(map, map->reg_defaults_raw, i);
		map->reg_defaults[j].reg = i * map->reg_stride;
		} 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);