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

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

regmap: Supply ranges to the sync operations



In order to allow us to support partial sync operations add minimum and
maximum register arguments to the sync operation and update the rbtree
and lzo caches to use this new information. The LZO implementation is
obviously not good, we could exit the iteration earlier, but there may
be room for more wide reaching optimisation there.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 6ff73738
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ struct regcache_ops {
	int (*exit)(struct regmap *map);
	int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
	int (*write)(struct regmap *map, unsigned int reg, unsigned int value);
	int (*sync)(struct regmap *map);
	int (*sync)(struct regmap *map, unsigned int min, unsigned int max);
};

bool regmap_writeable(struct regmap *map, unsigned int reg);
+8 −2
Original line number Diff line number Diff line
@@ -331,7 +331,8 @@ static int regcache_lzo_write(struct regmap *map,
	return ret;
}

static int regcache_lzo_sync(struct regmap *map)
static int regcache_lzo_sync(struct regmap *map, unsigned int min,
			     unsigned int max)
{
	struct regcache_lzo_ctx **lzo_blocks;
	unsigned int val;
@@ -339,7 +340,12 @@ static int regcache_lzo_sync(struct regmap *map)
	int ret;

	lzo_blocks = map->cache;
	for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
	i = min;
	for_each_set_bit_from(i, lzo_blocks[0]->sync_bmp,
			      lzo_blocks[0]->sync_bmp_nbits) {
		if (i > max)
			continue;

		ret = regcache_read(map, i, &val);
		if (ret)
			return ret;
+22 −3
Original line number Diff line number Diff line
@@ -357,7 +357,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
	return 0;
}

static int regcache_rbtree_sync(struct regmap *map)
static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
				unsigned int max)
{
	struct regcache_rbtree_ctx *rbtree_ctx;
	struct rb_node *node;
@@ -365,12 +366,30 @@ static int regcache_rbtree_sync(struct regmap *map)
	unsigned int regtmp;
	unsigned int val;
	int ret;
	int i;
	int i, base, end;

	rbtree_ctx = map->cache;
	for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
		rbnode = rb_entry(node, struct regcache_rbtree_node, node);
		for (i = 0; i < rbnode->blklen; i++) {

		if (rbnode->base_reg < min)
			continue;
		if (rbnode->base_reg > max)
			break;
		if (rbnode->base_reg + rbnode->blklen < min)
			continue;

		if (min < rbnode->base_reg + rbnode->blklen)
			base = min - rbnode->base_reg;
		else
			base = 0;

		if (max < rbnode->base_reg + rbnode->blklen)
			end = rbnode->base_reg + rbnode->blklen - max;
		else
			end = rbnode->blklen;

		for (i = base; i < end; i++) {
			regtmp = rbnode->base_reg + i;
			val = regcache_rbtree_get_register(rbnode, i,
							   map->cache_word_size);
+1 −1
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ int regcache_sync(struct regmap *map)
	}
	map->cache_bypass = 0;

	ret = map->cache_ops->sync(map);
	ret = map->cache_ops->sync(map, 0, map->max_register);

	if (ret == 0)
		map->cache_dirty = false;