Merge remote-tracking branches 'regmap/topic/cache', 'regmap/topic/irq', 'regmap...
authorMark Brown <broonie@linaro.org>
Fri, 28 Mar 2014 11:50:43 +0000 (11:50 +0000)
committerMark Brown <broonie@linaro.org>
Fri, 28 Mar 2014 11:50:43 +0000 (11:50 +0000)
1  2  3  4  5  6  7  8 
drivers/base/regmap/regcache.c
drivers/base/regmap/regmap.c
include/linux/regmap.h

index dd56177b7010823407a6ec4074c307eac9ad5ec2,a9d8d7be6aa31cb79ee066a247e24e11e7271395,d4dd77134814bac1a8ba2bc91a817c1cc2002454,d4dd77134814bac1a8ba2bc91a817c1cc2002454,d4dd77134814bac1a8ba2bc91a817c1cc2002454,d4dd77134814bac1a8ba2bc91a817c1cc2002454,d4dd77134814bac1a8ba2bc91a817c1cc2002454,16426aa1457c31e236f65310d253990b593852c7..29b4128da0b08ce6b8eda048557ed9093b07efa0
@@@@@@@@@ -249,11 -249,12 -249,11 -249,11 -249,11 -249,11 -249,11 -249,11 +249,12 @@@@@@@@@ static int regcache_default_sync(struc
        {
                unsigned int reg;
        
- ------        for (reg = min; reg <= max; reg++) {
+ ++++++        for (reg = min; reg <= max; reg += map->reg_stride) {
                        unsigned int val;
                        int ret;
        
- ------                if (regmap_volatile(map, reg))
+ ++++++                if (regmap_volatile(map, reg) ||
+ ++++++                    !regmap_writeable(map, reg))
                                continue;
        
                        ret = regcache_read(map, reg, &val);
@@@@@@@@@ -312,10 -313,10 -312,10 -312,10 -312,10 -312,10 -312,10 -312,6 +313,6 @@@@@@@@@ int regcache_sync(struct regmap *map
                /* Apply any patch first */
                map->cache_bypass = 1;
                for (i = 0; i < map->patch_regs; i++) {
-------                 if (map->patch[i].reg % map->reg_stride) {
-------                         ret = -EINVAL;
-------                         goto out;
-------                 }
                        ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
                        if (ret != 0) {
                                dev_err(map->dev, "Failed to write %x = %x: %d\n",
@@@@@@@@@ -636,10 -637,10 -636,10 -636,10 -636,10 -636,10 -636,10 -632,10 +633,10 @@@@@@@@@ static int regcache_sync_block_raw_flus
                if (*data == NULL)
                        return 0;
        
 -------        count = cur - base;
 +++++++        count = (cur - base) / map->reg_stride;
        
                dev_dbg(map->dev, "Writing %zu bytes for %d registers from 0x%x-0x%x\n",
 -------                count * val_bytes, count, base, cur - 1);
 +++++++                count * val_bytes, count, base, cur - map->reg_stride);
        
                map->cache_bypass = 1;
        
index 92d9b79ff93eda07970071f384403004c9bab901,6a19515f8a458b3719fce7325f265a60a4d147a4,6a19515f8a458b3719fce7325f265a60a4d147a4,35077374f38b3b5031d20c276423780bba531a9f,6a19515f8a458b3719fce7325f265a60a4d147a4,43065ceff90f9402f03e752910eeb44c597fa122,4b2ed0c9e80dba4aaaf6257fb2ce1816c383893a,c69bbc06dfbb58b8fe727f17d41d766343cd2bec..d0a072463a04ff1c4d3f83cbd66de587be4c5e44
@@@@@@@@@ -380,6 -380,6 -380,6 -380,6 -380,6 -380,28 -380,6 -380,6 +380,28 @@@@@@@@@ static void regmap_range_exit(struct re
                kfree(map->selector_work_buf);
        }
        
+++++ ++int regmap_attach_dev(struct device *dev, struct regmap *map,
+++++ ++                      const struct regmap_config *config)
+++++ ++{
+++++ ++        struct regmap **m;
+++++ ++
+++++ ++        map->dev = dev;
+++++ ++
+++++ ++        regmap_debugfs_init(map, config->name);
+++++ ++
+++++ ++        /* Add a devres resource for dev_get_regmap() */
+++++ ++        m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL);
+++++ ++        if (!m) {
+++++ ++                regmap_debugfs_exit(map);
+++++ ++                return -ENOMEM;
+++++ ++        }
+++++ ++        *m = map;
+++++ ++        devres_add(dev, m);
+++++ ++
+++++ ++        return 0;
+++++ ++}
+++++ ++EXPORT_SYMBOL_GPL(regmap_attach_dev);
+++++ ++
        /**
         * regmap_init(): Initialise register map
         *
@@@@@@@@@ -397,7 -397,7 -397,7 -397,7 -397,7 -419,7 -397,7 -397,7 +419,7 @@@@@@@@@ struct regmap *regmap_init(struct devic
                                   void *bus_context,
                                   const struct regmap_config *config)
        {
----- --        struct regmap *map, **m;
+++++ ++        struct regmap *map;
                int ret = -EINVAL;
                enum regmap_endian reg_endian, val_endian;
                int i, j;
                else
                        map->reg_stride = 1;
                map->use_single_rw = config->use_single_rw;
+++++++         map->can_multi_write = config->can_multi_write;
                map->dev = dev;
                map->bus = bus;
                map->bus_context = bus_context;
@@@@@@@@@ -718,7 -718,7 -718,7 -718,7 -718,7 -740,7 -718,7 -719,7 +741,7 @@@@@@@@@ skip_format_initialization
                        new->window_start = range_cfg->window_start;
                        new->window_len = range_cfg->window_len;
        
 -------                if (_regmap_range_add(map, new) == false) {
 +++++++                if (!_regmap_range_add(map, new)) {
                                dev_err(map->dev, "Failed to add range %d\n", i);
                                kfree(new);
                                goto err_range;
                        }
                }
        
----- --        regmap_debugfs_init(map, config->name);
----- --
                ret = regcache_init(map, config);
                if (ret != 0)
                        goto err_range;
        
----- --        /* Add a devres resource for dev_get_regmap() */
----- --        m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL);
----- --        if (!m) {
----- --                ret = -ENOMEM;
----- --                goto err_debugfs;
----- --        }
----- --        *m = map;
----- --        devres_add(dev, m);
+++++ ++        if (dev)
+++++ ++                ret = regmap_attach_dev(dev, map, config);
+++++ ++                if (ret != 0)
+++++ ++                        goto err_regcache;
        
                return map;
        
----- --err_debugfs:
----- --        regmap_debugfs_exit(map);
+++++ ++err_regcache:
                regcache_exit(map);
        err_range:
                regmap_range_exit(map);
@@@@@@@@@ -1520,12 -1520,12 -1520,12 -1520,12 -1520,12 -1535,12 -1520,12 -1521,12 +1536,12 @@@@@@@@@ int regmap_bulk_write(struct regmap *ma
                if (reg % map->reg_stride)
                        return -EINVAL;
        
--- ----        map->lock(map->lock_arg);
                /*
                 * Some devices don't support bulk write, for
                 * them we have a series of single write operations.
                 */
                if (!map->bus || map->use_single_rw) {
+++ ++++                map->lock(map->lock_arg);
                        for (i = 0; i < val_count; i++) {
                                unsigned int ival;
        
                                if (ret != 0)
                                        goto out;
                        }
+++ ++++out:
+++ ++++                map->unlock(map->lock_arg);
                } else {
                        void *wval;
        
                        wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
                        if (!wval) {
--- ----                        ret = -ENOMEM;
                                dev_err(map->dev, "Error in memory allocation\n");
--- ----                        goto out;
+++ ++++                        return -ENOMEM;
                        }
                        for (i = 0; i < val_count * val_bytes; i += val_bytes)
                                map->format.parse_inplace(wval + i);
        
+++ ++++                map->lock(map->lock_arg);
                        ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
+++ ++++                map->unlock(map->lock_arg);
        
                        kfree(wval);
                }
--- ----out:
--- ----        map->unlock(map->lock_arg);
                return ret;
        }
        EXPORT_SYMBOL_GPL(regmap_bulk_write);
        
+++++++ /*
+++++++  * _regmap_raw_multi_reg_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.
+++++++  */
+++++++ static int _regmap_raw_multi_reg_write(struct regmap *map,
+++++++                                        const struct reg_default *regs,
+++++++                                        size_t num_regs)
+++++++ {
+++++++         int ret;
+++++++         void *buf;
+++++++         int i;
+++++++         u8 *u8;
+++++++         size_t val_bytes = map->format.val_bytes;
+++++++         size_t reg_bytes = map->format.reg_bytes;
+++++++         size_t pad_bytes = map->format.pad_bytes;
+++++++         size_t pair_size = reg_bytes + pad_bytes + val_bytes;
+++++++         size_t len = pair_size * num_regs;
+++++++ 
+++++++         buf = kzalloc(len, GFP_KERNEL);
+++++++         if (!buf)
+++++++                 return -ENOMEM;
+++++++ 
+++++++         /* We have to linearise by hand. */
+++++++ 
+++++++         u8 = buf;
+++++++ 
+++++++         for (i = 0; i < num_regs; i++) {
+++++++                 int reg = regs[i].reg;
+++++++                 int val = regs[i].def;
+++++++                 trace_regmap_hw_write_start(map->dev, reg, 1);
+++++++                 map->format.format_reg(u8, reg, map->reg_shift);
+++++++                 u8 += reg_bytes + pad_bytes;
+++++++                 map->format.format_val(u8, val, 0);
+++++++                 u8 += val_bytes;
+++++++         }
+++++++         u8 = buf;
+++++++         *u8 |= map->write_flag_mask;
+++++++ 
+++++++         ret = map->bus->write(map->bus_context, buf, len);
+++++++ 
+++++++         kfree(buf);
+++++++ 
+++++++         for (i = 0; i < num_regs; i++) {
+++++++                 int reg = regs[i].reg;
+++++++                 trace_regmap_hw_write_done(map->dev, reg, 1);
+++++++         }
+++++++         return ret;
+++++++ }
+++++++ 
+++++++ static unsigned int _regmap_register_page(struct regmap *map,
+++++++                                           unsigned int reg,
+++++++                                           struct regmap_range_node *range)
+++++++ {
+++++++         unsigned int win_page = (reg - range->range_min) / range->window_len;
+++++++ 
+++++++         return win_page;
+++++++ }
+++++++ 
+++++++ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
+++++++                                                struct reg_default *regs,
+++++++                                                size_t num_regs)
+++++++ {
+++++++         int ret;
+++++++         int i, n;
+++++++         struct reg_default *base;
+++++++         unsigned int this_page;
+++++++         /*
+++++++          * 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
+++++++          */
+++++++         base = regs;
+++++++         for (i = 0, n = 0; i < num_regs; i++, n++) {
+++++++                 unsigned int reg = regs[i].reg;
+++++++                 struct regmap_range_node *range;
+++++++ 
+++++++                 range = _regmap_range_lookup(map, reg);
+++++++                 if (range) {
+++++++                         unsigned int win_page = _regmap_register_page(map, reg,
+++++++                                                                       range);
+++++++ 
+++++++                         if (i == 0)
+++++++                                 this_page = win_page;
+++++++                         if (win_page != this_page) {
+++++++                                 this_page = win_page;
+++++++                                 ret = _regmap_raw_multi_reg_write(map, base, n);
+++++++                                 if (ret != 0)
+++++++                                         return ret;
+++++++                                 base += n;
+++++++                                 n = 0;
+++++++                         }
+++++++                         ret = _regmap_select_page(map, &base[n].reg, range, 1);
+++++++                         if (ret != 0)
+++++++                                 return ret;
+++++++                 }
+++++++         }
+++++++         if (n > 0)
+++++++                 return _regmap_raw_multi_reg_write(map, base, n);
+++++++         return 0;
+++++++ }
+++++++ 
+++++++ static int _regmap_multi_reg_write(struct regmap *map,
+++++++                                    const struct reg_default *regs,
+++++++                                    size_t num_regs)
+++++++ {
+++++++         int i;
+++++++         int ret;
+++++++ 
+++++++         if (!map->can_multi_write) {
+++++++                 for (i = 0; i < num_regs; i++) {
+++++++                         ret = _regmap_write(map, regs[i].reg, regs[i].def);
+++++++                         if (ret != 0)
+++++++                                 return ret;
+++++++                 }
+++++++                 return 0;
+++++++         }
+++++++ 
+++++++         if (!map->format.parse_inplace)
+++++++                 return -EINVAL;
+++++++ 
+++++++         if (map->writeable_reg)
+++++++                 for (i = 0; i < num_regs; i++) {
+++++++                         int reg = regs[i].reg;
+++++++                         if (!map->writeable_reg(map->dev, reg))
+++++++                                 return -EINVAL;
+++++++                         if (reg % map->reg_stride)
+++++++                                 return -EINVAL;
+++++++                 }
+++++++ 
+++++++         if (!map->cache_bypass) {
+++++++                 for (i = 0; i < num_regs; i++) {
+++++++                         unsigned int val = regs[i].def;
+++++++                         unsigned int reg = regs[i].reg;
+++++++                         ret = regcache_write(map, reg, val);
+++++++                         if (ret) {
+++++++                                 dev_err(map->dev,
+++++++                                 "Error in caching of register: %x ret: %d\n",
+++++++                                                                 reg, ret);
+++++++                                 return ret;
+++++++                         }
+++++++                 }
+++++++                 if (map->cache_only) {
+++++++                         map->cache_dirty = true;
+++++++                         return 0;
+++++++                 }
+++++++         }
+++++++ 
+++++++         WARN_ON(!map->bus);
+++++++ 
+++++++         for (i = 0; i < num_regs; i++) {
+++++++                 unsigned int reg = regs[i].reg;
+++++++                 struct regmap_range_node *range;
+++++++                 range = _regmap_range_lookup(map, reg);
+++++++                 if (range) {
+++++++                         size_t len = sizeof(struct reg_default)*num_regs;
+++++++                         struct reg_default *base = kmemdup(regs, len,
+++++++                                                            GFP_KERNEL);
+++++++                         if (!base)
+++++++                                 return -ENOMEM;
+++++++                         ret = _regmap_range_multi_paged_reg_write(map, base,
+++++++                                                                   num_regs);
+++++++                         kfree(base);
+++++++ 
+++++++                         return ret;
+++++++                 }
+++++++         }
+++++++         return _regmap_raw_multi_reg_write(map, regs, num_regs);
+++++++ }
+++++++ 
        /*
         * regmap_multi_reg_write(): Write multiple registers to the device
         *
+++++++  * where the set of register,value pairs are supplied in any order,
+++++++  * possibly not all in a single range.
+++++++  *
+++++++  * @map: Register map to write to
+++++++  * @regs: Array of structures containing register,value to be written
+++++++  * @num_regs: Number of registers to write
+++++++  *
+++++++  * The 'normal' block write mode will send ultimately send data on the
+++++++  * target bus as R,V1,V2,V3,..,Vn where successively higer registers are
+++++++  * addressed. However, this alternative block multi write mode will send
+++++++  * the data as R1,V1,R2,V2,..,Rn,Vn on the target bus. The target device
+++++++  * must of course support the mode.
+++++++  *
+++++++  * 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 num_regs)
+++++++ {
+++++++         int ret;
+++++++ 
+++++++         map->lock(map->lock_arg);
+++++++ 
+++++++         ret = _regmap_multi_reg_write(map, regs, num_regs);
+++++++ 
+++++++         map->unlock(map->lock_arg);
+++++++ 
+++++++         return ret;
+++++++ }
+++++++ EXPORT_SYMBOL_GPL(regmap_multi_reg_write);
+++++++ 
+++++++ /*
+++++++  * regmap_multi_reg_write_bypassed(): Write multiple registers to the
+++++++  *                                    device but not the cache
+++++++  *
         * where the set of register are supplied in any order
         *
         * @map: Register map to write to
         * 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, struct reg_default *regs,
-------                                 int num_regs)
+++++++ int regmap_multi_reg_write_bypassed(struct regmap *map,
+++++++                                     const struct reg_default *regs,
+++++++                                     int num_regs)
        {
-------         int ret = 0, i;
------- 
-------         for (i = 0; i < num_regs; i++) {
-------                 int reg = regs[i].reg;
-------                 if (reg % map->reg_stride)
-------                         return -EINVAL;
-------         }
+++++++         int ret;
+++++++         bool bypass;
        
                map->lock(map->lock_arg);
        
-------         for (i = 0; i < num_regs; i++) {
-------                 ret = _regmap_write(map, regs[i].reg, regs[i].def);
-------                 if (ret != 0)
-------                         goto out;
-------         }
------- out:
+++++++         bypass = map->cache_bypass;
+++++++         map->cache_bypass = true;
+++++++ 
+++++++         ret = _regmap_multi_reg_write(map, regs, num_regs);
+++++++ 
+++++++         map->cache_bypass = bypass;
+++++++ 
                map->unlock(map->lock_arg);
        
                return ret;
        }
------- EXPORT_SYMBOL_GPL(regmap_multi_reg_write);
+++++++ EXPORT_SYMBOL_GPL(regmap_multi_reg_write_bypassed);
        
        /**
         * regmap_raw_write_async(): Write raw values to one or more registers
@@@@@@@@@ -1736,9 -1736,6 -1736,6 -1737,6 -1736,6 -1751,6 -1736,6 -1941,6 +1957,9 @@@@@@@@@ static int _regmap_read(struct regmap *
                if (map->cache_only)
                        return -EBUSY;
        
 +++++++        if (!regmap_readable(map, reg))
 +++++++                return -EIO;
 +++++++
                ret = map->reg_read(context, reg, val);
                if (ret == 0) {
        #ifdef LOG_DEVICE
@@@@@@@@@ -1969,11 -1966,9 -1966,9 -1967,9 -1966,9 -1981,9 -1966,9 -2171,9 +2190,11 @@@@@@@@@ static int _regmap_update_bits(struct r
        
                if (tmp != orig) {
                        ret = _regmap_write(map, reg, tmp);
 -------                *change = true;
 +++++++                if (change)
 +++++++                        *change = true;
                } else {
 -------                *change = false;
 +++++++                if (change)
 +++++++                        *change = false;
                }
        
                return ret;
        int regmap_update_bits(struct regmap *map, unsigned int reg,
                               unsigned int mask, unsigned int val)
        {
 -------        bool change;
                int ret;
        
                map->lock(map->lock_arg);
 -------        ret = _regmap_update_bits(map, reg, mask, val, &change);
 +++++++        ret = _regmap_update_bits(map, reg, mask, val, NULL);
                map->unlock(map->lock_arg);
        
                return ret;
@@@@@@@@@ -2020,13 -2016,14 -2016,14 -2017,14 -2016,14 -2031,14 -2016,14 -2221,14 +2241,13 @@@@@@@@@ EXPORT_SYMBOL_GPL(regmap_update_bits)
        int regmap_update_bits_async(struct regmap *map, unsigned int reg,
                                     unsigned int mask, unsigned int val)
        {
 -------        bool change;
                int ret;
        
                map->lock(map->lock_arg);
        
                map->async = true;
        
 -------        ret = _regmap_update_bits(map, reg, mask, val, &change);
 +++++++        ret = _regmap_update_bits(map, reg, mask, val, NULL);
        
                map->async = false;
        
@@@@@@@@@ -2176,46 -2173,46 -2173,46 -2174,49 -2173,46 -2188,46 -2173,46 -2378,40 +2397,43 @@@@@@@@@ EXPORT_SYMBOL_GPL(regmap_async_complete
         * apply them immediately.  Typically this is used to apply
         * corrections to be applied to the device defaults on startup, such
         * as the updates some vendors provide to undocumented registers.
+++ ++++ *
+++ ++++ * 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 num_regs)
        {
                struct reg_default *p;
-------         int i, ret;
+++++++         int ret;
                bool bypass;
        
                if (WARN_ONCE(num_regs <= 0, "invalid registers number (%d)\n",
                    num_regs))
                        return 0;
        
--- ---         map->lock(map->lock_arg);
--- --- 
--- ---         bypass = map->cache_bypass;
--- --- 
--- ---         map->cache_bypass = true;
--- ---         map->async = true;
--- --- 
--- ---         /* Write out first; it's useful to apply even if we fail later. */
--- ---         for (i = 0; i < num_regs; i++) {
--- ---                 ret = _regmap_write(map, regs[i].reg, regs[i].def);
--- ---                 if (ret != 0) {
--- ---                         dev_err(map->dev, "Failed to write %x = %x: %d\n",
--- ---                                 regs[i].reg, regs[i].def, ret);
--- ---                         goto out;
--- ---                 }
--- ---         }
--- --- 
       +        p = krealloc(map->patch,
       +                     sizeof(struct reg_default) * (map->patch_regs + num_regs),
       +                     GFP_KERNEL);
       +        if (p) {
       +                memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
       +                map->patch = p;
       +                map->patch_regs += num_regs;
       +        } else {
--- ---                 ret = -ENOMEM;
+++ ++++                return -ENOMEM;
       +        }
       +
+++ +++         map->lock(map->lock_arg);
+++ +++ 
+++ +++         bypass = map->cache_bypass;
+++ +++ 
+++ +++         map->cache_bypass = true;
+++ +++         map->async = true;
+++ +++ 
   -            /* Write out first; it's useful to apply even if we fail later. */
   -            for (i = 0; i < num_regs; i++) {
   -                    ret = _regmap_write(map, regs[i].reg, regs[i].def);
   -                    if (ret != 0) {
   -                            dev_err(map->dev, "Failed to write %x = %x: %d\n",
   -                                    regs[i].reg, regs[i].def, ret);
   -                            goto out;
   -                    }
   -            }
+++++++         ret = _regmap_multi_reg_write(map, regs, num_regs);
+++++++         if (ret != 0)
+++++++                 goto out;
+++ +++ 
       -        p = krealloc(map->patch,
       -                     sizeof(struct reg_default) * (map->patch_regs + num_regs),
       -                     GFP_KERNEL);
       -        if (p) {
       -                memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
       -                map->patch = p;
       -                map->patch_regs += num_regs;
       -        } else {
       -                ret = -ENOMEM;
       -        }
       -
        out:
                map->async = false;
                map->cache_bypass = bypass;
@@@@@@@@@ -2243,6 -2240,6 -2240,6 -2244,6 -2240,6 -2255,6 -2240,18 -2439,6 +2461,18 @@@@@@@@@ int regmap_get_val_bytes(struct regmap 
        }
        EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
        
++++++ +int regmap_parse_val(struct regmap *map, const void *buf,
++++++ +                        unsigned int *val)
++++++ +{
++++++ +        if (!map->format.parse_val)
++++++ +                return -EINVAL;
++++++ +
++++++ +        *val = map->format.parse_val(buf);
++++++ +
++++++ +        return 0;
++++++ +}
++++++ +EXPORT_SYMBOL_GPL(regmap_parse_val);
++++++ +
        static int __init regmap_initcall(void)
        {
                regmap_debugfs_initcall();
diff --combined include/linux/regmap.h
index 4149f1a9b00320dfeea8768817b2adbd2d1a4da2,4149f1a9b00320dfeea8768817b2adbd2d1a4da2,4149f1a9b00320dfeea8768817b2adbd2d1a4da2,4149f1a9b00320dfeea8768817b2adbd2d1a4da2,4149f1a9b00320dfeea8768817b2adbd2d1a4da2,fa4d079fa44c31925d2d023575f12ba173ed14a0,3e1a2e4a92ad0e920900b65db648159fd347532b,220aec66006478075d62dfe6a6f9f855caa7c5bd..5ad86eacef0d4c17bae725f9a0eb1ebf09cd48a6
@@@@@@@@@ -164,6 -164,6 -164,6 -164,6 -164,6 -164,6 -164,6 -164,9 +164,9 @@@@@@@@@ typedef void (*regmap_unlock)(void *)
         * @use_single_rw: If set, converts the bulk read and write operations into
         *                  a series of single read and write operations. This is useful
         *                  for device that does not support bulk read and write.
+++++++  * @can_multi_write: If set, the device supports the multi write mode of bulk
+++++++  *                   write operations, if clear multi write requests will be
+++++++  *                   split into individual write operations
         *
         * @cache_type: The actual cache type.
         * @reg_defaults_raw: Power on reset values for registers (for use with
@@@@@@@@@ -215,6 -215,6 -215,6 -215,6 -215,6 -215,6 -215,6 -218,7 +218,7 @@@@@@@@@ struct regmap_config 
                u8 write_flag_mask;
        
                bool use_single_rw;
+++++++         bool can_multi_write;
        
                enum regmap_endian reg_format_endian;
                enum regmap_endian val_format_endian;
@@@@@@@@@ -317,6 -317,6 -317,6 -317,6 -317,6 -317,8 -317,6 -321,6 +321,8 @@@@@@@@@ struct regmap *regmap_init(struct devic
                                   const struct regmap_bus *bus,
                                   void *bus_context,
                                   const struct regmap_config *config);
+++++ ++int regmap_attach_dev(struct device *dev, struct regmap *map,
+++++ ++                                 const struct regmap_config *config);
        struct regmap *regmap_init_i2c(struct i2c_client *i2c,
                                       const struct regmap_config *config);
        struct regmap *regmap_init_spi(struct spi_device *dev,
@@@@@@@@@ -386,8 -386,8 -386,8 -386,8 -386,8 -388,8 -386,8 -390,11 +392,11 @@@@@@@@@ int regmap_raw_write(struct regmap *map
                             const void *val, size_t val_len);
        int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
                                size_t val_count);
------- int regmap_multi_reg_write(struct regmap *map, struct reg_default *regs,
+++++++ int regmap_multi_reg_write(struct regmap *map, const struct reg_default *regs,
                                int num_regs);
+++++++ int regmap_multi_reg_write_bypassed(struct regmap *map,
+++++++                                     const struct reg_default *regs,
+++++++                                     int num_regs);
        int regmap_raw_write_async(struct regmap *map, unsigned int reg,
                                   const void *val, size_t val_len);
        int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
@@@@@@@@@ -423,6 -423,6 -423,6 -423,6 -423,6 -425,6 -423,8 -430,6 +432,8 @@@@@@@@@ bool regmap_check_range_table(struct re
        
        int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
                                  int num_regs);
++++++ +int regmap_parse_val(struct regmap *map, const void *buf,
++++++ +                                unsigned int *val);
        
        static inline bool regmap_reg_in_range(unsigned int reg,
                                               const struct regmap_range *range)
@@@@@@@@@ -695,6 -695,6 -695,6 -695,6 -695,6 -697,6 -697,13 -702,6 +706,13 @@@@@@@@@ static inline int regmap_register_patch
                return -EINVAL;
        }
        
++++++ +static inline int regmap_parse_val(struct regmap *map, const void *buf,
++++++ +                                unsigned int *val)
++++++ +{
++++++ +        WARN_ONCE(1, "regmap API is disabled");
++++++ +        return -EINVAL;
++++++ +}
++++++ +
        static inline struct regmap *dev_get_regmap(struct device *dev,
                                                    const char *name)
        {