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:
parent
925b220731
commit
5f7e5f22d0
1 changed files with 53 additions and 1 deletions
|
|
@ -731,6 +731,53 @@ 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 long *cache_present,
|
||||
unsigned int block_base,
|
||||
unsigned int start,
|
||||
unsigned int end)
|
||||
{
|
||||
unsigned int i, val;
|
||||
unsigned int regtmp = 0;
|
||||
int ret = 0;
|
||||
struct reg_sequence *regs;
|
||||
size_t num_regs = ((end - start) + 1);
|
||||
|
||||
regs = kcalloc(num_regs, sizeof(struct reg_sequence), 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(cache_present, i))
|
||||
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;
|
||||
regs[num_regs].delay_us = 0;
|
||||
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 long *cache_present,
|
||||
unsigned int block_base, unsigned int start,
|
||||
|
|
@ -778,7 +825,12 @@ 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) && !map->use_single_write)
|
||||
if (regmap_can_raw_write(map) && map->can_multi_write)
|
||||
return regcache_sync_block_raw_multi_reg(map, block,
|
||||
cache_present,
|
||||
block_base, start,
|
||||
end);
|
||||
else if (regmap_can_raw_write(map) && !map->use_single_write)
|
||||
return regcache_sync_block_raw(map, block, cache_present,
|
||||
block_base, start, end);
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in a new issue