regmap: call regmap_raw_multi_reg_write from regcache sync

Call regmap_raw_multi_reg_write API from regcache sync to sync
multiple registers to the hardware if bus interface supports
multi register write. This change will help in reducing the
latency for syncing the registers to the hardware.

Change-Id: I94d19434dc7465434f10db9f7bd62fcc8246d845
Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org>
This commit is contained in:
Sudheer Papothi 2015-08-29 09:03:56 +05:30 committed by Gerrit - the friendly Code Review server
parent a05624fe92
commit 5907b03316
1 changed files with 52 additions and 3 deletions

View File

@ -605,6 +605,51 @@ static int regcache_sync_block_raw_flush(struct regmap *map, const void **data,
return ret;
}
static int regcache_sync_block_raw_multi_reg(struct regmap *map, void *block,
unsigned int block_base,
unsigned int start,
unsigned int end)
{
unsigned int i, val;
unsigned int regtmp = 0;
int ret = 0;
struct reg_default *regs;
size_t num_regs = ((end - start) + 1);
regs = kcalloc(num_regs, sizeof(struct reg_default), GFP_KERNEL);
if (!regs)
return -ENOMEM;
num_regs = 0;
for (i = start; i < end; i++) {
regtmp = block_base + (i * map->reg_stride);
/* skip registers that are not defined/available */
if (!regcache_reg_present(map, regtmp))
continue;
val = regcache_get_val(map, block, i);
/* Is this the hardware default? If so skip. */
ret = regcache_lookup_reg(map, regtmp);
if (ret >= 0 && val == map->reg_defaults[ret].def) {
continue;
} else {
regs[num_regs].reg = regtmp;
regs[num_regs].def = val;
num_regs += 1;
}
}
ret = 0;
if (num_regs) {
dev_dbg(map->dev, "%s: start: 0x%x - end: 0x%x\n",
__func__, regs[0].reg, regs[num_regs-1].reg);
ret = _regmap_raw_multi_reg_write(map, regs, num_regs);
}
kfree(regs);
return ret;
}
static int regcache_sync_block_raw(struct regmap *map, void *block,
unsigned int block_base, unsigned int start,
unsigned int end)
@ -652,9 +697,13 @@ int regcache_sync_block(struct regmap *map, void *block,
unsigned int block_base, unsigned int start,
unsigned int end)
{
if (regmap_can_raw_write(map))
return regcache_sync_block_raw(map, block, block_base,
start, end);
if (regmap_can_raw_write(map) && map->can_multi_write)
return regcache_sync_block_raw_multi_reg(map, block,
block_base, start,
end);
else if (regmap_can_raw_write(map) && !map->use_single_rw)
return regcache_sync_block_raw(map, block,
block_base, start, end);
else
return regcache_sync_block_single(map, block, block_base,
start, end);