These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / base / regmap / regmap.c
index 1c76dcb..4ac63c0 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of.h>
 #include <linux/rbtree.h>
 #include <linux/sched.h>
+#include <linux/delay.h>
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
@@ -34,7 +35,7 @@
 
 static int _regmap_update_bits(struct regmap *map, unsigned int reg,
                               unsigned int mask, unsigned int val,
-                              bool *change);
+                              bool *change, bool force_write);
 
 static int _regmap_bus_reg_read(void *context, unsigned int reg,
                                unsigned int *val);
@@ -93,6 +94,9 @@ bool regmap_writeable(struct regmap *map, unsigned int reg)
 
 bool regmap_readable(struct regmap *map, unsigned int reg)
 {
+       if (!map->reg_read)
+               return false;
+
        if (map->max_register && reg > map->max_register)
                return false;
 
@@ -515,22 +519,12 @@ enum regmap_endian regmap_get_val_endian(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(regmap_get_val_endian);
 
-/**
- * regmap_init(): Initialise register map
- *
- * @dev: Device that will be interacted with
- * @bus: Bus-specific callbacks to use with device
- * @bus_context: Data passed to bus-specific callbacks
- * @config: Configuration for register map
- *
- * The return value will be an ERR_PTR() on error or a valid pointer to
- * a struct regmap.  This function should generally not be called
- * directly, it should be called by bus-specific init functions.
- */
-struct regmap *regmap_init(struct device *dev,
-                          const struct regmap_bus *bus,
-                          void *bus_context,
-                          const struct regmap_config *config)
+struct regmap *__regmap_init(struct device *dev,
+                            const struct regmap_bus *bus,
+                            void *bus_context,
+                            const struct regmap_config *config,
+                            struct lock_class_key *lock_key,
+                            const char *lock_name)
 {
        struct regmap *map;
        int ret = -EINVAL;
@@ -556,13 +550,27 @@ struct regmap *regmap_init(struct device *dev,
                        spin_lock_init(&map->spinlock);
                        map->lock = regmap_lock_spinlock;
                        map->unlock = regmap_unlock_spinlock;
+                       lockdep_set_class_and_name(&map->spinlock,
+                                                  lock_key, lock_name);
                } else {
                        mutex_init(&map->mutex);
                        map->lock = regmap_lock_mutex;
                        map->unlock = regmap_unlock_mutex;
+                       lockdep_set_class_and_name(&map->mutex,
+                                                  lock_key, lock_name);
                }
                map->lock_arg = map;
        }
+
+       /*
+        * When we write in fast-paths with regmap_bulk_write() don't allocate
+        * scratch buffers with sleeping allocations.
+        */
+       if ((bus && bus->fast_io) || config->fast_io)
+               map->alloc_flags = GFP_ATOMIC;
+       else
+               map->alloc_flags = GFP_KERNEL;
+
        map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
        map->format.pad_bytes = config->pad_bits / 8;
        map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
@@ -573,8 +581,13 @@ struct regmap *regmap_init(struct device *dev,
                map->reg_stride = config->reg_stride;
        else
                map->reg_stride = 1;
-       map->use_single_rw = config->use_single_rw;
-       map->can_multi_write = config->can_multi_write;
+       map->use_single_read = config->use_single_rw || !bus || !bus->read;
+       map->use_single_write = config->use_single_rw || !bus || !bus->write;
+       map->can_multi_write = config->can_multi_write && bus && bus->write;
+       if (bus) {
+               map->max_raw_read = bus->max_raw_read;
+               map->max_raw_write = bus->max_raw_write;
+       }
        map->dev = dev;
        map->bus = bus;
        map->bus_context = bus_context;
@@ -616,6 +629,7 @@ struct regmap *regmap_init(struct device *dev,
                goto skip_format_initialization;
        } else {
                map->reg_read  = _regmap_bus_read;
+               map->reg_update_bits = bus->reg_update_bits;
        }
 
        reg_endian = regmap_get_reg_endian(bus, config);
@@ -763,7 +777,7 @@ struct regmap *regmap_init(struct device *dev,
                if ((reg_endian != REGMAP_ENDIAN_BIG) ||
                    (val_endian != REGMAP_ENDIAN_BIG))
                        goto err_map;
-               map->use_single_rw = true;
+               map->use_single_write = true;
        }
 
        if (!map->format.format_write &&
@@ -899,30 +913,19 @@ err_map:
 err:
        return ERR_PTR(ret);
 }
-EXPORT_SYMBOL_GPL(regmap_init);
+EXPORT_SYMBOL_GPL(__regmap_init);
 
 static void devm_regmap_release(struct device *dev, void *res)
 {
        regmap_exit(*(struct regmap **)res);
 }
 
-/**
- * devm_regmap_init(): Initialise managed register map
- *
- * @dev: Device that will be interacted with
- * @bus: Bus-specific callbacks to use with device
- * @bus_context: Data passed to bus-specific callbacks
- * @config: Configuration for register map
- *
- * The return value will be an ERR_PTR() on error or a valid pointer
- * to a struct regmap.  This function should generally not be called
- * directly, it should be called by bus-specific init functions.  The
- * map will be automatically freed by the device management code.
- */
-struct regmap *devm_regmap_init(struct device *dev,
-                               const struct regmap_bus *bus,
-                               void *bus_context,
-                               const struct regmap_config *config)
+struct regmap *__devm_regmap_init(struct device *dev,
+                                 const struct regmap_bus *bus,
+                                 void *bus_context,
+                                 const struct regmap_config *config,
+                                 struct lock_class_key *lock_key,
+                                 const char *lock_name)
 {
        struct regmap **ptr, *regmap;
 
@@ -930,7 +933,8 @@ struct regmap *devm_regmap_init(struct device *dev,
        if (!ptr)
                return ERR_PTR(-ENOMEM);
 
-       regmap = regmap_init(dev, bus, bus_context, config);
+       regmap = __regmap_init(dev, bus, bus_context, config,
+                              lock_key, lock_name);
        if (!IS_ERR(regmap)) {
                *ptr = regmap;
                devres_add(dev, ptr);
@@ -940,7 +944,7 @@ struct regmap *devm_regmap_init(struct device *dev,
 
        return regmap;
 }
-EXPORT_SYMBOL_GPL(devm_regmap_init);
+EXPORT_SYMBOL_GPL(__devm_regmap_init);
 
 static void regmap_field_init(struct regmap_field *rm_field,
        struct regmap *regmap, struct reg_field reg_field)
@@ -1178,7 +1182,7 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
                ret = _regmap_update_bits(map, range->selector_reg,
                                          range->selector_mask,
                                          win_page << range->selector_shift,
-                                         &page_chg);
+                                         &page_chg, false);
 
                map->work_buf = orig_work_buf;
 
@@ -1382,10 +1386,33 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
  */
 bool regmap_can_raw_write(struct regmap *map)
 {
-       return map->bus && map->format.format_val && map->format.format_reg;
+       return map->bus && map->bus->write && map->format.format_val &&
+               map->format.format_reg;
 }
 EXPORT_SYMBOL_GPL(regmap_can_raw_write);
 
+/**
+ * regmap_get_raw_read_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_read_max(struct regmap *map)
+{
+       return map->max_raw_read;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_read_max);
+
+/**
+ * regmap_get_raw_write_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_write_max(struct regmap *map)
+{
+       return map->max_raw_write;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_write_max);
+
 static int _regmap_bus_formatted_write(void *context, unsigned int reg,
                                       unsigned int val)
 {
@@ -1555,6 +1582,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
                return -EINVAL;
        if (val_len % map->format.val_bytes)
                return -EINVAL;
+       if (map->max_raw_write && map->max_raw_write > val_len)
+               return -E2BIG;
 
        map->lock(map->lock_arg);
 
@@ -1624,6 +1653,18 @@ int regmap_fields_write(struct regmap_field *field, unsigned int id,
 }
 EXPORT_SYMBOL_GPL(regmap_fields_write);
 
+int regmap_fields_force_write(struct regmap_field *field, unsigned int id,
+                       unsigned int val)
+{
+       if (id >= field->id_size)
+               return -EINVAL;
+
+       return regmap_write_bits(field->regmap,
+                                 field->reg + (field->id_offset * id),
+                                 field->mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_fields_force_write);
+
 /**
  * regmap_fields_update_bits():        Perform a read/modify/write cycle
  *                              on the register field
@@ -1669,6 +1710,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 {
        int ret = 0, i;
        size_t val_bytes = map->format.val_bytes;
+       size_t total_size = val_bytes * val_count;
 
        if (map->bus && !map->format.parse_inplace)
                return -EINVAL;
@@ -1677,9 +1719,15 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 
        /*
         * Some devices don't support bulk write, for
-        * them we have a series of single write operations.
+        * them we have a series of single write operations in the first two if
+        * blocks.
+        *
+        * The first if block is used for memory mapped io. It does not allow
+        * val_bytes of 3 for example.
+        * The second one is used for busses which do not have this limitation
+        * and can write arbitrary value lengths.
         */
-       if (!map->bus || map->use_single_rw) {
+       if (!map->bus) {
                map->lock(map->lock_arg);
                for (i = 0; i < val_count; i++) {
                        unsigned int ival;
@@ -1711,13 +1759,45 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
                }
 out:
                map->unlock(map->lock_arg);
+       } else if (map->use_single_write ||
+                  (map->max_raw_write && map->max_raw_write < total_size)) {
+               int chunk_stride = map->reg_stride;
+               size_t chunk_size = val_bytes;
+               size_t chunk_count = val_count;
+
+               if (!map->use_single_write) {
+                       chunk_size = map->max_raw_write;
+                       if (chunk_size % val_bytes)
+                               chunk_size -= chunk_size % val_bytes;
+                       chunk_count = total_size / chunk_size;
+                       chunk_stride *= chunk_size / val_bytes;
+               }
+
+               map->lock(map->lock_arg);
+               /* Write as many bytes as possible with chunk_size */
+               for (i = 0; i < chunk_count; i++) {
+                       ret = _regmap_raw_write(map,
+                                               reg + (i * chunk_stride),
+                                               val + (i * chunk_size),
+                                               chunk_size);
+                       if (ret)
+                               break;
+               }
+
+               /* Write remaining bytes */
+               if (!ret && chunk_size * i < total_size) {
+                       ret = _regmap_raw_write(map, reg + (i * chunk_stride),
+                                               val + (i * chunk_size),
+                                               total_size - i * chunk_size);
+               }
+               map->unlock(map->lock_arg);
        } else {
                void *wval;
 
                if (!val_count)
                        return -EINVAL;
 
-               wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
+               wval = kmemdup(val, val_count * val_bytes, map->alloc_flags);
                if (!wval) {
                        dev_err(map->dev, "Error in memory allocation\n");
                        return -ENOMEM;
@@ -1740,10 +1820,10 @@ EXPORT_SYMBOL_GPL(regmap_bulk_write);
  *
  * the (register,newvalue) pairs in regs have not been formatted, but
  * they are all in the same page and have been changed to being page
- * relative. The page register has been written if that was neccessary.
+ * relative. The page register has been written if that was necessary.
  */
 static int _regmap_raw_multi_reg_write(struct regmap *map,
-                                      const struct reg_default *regs,
+                                      const struct reg_sequence *regs,
                                       size_t num_regs)
 {
        int ret;
@@ -1768,8 +1848,8 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
        u8 = buf;
 
        for (i = 0; i < num_regs; i++) {
-               int reg = regs[i].reg;
-               int val = regs[i].def;
+               unsigned int reg = regs[i].reg;
+               unsigned int val = regs[i].def;
                trace_regmap_hw_write_start(map, reg, 1);
                map->format.format_reg(u8, reg, map->reg_shift);
                u8 += reg_bytes + pad_bytes;
@@ -1800,17 +1880,19 @@ static unsigned int _regmap_register_page(struct regmap *map,
 }
 
 static int _regmap_range_multi_paged_reg_write(struct regmap *map,
-                                              struct reg_default *regs,
+                                              struct reg_sequence *regs,
                                               size_t num_regs)
 {
        int ret;
        int i, n;
-       struct reg_default *base;
+       struct reg_sequence *base;
        unsigned int this_page = 0;
+       unsigned int page_change = 0;
        /*
         * the set of registers are not neccessarily in order, but
         * since the order of write must be preserved this algorithm
-        * chops the set each time the page changes
+        * chops the set each time the page changes. This also applies
+        * if there is a delay required at any point in the sequence.
         */
        base = regs;
        for (i = 0, n = 0; i < num_regs; i++, n++) {
@@ -1826,16 +1908,48 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
                                this_page = win_page;
                        if (win_page != this_page) {
                                this_page = win_page;
+                               page_change = 1;
+                       }
+               }
+
+               /* If we have both a page change and a delay make sure to
+                * write the regs and apply the delay before we change the
+                * page.
+                */
+
+               if (page_change || regs[i].delay_us) {
+
+                               /* For situations where the first write requires
+                                * a delay we need to make sure we don't call
+                                * raw_multi_reg_write with n=0
+                                * This can't occur with page breaks as we
+                                * never write on the first iteration
+                                */
+                               if (regs[i].delay_us && i == 0)
+                                       n = 1;
+
                                ret = _regmap_raw_multi_reg_write(map, base, n);
                                if (ret != 0)
                                        return ret;
+
+                               if (regs[i].delay_us)
+                                       udelay(regs[i].delay_us);
+
                                base += n;
                                n = 0;
-                       }
-                       ret = _regmap_select_page(map, &base[n].reg, range, 1);
-                       if (ret != 0)
-                               return ret;
+
+                               if (page_change) {
+                                       ret = _regmap_select_page(map,
+                                                                 &base[n].reg,
+                                                                 range, 1);
+                                       if (ret != 0)
+                                               return ret;
+
+                                       page_change = 0;
+                               }
+
                }
+
        }
        if (n > 0)
                return _regmap_raw_multi_reg_write(map, base, n);
@@ -1843,7 +1957,7 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
 }
 
 static int _regmap_multi_reg_write(struct regmap *map,
-                                  const struct reg_default *regs,
+                                  const struct reg_sequence *regs,
                                   size_t num_regs)
 {
        int i;
@@ -1854,6 +1968,9 @@ static int _regmap_multi_reg_write(struct regmap *map,
                        ret = _regmap_write(map, regs[i].reg, regs[i].def);
                        if (ret != 0)
                                return ret;
+
+                       if (regs[i].delay_us)
+                               udelay(regs[i].delay_us);
                }
                return 0;
        }
@@ -1893,10 +2010,14 @@ static int _regmap_multi_reg_write(struct regmap *map,
        for (i = 0; i < num_regs; i++) {
                unsigned int reg = regs[i].reg;
                struct regmap_range_node *range;
+
+               /* Coalesce all the writes between a page break or a delay
+                * in a sequence
+                */
                range = _regmap_range_lookup(map, reg);
-               if (range) {
-                       size_t len = sizeof(struct reg_default)*num_regs;
-                       struct reg_default *base = kmemdup(regs, len,
+               if (range || regs[i].delay_us) {
+                       size_t len = sizeof(struct reg_sequence)*num_regs;
+                       struct reg_sequence *base = kmemdup(regs, len,
                                                           GFP_KERNEL);
                        if (!base)
                                return -ENOMEM;
@@ -1929,7 +2050,7 @@ static int _regmap_multi_reg_write(struct regmap *map,
  * A value of zero will be returned on success, a negative errno will be
  * returned in error cases.
  */
-int regmap_multi_reg_write(struct regmap *map, const struct reg_default *regs,
+int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs,
                           int num_regs)
 {
        int ret;
@@ -1962,7 +2083,7 @@ EXPORT_SYMBOL_GPL(regmap_multi_reg_write);
  * be returned in error cases.
  */
 int regmap_multi_reg_write_bypassed(struct regmap *map,
-                                   const struct reg_default *regs,
+                                   const struct reg_sequence *regs,
                                    int num_regs)
 {
        int ret;
@@ -2050,7 +2171,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 
        /*
         * Some buses or devices flag reads by setting the high bits in the
-        * register addresss; since it's always the high bits for all
+        * register address; since it's always the high bits for all
         * current formats we can do this here rather than in
         * formatting.  This may break if we get interesting formats.
         */
@@ -2097,8 +2218,6 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
        int ret;
        void *context = _regmap_map_get_context(map);
 
-       WARN_ON(!map->reg_read);
-
        if (!map->cache_bypass) {
                ret = regcache_read(map, reg, val);
                if (ret == 0)
@@ -2179,11 +2298,22 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
                return -EINVAL;
        if (reg % map->reg_stride)
                return -EINVAL;
+       if (val_count == 0)
+               return -EINVAL;
 
        map->lock(map->lock_arg);
 
        if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
            map->cache_type == REGCACHE_NONE) {
+               if (!map->bus->read) {
+                       ret = -ENOTSUPP;
+                       goto out;
+               }
+               if (map->max_raw_read && map->max_raw_read < val_len) {
+                       ret = -E2BIG;
+                       goto out;
+               }
+
                /* Physical block read if there's no cache involved */
                ret = _regmap_raw_read(map, reg, val, val_len);
 
@@ -2292,20 +2422,51 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
                 * Some devices does not support bulk read, for
                 * them we have a series of single read operations.
                 */
-               if (map->use_single_rw) {
-                       for (i = 0; i < val_count; i++) {
-                               ret = regmap_raw_read(map,
-                                               reg + (i * map->reg_stride),
-                                               val + (i * val_bytes),
-                                               val_bytes);
-                               if (ret != 0)
-                                       return ret;
-                       }
-               } else {
+               size_t total_size = val_bytes * val_count;
+
+               if (!map->use_single_read &&
+                   (!map->max_raw_read || map->max_raw_read > total_size)) {
                        ret = regmap_raw_read(map, reg, val,
                                              val_bytes * val_count);
                        if (ret != 0)
                                return ret;
+               } else {
+                       /*
+                        * Some devices do not support bulk read or do not
+                        * support large bulk reads, for them we have a series
+                        * of read operations.
+                        */
+                       int chunk_stride = map->reg_stride;
+                       size_t chunk_size = val_bytes;
+                       size_t chunk_count = val_count;
+
+                       if (!map->use_single_read) {
+                               chunk_size = map->max_raw_read;
+                               if (chunk_size % val_bytes)
+                                       chunk_size -= chunk_size % val_bytes;
+                               chunk_count = total_size / chunk_size;
+                               chunk_stride *= chunk_size / val_bytes;
+                       }
+
+                       /* Read bytes that fit into a multiple of chunk_size */
+                       for (i = 0; i < chunk_count; i++) {
+                               ret = regmap_raw_read(map,
+                                                     reg + (i * chunk_stride),
+                                                     val + (i * chunk_size),
+                                                     chunk_size);
+                               if (ret != 0)
+                                       return ret;
+                       }
+
+                       /* Read remaining bytes */
+                       if (chunk_size * i < total_size) {
+                               ret = regmap_raw_read(map,
+                                                     reg + (i * chunk_stride),
+                                                     val + (i * chunk_size),
+                                                     total_size - i * chunk_size);
+                               if (ret != 0)
+                                       return ret;
+                       }
                }
 
                for (i = 0; i < val_count * val_bytes; i += val_bytes)
@@ -2317,7 +2478,34 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
                                          &ival);
                        if (ret != 0)
                                return ret;
-                       map->format.format_val(val + (i * val_bytes), ival, 0);
+
+                       if (map->format.format_val) {
+                               map->format.format_val(val + (i * val_bytes), ival, 0);
+                       } else {
+                               /* Devices providing read and write
+                                * operations can use the bulk I/O
+                                * functions if they define a val_bytes,
+                                * we assume that the values are native
+                                * endian.
+                                */
+                               u32 *u32 = val;
+                               u16 *u16 = val;
+                               u8 *u8 = val;
+
+                               switch (map->format.val_bytes) {
+                               case 4:
+                                       u32[i] = ival;
+                                       break;
+                               case 2:
+                                       u16[i] = ival;
+                                       break;
+                               case 1:
+                                       u8[i] = ival;
+                                       break;
+                               default:
+                                       return -EINVAL;
+                               }
+                       }
                }
        }
 
@@ -2327,25 +2515,31 @@ EXPORT_SYMBOL_GPL(regmap_bulk_read);
 
 static int _regmap_update_bits(struct regmap *map, unsigned int reg,
                               unsigned int mask, unsigned int val,
-                              bool *change)
+                              bool *change, bool force_write)
 {
        int ret;
        unsigned int tmp, orig;
 
-       ret = _regmap_read(map, reg, &orig);
-       if (ret != 0)
-               return ret;
+       if (change)
+               *change = false;
 
-       tmp = orig & ~mask;
-       tmp |= val & mask;
-
-       if (tmp != orig) {
-               ret = _regmap_write(map, reg, tmp);
-               if (change)
+       if (regmap_volatile(map, reg) && map->reg_update_bits) {
+               ret = map->reg_update_bits(map->bus_context, reg, mask, val);
+               if (ret == 0 && change)
                        *change = true;
        } else {
-               if (change)
-                       *change = false;
+               ret = _regmap_read(map, reg, &orig);
+               if (ret != 0)
+                       return ret;
+
+               tmp = orig & ~mask;
+               tmp |= val & mask;
+
+               if (force_write || (tmp != orig)) {
+                       ret = _regmap_write(map, reg, tmp);
+                       if (ret == 0 && change)
+                               *change = true;
+               }
        }
 
        return ret;
@@ -2367,13 +2561,36 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
        int ret;
 
        map->lock(map->lock_arg);
-       ret = _regmap_update_bits(map, reg, mask, val, NULL);
+       ret = _regmap_update_bits(map, reg, mask, val, NULL, false);
        map->unlock(map->lock_arg);
 
        return ret;
 }
 EXPORT_SYMBOL_GPL(regmap_update_bits);
 
+/**
+ * regmap_write_bits: Perform a read/modify/write cycle on the register map
+ *
+ * @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_write_bits(struct regmap *map, unsigned int reg,
+                     unsigned int mask, unsigned int val)
+{
+       int ret;
+
+       map->lock(map->lock_arg);
+       ret = _regmap_update_bits(map, reg, mask, val, NULL, true);
+       map->unlock(map->lock_arg);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_write_bits);
+
 /**
  * regmap_update_bits_async: Perform a read/modify/write cycle on the register
  *                           map asynchronously
@@ -2398,7 +2615,7 @@ int regmap_update_bits_async(struct regmap *map, unsigned int reg,
 
        map->async = true;
 
-       ret = _regmap_update_bits(map, reg, mask, val, NULL);
+       ret = _regmap_update_bits(map, reg, mask, val, NULL, false);
 
        map->async = false;
 
@@ -2427,7 +2644,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
        int ret;
 
        map->lock(map->lock_arg);
-       ret = _regmap_update_bits(map, reg, mask, val, change);
+       ret = _regmap_update_bits(map, reg, mask, val, change, false);
        map->unlock(map->lock_arg);
        return ret;
 }
@@ -2460,7 +2677,7 @@ int regmap_update_bits_check_async(struct regmap *map, unsigned int reg,
 
        map->async = true;
 
-       ret = _regmap_update_bits(map, reg, mask, val, change);
+       ret = _regmap_update_bits(map, reg, mask, val, change, false);
 
        map->async = false;
 
@@ -2552,10 +2769,10 @@ EXPORT_SYMBOL_GPL(regmap_async_complete);
  * The caller must ensure that this function cannot be called
  * concurrently with either itself or regcache_sync().
  */
-int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
+int regmap_register_patch(struct regmap *map, const struct reg_sequence *regs,
                          int num_regs)
 {
-       struct reg_default *p;
+       struct reg_sequence *p;
        int ret;
        bool bypass;
 
@@ -2564,7 +2781,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
                return 0;
 
        p = krealloc(map->patch,
-                    sizeof(struct reg_default) * (map->patch_regs + num_regs),
+                    sizeof(struct reg_sequence) * (map->patch_regs + num_regs),
                     GFP_KERNEL);
        if (p) {
                memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
@@ -2582,10 +2799,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
        map->async = true;
 
        ret = _regmap_multi_reg_write(map, regs, num_regs);
-       if (ret != 0)
-               goto out;
 
-out:
        map->async = false;
        map->cache_bypass = bypass;
 
@@ -2612,6 +2826,30 @@ int regmap_get_val_bytes(struct regmap *map)
 }
 EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
 
+/**
+ * regmap_get_max_register(): Report the max register value
+ *
+ * Report the max register value, mainly intended to for use by
+ * generic infrastructure built on top of regmap.
+ */
+int regmap_get_max_register(struct regmap *map)
+{
+       return map->max_register ? map->max_register : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(regmap_get_max_register);
+
+/**
+ * regmap_get_reg_stride(): Report the register address stride
+ *
+ * Report the register address stride, mainly intended to for use by
+ * generic infrastructure built on top of regmap.
+ */
+int regmap_get_reg_stride(struct regmap *map)
+{
+       return map->reg_stride;
+}
+EXPORT_SYMBOL_GPL(regmap_get_reg_stride);
+
 int regmap_parse_val(struct regmap *map, const void *buf,
                        unsigned int *val)
 {