diff options
author | Alex Frid <afrid@nvidia.com> | 2014-02-05 22:15:28 -0800 |
---|---|---|
committer | Aleksandr Frid <afrid@nvidia.com> | 2014-02-10 10:48:32 -0800 |
commit | c7dc53a6ac9fdb26a7224cbbe0fa44c7f5286db2 (patch) | |
tree | e63c7a68371124561b0da8d5a018921ee2591ef1 /drivers/regulator | |
parent | e4a807c4759cd172eb67b3161e9d02af34922485 (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.c | 10 |
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; |