regmap: add regmap_update_bits_lazy
Colin Patrick McCabe [Thu, 20 Oct 2011 21:44:17 +0000 (14:44 -0700)]
Add regmap_update_bits_lazy. Like regmap_update_bits, this performs a
read-modify-write cycle on a regmap register, but it skips the write if
nothing has changed.

Change-Id: Id075f711770a6bf15dea9ae085593fef268491ac
Signed-off-by: Colin Patrick McCabe <cmccabe@nvidia.com>
Reviewed-on: http://git-master/r/59460
Reviewed-by: Dan Willemsen <dwillemsen@nvidia.com>

Rebase-Id: R93e1c3cf4a506cb17346f4e981a60350846a856e

drivers/base/regmap/regmap.c
include/linux/regmap.h

index 158eb1b..a7c794c 100644 (file)
@@ -791,6 +791,42 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
 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);
+
+/**
  * regmap_update_bits_check: Perform a read/modify/write cycle on the
  *                           register map and report if updated
  *
index 7cb21e8..e5b991b 100644 (file)
@@ -152,6 +152,8 @@ 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);
 int regmap_update_bits_check(struct regmap *map, unsigned int reg,
                             unsigned int mask, unsigned int val,
                             bool *change);