summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2014-02-05 22:15:28 -0800
committerAleksandr Frid <afrid@nvidia.com>2014-02-10 10:48:32 -0800
commitc7dc53a6ac9fdb26a7224cbbe0fa44c7f5286db2 (patch)
treee63c7a68371124561b0da8d5a018921ee2591ef1 /drivers/regulator
parente4a807c4759cd172eb67b3161e9d02af34922485 (diff)
regulator: Optimize set voltage for regmap users
If regulator voltage selection register includes bits other than selector itself, it is pretty common to program those bits once, and keep them unchanged after initialization. In this case value of the entire VSEL register can be constructed by combining persistent and variable selector bits, and then directly written to the register without extra read access required for read-modify-write update. This commit has added persistency fields to the regulator descriptor. If VSEL is persistent, regulator_set_voltage_sel_regmap() interface calls regmap_write() instead of regmap_update_bits(). As a result for volatile VSEL register number of bytes transferred over the regmap bus is reduced at least by 50% (commonly read transaction is longer than its write counterpart). No significant saving for cached VSEL register. If any non-selector bit is not persistent, VSEL persistency fields must be cleared. Bug 1454969 Change-Id: Ib37d661f8929984ea642b8983c1fad84f61360b4 Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/364697 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/core.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index eb38288a6959..e8dfbdd4662a 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2542,8 +2542,14 @@ int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
sel <<= ffs(rdev->desc->vsel_mask) - 1;
- ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
- rdev->desc->vsel_mask, sel);
+ if (rdev->desc->vsel_persist) {
+ sel &= rdev->desc->vsel_mask;
+ sel |= ~rdev->desc->vsel_mask & rdev->desc->vsel_persist_val;
+ ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, sel);
+ } else {
+ ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+ rdev->desc->vsel_mask, sel);
+ }
if (ret)
return ret;