Commit c6efe576 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'regmap/topic/cache' into regmap-next

parents 28176ab6 3d7e9cec
Loading
Loading
Loading
Loading
+30 −25
Original line number Diff line number Diff line
@@ -36,6 +36,23 @@ static int regcache_hw_init(struct regmap *map)
	if (!map->num_reg_defaults_raw)
		return -EINVAL;

	/* calculate the size of reg_defaults */
	for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++)
		if (!regmap_volatile(map, i * map->reg_stride))
			count++;

	/* all registers are volatile, so just bypass */
	if (!count) {
		map->cache_bypass = true;
		return 0;
	}

	map->num_reg_defaults = count;
	map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default),
					  GFP_KERNEL);
	if (!map->reg_defaults)
		return -ENOMEM;

	if (!map->reg_defaults_raw) {
		u32 cache_bypass = map->cache_bypass;
		dev_warn(map->dev, "No cache defaults, reading back from HW\n");
@@ -43,40 +60,25 @@ static int regcache_hw_init(struct regmap *map)
		/* Bypass the cache access till data read from HW*/
		map->cache_bypass = 1;
		tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL);
		if (!tmp_buf)
			return -ENOMEM;
		if (!tmp_buf) {
			ret = -ENOMEM;
			goto err_free;
		}
		ret = regmap_raw_read(map, 0, tmp_buf,
				      map->num_reg_defaults_raw);
		map->cache_bypass = cache_bypass;
		if (ret < 0) {
			kfree(tmp_buf);
			return ret;
		}
		if (ret < 0)
			goto err_cache_free;

		map->reg_defaults_raw = tmp_buf;
		map->cache_free = 1;
	}

	/* calculate the size of reg_defaults */
	for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) {
		val = regcache_get_val(map, map->reg_defaults_raw, i);
		if (regmap_volatile(map, i * map->reg_stride))
			continue;
		count++;
	}

	map->reg_defaults = kmalloc(count * sizeof(struct reg_default),
				      GFP_KERNEL);
	if (!map->reg_defaults) {
		ret = -ENOMEM;
		goto err_free;
	}

	/* fill the reg_defaults */
	map->num_reg_defaults = count;
	for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
		val = regcache_get_val(map, map->reg_defaults_raw, i);
		if (regmap_volatile(map, i * map->reg_stride))
			continue;
		val = regcache_get_val(map, map->reg_defaults_raw, i);
		map->reg_defaults[j].reg = i * map->reg_stride;
		map->reg_defaults[j].def = val;
		j++;
@@ -84,9 +86,10 @@ static int regcache_hw_init(struct regmap *map)

	return 0;

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

	return ret;
}
@@ -150,6 +153,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
		ret = regcache_hw_init(map);
		if (ret < 0)
			return ret;
		if (map->cache_bypass)
			return 0;
	}

	if (!map->max_register)