diff options
-rw-r--r-- | drivers/base/regmap/regmap.c | 36 | ||||
-rw-r--r-- | include/linux/regmap.h | 2 |
2 files changed, 38 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 20663f8dae45..843f722ff9cd 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -450,3 +450,39 @@ out: return ret; } EXPORT_SYMBOL_GPL(regmap_update_bits); + +/** + * remap_update_bits_lazy: Perform a read/modify/write cycle on the register + * map. Only write new contents if they differ from the previous ones. + * + * @map: Register map to update + * @reg: Register to update + * @mask: Bitmask to change + * @val: New value for bitmask + * + * Returns zero for success, a negative number on error. + */ +int regmap_update_bits_lazy(struct regmap *map, unsigned int reg, + unsigned int mask, unsigned int val) +{ + int ret, new; + unsigned int tmp; + + mutex_lock(&map->lock); + + ret = _regmap_read(map, reg, &tmp); + if (ret != 0) + goto out; + + new = tmp & ~mask; + new |= val & mask; + if (new != tmp) { + ret = _regmap_write(map, reg, new); + } + +out: + mutex_unlock(&map->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(regmap_update_bits_lazy); diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 60a65cd7e1a0..04e59205dec9 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -78,5 +78,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, size_t val_count); int regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val); +int regmap_update_bits_lazy(struct regmap *map, unsigned int reg, + unsigned int mask, unsigned int val); #endif |