Merge branch 'mfd/da9052' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Wed, 14 Dec 2011 12:02:09 +0000 (20:02 +0800)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Wed, 14 Dec 2011 12:02:09 +0000 (20:02 +0800)
drivers/base/regmap/Makefile
drivers/base/regmap/internal.h
drivers/base/regmap/regcache-indexed.c [deleted file]
drivers/base/regmap/regcache-lzo.c
drivers/base/regmap/regcache-rbtree.c
drivers/base/regmap/regcache.c
drivers/base/regmap/regmap.c
include/linux/regmap.h
include/trace/events/regmap.h

index ce2d18a6465be1d15cac7cb8a410de070d42f9cd..defd57963c84ec5d91ecb756317bb385ae1e3210 100644 (file)
@@ -1,4 +1,5 @@
-obj-$(CONFIG_REGMAP) += regmap.o regcache.o regcache-indexed.o regcache-rbtree.o regcache-lzo.o
+obj-$(CONFIG_REGMAP) += regmap.o regcache.o
+obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o
 obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
 obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
 obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
index 348ff02eb93e02a66887b59995900335f7214fc0..1a02b7537c8bbac9d59d21ee51c1361dd03c01c0 100644 (file)
@@ -74,6 +74,7 @@ struct regmap {
        struct reg_default *reg_defaults;
        const void *reg_defaults_raw;
        void *cache;
+       bool cache_dirty;
 };
 
 struct regcache_ops {
@@ -105,7 +106,7 @@ static inline void regmap_debugfs_exit(struct regmap *map) { }
 #endif
 
 /* regcache core declarations */
-int regcache_init(struct regmap *map);
+int regcache_init(struct regmap *map, const struct regmap_config *config);
 void regcache_exit(struct regmap *map);
 int regcache_read(struct regmap *map,
                       unsigned int reg, unsigned int *value);
@@ -118,10 +119,7 @@ unsigned int regcache_get_val(const void *base, unsigned int idx,
 bool regcache_set_val(void *base, unsigned int idx,
                      unsigned int val, unsigned int word_size);
 int regcache_lookup_reg(struct regmap *map, unsigned int reg);
-int regcache_insert_reg(struct regmap *map, unsigned int reg,
-                       unsigned int val);
 
-extern struct regcache_ops regcache_indexed_ops;
 extern struct regcache_ops regcache_rbtree_ops;
 extern struct regcache_ops regcache_lzo_ops;
 
diff --git a/drivers/base/regmap/regcache-indexed.c b/drivers/base/regmap/regcache-indexed.c
deleted file mode 100644 (file)
index 507731a..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Register cache access API - indexed caching support
- *
- * Copyright 2011 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/slab.h>
-
-#include "internal.h"
-
-static int regcache_indexed_read(struct regmap *map, unsigned int reg,
-                                unsigned int *value)
-{
-       int ret;
-
-       ret = regcache_lookup_reg(map, reg);
-       if (ret >= 0)
-               *value = map->reg_defaults[ret].def;
-
-       return ret;
-}
-
-static int regcache_indexed_write(struct regmap *map, unsigned int reg,
-                                 unsigned int value)
-{
-       int ret;
-
-       ret = regcache_lookup_reg(map, reg);
-       if (ret < 0)
-               return regcache_insert_reg(map, reg, value);
-       map->reg_defaults[ret].def = value;
-       return 0;
-}
-
-static int regcache_indexed_sync(struct regmap *map)
-{
-       unsigned int i;
-       int ret;
-
-       for (i = 0; i < map->num_reg_defaults; i++) {
-               ret = _regmap_write(map, map->reg_defaults[i].reg,
-                                   map->reg_defaults[i].def);
-               if (ret < 0)
-                       return ret;
-               dev_dbg(map->dev, "Synced register %#x, value %#x\n",
-                       map->reg_defaults[i].reg,
-                       map->reg_defaults[i].def);
-       }
-       return 0;
-}
-
-struct regcache_ops regcache_indexed_ops = {
-       .type = REGCACHE_INDEXED,
-       .name = "indexed",
-       .read = regcache_indexed_read,
-       .write = regcache_indexed_write,
-       .sync = regcache_indexed_sync
-};
index 066aeece3626265610d17f25785dd2dd1f6ebc5f..b7d16143edeb19b27ffe227535afdc9a555890d5 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "internal.h"
 
+static int regcache_lzo_exit(struct regmap *map);
+
 struct regcache_lzo_ctx {
        void *wmem;
        void *dst;
@@ -27,7 +29,7 @@ struct regcache_lzo_ctx {
 };
 
 #define LZO_BLOCK_NUM 8
-static int regcache_lzo_block_count(void)
+static int regcache_lzo_block_count(struct regmap *map)
 {
        return LZO_BLOCK_NUM;
 }
@@ -106,19 +108,22 @@ static inline int regcache_lzo_get_blkindex(struct regmap *map,
                                            unsigned int reg)
 {
        return (reg * map->cache_word_size) /
-               DIV_ROUND_UP(map->cache_size_raw, regcache_lzo_block_count());
+               DIV_ROUND_UP(map->cache_size_raw,
+                            regcache_lzo_block_count(map));
 }
 
 static inline int regcache_lzo_get_blkpos(struct regmap *map,
                                          unsigned int reg)
 {
-       return reg % (DIV_ROUND_UP(map->cache_size_raw, regcache_lzo_block_count()) /
+       return reg % (DIV_ROUND_UP(map->cache_size_raw,
+                                  regcache_lzo_block_count(map)) /
                      map->cache_word_size);
 }
 
 static inline int regcache_lzo_get_blksize(struct regmap *map)
 {
-       return DIV_ROUND_UP(map->cache_size_raw, regcache_lzo_block_count());
+       return DIV_ROUND_UP(map->cache_size_raw,
+                           regcache_lzo_block_count(map));
 }
 
 static int regcache_lzo_init(struct regmap *map)
@@ -131,7 +136,7 @@ static int regcache_lzo_init(struct regmap *map)
 
        ret = 0;
 
-       blkcount = regcache_lzo_block_count();
+       blkcount = regcache_lzo_block_count(map);
        map->cache = kzalloc(blkcount * sizeof *lzo_blocks,
                             GFP_KERNEL);
        if (!map->cache)
@@ -190,7 +195,7 @@ static int regcache_lzo_init(struct regmap *map)
 
        return 0;
 err:
-       regcache_exit(map);
+       regcache_lzo_exit(map);
        return ret;
 }
 
@@ -203,7 +208,7 @@ static int regcache_lzo_exit(struct regmap *map)
        if (!lzo_blocks)
                return 0;
 
-       blkcount = regcache_lzo_block_count();
+       blkcount = regcache_lzo_block_count(map);
        /*
         * the pointer to the bitmap used for syncing the cache
         * is shared amongst all lzo_blocks.  Ensure it is freed
@@ -351,7 +356,7 @@ static int regcache_lzo_sync(struct regmap *map)
 }
 
 struct regcache_ops regcache_lzo_ops = {
-       .type = REGCACHE_LZO,
+       .type = REGCACHE_COMPRESSED,
        .name = "lzo",
        .init = regcache_lzo_init,
        .exit = regcache_lzo_exit,
index e31498499b0fdc86df83b653950769ec6c814e31..32620c4f16834112ab88c9f9741750aee94f26d6 100644 (file)
  */
 
 #include <linux/slab.h>
+#include <linux/debugfs.h>
 #include <linux/rbtree.h>
+#include <linux/seq_file.h>
 
 #include "internal.h"
 
 static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
                                 unsigned int value);
+static int regcache_rbtree_exit(struct regmap *map);
 
 struct regcache_rbtree_node {
        /* the actual rbtree node holding this block */
@@ -124,6 +127,60 @@ static int regcache_rbtree_insert(struct rb_root *root,
        return 1;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static int rbtree_show(struct seq_file *s, void *ignored)
+{
+       struct regmap *map = s->private;
+       struct regcache_rbtree_ctx *rbtree_ctx = map->cache;
+       struct regcache_rbtree_node *n;
+       struct rb_node *node;
+       unsigned int base, top;
+       int nodes = 0;
+       int registers = 0;
+
+       mutex_lock(&map->lock);
+
+       for (node = rb_first(&rbtree_ctx->root); node != NULL;
+            node = rb_next(node)) {
+               n = container_of(node, struct regcache_rbtree_node, node);
+
+               regcache_rbtree_get_base_top_reg(n, &base, &top);
+               seq_printf(s, "%x-%x (%d)\n", base, top, top - base + 1);
+
+               nodes++;
+               registers += top - base + 1;
+       }
+
+       seq_printf(s, "%d nodes, %d registers, average %d registers\n",
+                  nodes, registers, registers / nodes);
+
+       mutex_unlock(&map->lock);
+
+       return 0;
+}
+
+static int rbtree_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, rbtree_show, inode->i_private);
+}
+
+static const struct file_operations rbtree_fops = {
+       .open           = rbtree_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static void rbtree_debugfs_init(struct regmap *map)
+{
+       debugfs_create_file("rbtree", 0400, map->debugfs, map, &rbtree_fops);
+}
+#else
+static void rbtree_debugfs_init(struct regmap *map)
+{
+}
+#endif
+
 static int regcache_rbtree_init(struct regmap *map)
 {
        struct regcache_rbtree_ctx *rbtree_ctx;
@@ -146,10 +203,12 @@ static int regcache_rbtree_init(struct regmap *map)
                        goto err;
        }
 
+       rbtree_debugfs_init(map);
+
        return 0;
 
 err:
-       regcache_exit(map);
+       regcache_rbtree_exit(map);
        return ret;
 }
 
index 666f6f5011dc85339287f9b982f991e22081626b..1ead66186b7c0a90586f223b0b9bc23d3770a3ed 100644 (file)
@@ -19,7 +19,6 @@
 #include "internal.h"
 
 static const struct regcache_ops *cache_types[] = {
-       &regcache_indexed_ops,
        &regcache_rbtree_ops,
        &regcache_lzo_ops,
 };
@@ -61,8 +60,10 @@ static int regcache_hw_init(struct regmap *map)
 
        map->reg_defaults = kmalloc(count * sizeof(struct reg_default),
                                      GFP_KERNEL);
-       if (!map->reg_defaults)
-               return -ENOMEM;
+       if (!map->reg_defaults) {
+               ret = -ENOMEM;
+               goto err_free;
+       }
 
        /* fill the reg_defaults */
        map->num_reg_defaults = count;
@@ -77,9 +78,15 @@ static int regcache_hw_init(struct regmap *map)
        }
 
        return 0;
+
+err_free:
+       if (map->cache_free)
+               kfree(map->reg_defaults_raw);
+
+       return ret;
 }
 
-int regcache_init(struct regmap *map)
+int regcache_init(struct regmap *map, const struct regmap_config *config)
 {
        int ret;
        int i;
@@ -100,6 +107,12 @@ int regcache_init(struct regmap *map)
                return -EINVAL;
        }
 
+       map->num_reg_defaults = config->num_reg_defaults;
+       map->num_reg_defaults_raw = config->num_reg_defaults_raw;
+       map->reg_defaults_raw = config->reg_defaults_raw;
+       map->cache_word_size = DIV_ROUND_UP(config->val_bits, 8);
+       map->cache_size_raw = map->cache_word_size * config->num_reg_defaults_raw;
+
        map->cache = NULL;
        map->cache_ops = cache_types[i];
 
@@ -112,10 +125,10 @@ int regcache_init(struct regmap *map)
         * won't vanish from under us.  We'll need to make
         * a copy of it.
         */
-       if (map->reg_defaults) {
+       if (config->reg_defaults) {
                if (!map->num_reg_defaults)
                        return -EINVAL;
-               tmp_buf = kmemdup(map->reg_defaults, map->num_reg_defaults *
+               tmp_buf = kmemdup(config->reg_defaults, map->num_reg_defaults *
                                  sizeof(struct reg_default), GFP_KERNEL);
                if (!tmp_buf)
                        return -ENOMEM;
@@ -136,9 +149,18 @@ int regcache_init(struct regmap *map)
        if (map->cache_ops->init) {
                dev_dbg(map->dev, "Initializing %s cache\n",
                        map->cache_ops->name);
-               return map->cache_ops->init(map);
+               ret = map->cache_ops->init(map);
+               if (ret)
+                       goto err_free;
        }
        return 0;
+
+err_free:
+       kfree(map->reg_defaults);
+       if (map->cache_free)
+               kfree(map->reg_defaults_raw);
+
+       return ret;
 }
 
 void regcache_exit(struct regmap *map)
@@ -171,16 +193,21 @@ void regcache_exit(struct regmap *map)
 int regcache_read(struct regmap *map,
                  unsigned int reg, unsigned int *value)
 {
+       int ret;
+
        if (map->cache_type == REGCACHE_NONE)
                return -ENOSYS;
 
        BUG_ON(!map->cache_ops);
 
-       if (!regmap_readable(map, reg))
-               return -EIO;
+       if (!regmap_volatile(map, reg)) {
+               ret = map->cache_ops->read(map, reg, value);
 
-       if (!regmap_volatile(map, reg))
-               return map->cache_ops->read(map, reg, value);
+               if (ret == 0)
+                       trace_regmap_reg_read_cache(map->dev, reg, *value);
+
+               return ret;
+       }
 
        return -EINVAL;
 }
@@ -241,6 +268,8 @@ int regcache_sync(struct regmap *map)
                map->cache_ops->name);
        name = map->cache_ops->name;
        trace_regcache_sync(map->dev, name, "start");
+       if (!map->cache_dirty)
+               goto out;
        if (map->cache_ops->sync) {
                ret = map->cache_ops->sync(map);
        } else {
@@ -290,6 +319,23 @@ void regcache_cache_only(struct regmap *map, bool enable)
 }
 EXPORT_SYMBOL_GPL(regcache_cache_only);
 
+/**
+ * regcache_mark_dirty: Mark the register cache as dirty
+ *
+ * @map: map to mark
+ *
+ * Mark the register cache as dirty, for example due to the device
+ * having been powered down for suspend.  If the cache is not marked
+ * as dirty then the cache sync will be suppressed.
+ */
+void regcache_mark_dirty(struct regmap *map)
+{
+       mutex_lock(&map->lock);
+       map->cache_dirty = true;
+       mutex_unlock(&map->lock);
+}
+EXPORT_SYMBOL_GPL(regcache_mark_dirty);
+
 /**
  * regcache_cache_bypass: Put a register map into cache bypass mode
  *
@@ -381,22 +427,3 @@ int regcache_lookup_reg(struct regmap *map, unsigned int reg)
        else
                return -ENOENT;
 }
-
-int regcache_insert_reg(struct regmap *map, unsigned int reg,
-                       unsigned int val)
-{
-       void *tmp;
-
-       tmp = krealloc(map->reg_defaults,
-                      (map->num_reg_defaults + 1) * sizeof(struct reg_default),
-                      GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
-       map->reg_defaults = tmp;
-       map->num_reg_defaults++;
-       map->reg_defaults[map->num_reg_defaults - 1].reg = reg;
-       map->reg_defaults[map->num_reg_defaults - 1].def = val;
-       sort(map->reg_defaults, map->num_reg_defaults,
-            sizeof(struct reg_default), regcache_default_cmp, NULL);
-       return 0;
-}
index bf441db1ee90af507ac3597e6a32dd1a3cbfec10..be10a4ff660915625454375ce9fb30a97d5b7ef9 100644 (file)
@@ -64,6 +64,18 @@ bool regmap_precious(struct regmap *map, unsigned int reg)
        return false;
 }
 
+static bool regmap_volatile_range(struct regmap *map, unsigned int reg,
+       unsigned int num)
+{
+       unsigned int i;
+
+       for (i = 0; i < num; i++)
+               if (!regmap_volatile(map, reg + i))
+                       return false;
+
+       return true;
+}
+
 static void regmap_format_4_12_write(struct regmap *map,
                                     unsigned int reg, unsigned int val)
 {
@@ -78,6 +90,16 @@ static void regmap_format_7_9_write(struct regmap *map,
        *out = cpu_to_be16((reg << 9) | val);
 }
 
+static void regmap_format_10_14_write(struct regmap *map,
+                                   unsigned int reg, unsigned int val)
+{
+       u8 *out = map->work_buf;
+
+       out[2] = val;
+       out[1] = (val >> 8) | (reg << 6);
+       out[0] = reg >> 2;
+}
+
 static void regmap_format_8(void *buf, unsigned int val)
 {
        u8 *b = buf;
@@ -127,7 +149,7 @@ struct regmap *regmap_init(struct device *dev,
        int ret = -EINVAL;
 
        if (!bus || !config)
-               return NULL;
+               goto err;
 
        map = kzalloc(sizeof(*map), GFP_KERNEL);
        if (map == NULL) {
@@ -147,12 +169,6 @@ struct regmap *regmap_init(struct device *dev,
        map->volatile_reg = config->volatile_reg;
        map->precious_reg = config->precious_reg;
        map->cache_type = config->cache_type;
-       map->reg_defaults = config->reg_defaults;
-       map->num_reg_defaults = config->num_reg_defaults;
-       map->num_reg_defaults_raw = config->num_reg_defaults_raw;
-       map->reg_defaults_raw = config->reg_defaults_raw;
-       map->cache_size_raw = (config->val_bits / 8) * config->num_reg_defaults_raw;
-       map->cache_word_size = config->val_bits / 8;
 
        if (config->read_flag_mask || config->write_flag_mask) {
                map->read_flag_mask = config->read_flag_mask;
@@ -182,6 +198,16 @@ struct regmap *regmap_init(struct device *dev,
                }
                break;
 
+       case 10:
+               switch (config->val_bits) {
+               case 14:
+                       map->format.format_write = regmap_format_10_14_write;
+                       break;
+               default:
+                       goto err_map;
+               }
+               break;
+
        case 8:
                map->format.format_reg = regmap_format_8;
                break;
@@ -215,14 +241,16 @@ struct regmap *regmap_init(struct device *dev,
                goto err_map;
        }
 
-       ret = regcache_init(map);
-       if (ret < 0)
-               goto err_map;
-
        regmap_debugfs_init(map);
 
+       ret = regcache_init(map, config);
+       if (ret < 0)
+               goto err_free_workbuf;
+
        return map;
 
+err_free_workbuf:
+       kfree(map->work_buf);
 err_map:
        kfree(map);
 err:
@@ -230,6 +258,39 @@ err:
 }
 EXPORT_SYMBOL_GPL(regmap_init);
 
+/**
+ * regmap_reinit_cache(): Reinitialise the current register cache
+ *
+ * @map: Register map to operate on.
+ * @config: New configuration.  Only the cache data will be used.
+ *
+ * Discard any existing register cache for the map and initialize a
+ * new cache.  This can be used to restore the cache to defaults or to
+ * update the cache configuration to reflect runtime discovery of the
+ * hardware.
+ */
+int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
+{
+       int ret;
+
+       mutex_lock(&map->lock);
+
+       regcache_exit(map);
+
+       map->max_register = config->max_register;
+       map->writeable_reg = config->writeable_reg;
+       map->readable_reg = config->readable_reg;
+       map->volatile_reg = config->volatile_reg;
+       map->precious_reg = config->precious_reg;
+       map->cache_type = config->cache_type;
+
+       ret = regcache_init(map, config);
+
+       mutex_unlock(&map->lock);
+
+       return ret;
+}
+
 /**
  * regmap_exit(): Free a previously allocated register map
  */
@@ -306,8 +367,10 @@ int _regmap_write(struct regmap *map, unsigned int reg,
                ret = regcache_write(map, reg, val);
                if (ret != 0)
                        return ret;
-               if (map->cache_only)
+               if (map->cache_only) {
+                       map->cache_dirty = true;
                        return 0;
+               }
        }
 
        trace_regmap_reg_write(map->dev, reg, val);
@@ -375,9 +438,11 @@ EXPORT_SYMBOL_GPL(regmap_write);
 int regmap_raw_write(struct regmap *map, unsigned int reg,
                     const void *val, size_t val_len)
 {
+       size_t val_count = val_len / map->format.val_bytes;
        int ret;
 
-       WARN_ON(map->cache_type != REGCACHE_NONE);
+       WARN_ON(!regmap_volatile_range(map, reg, val_count) &&
+               map->cache_type != REGCACHE_NONE);
 
        mutex_lock(&map->lock);
 
@@ -422,15 +487,15 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
 {
        int ret;
 
-       if (!map->format.parse_val)
-               return -EINVAL;
-
        if (!map->cache_bypass) {
                ret = regcache_read(map, reg, val);
                if (ret == 0)
                        return 0;
        }
 
+       if (!map->format.parse_val)
+               return -EINVAL;
+
        if (map->cache_only)
                return -EBUSY;
 
@@ -481,15 +546,11 @@ EXPORT_SYMBOL_GPL(regmap_read);
 int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
                    size_t val_len)
 {
+       size_t val_count = val_len / map->format.val_bytes;
        int ret;
-       int i;
-       bool vol = true;
 
-       for (i = 0; i < val_len / map->format.val_bytes; i++)
-               if (!regmap_volatile(map, reg + i))
-                       vol = false;
-
-       WARN_ON(!vol && map->cache_type != REGCACHE_NONE);
+       WARN_ON(!regmap_volatile_range(map, reg, val_count) &&
+               map->cache_type != REGCACHE_NONE);
 
        mutex_lock(&map->lock);
 
@@ -517,16 +578,11 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 {
        int ret, i;
        size_t val_bytes = map->format.val_bytes;
-       bool vol = true;
+       bool vol = regmap_volatile_range(map, reg, val_count);
 
        if (!map->format.parse_val)
                return -EINVAL;
 
-       /* Is this a block of volatile registers? */
-       for (i = 0; i < val_count; i++)
-               if (!regmap_volatile(map, reg + i))
-                       vol = false;
-
        if (vol || map->cache_type == REGCACHE_NONE) {
                ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
                if (ret != 0)
@@ -546,40 +602,73 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 }
 EXPORT_SYMBOL_GPL(regmap_bulk_read);
 
-/**
- * remap_update_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_update_bits(struct regmap *map, unsigned int reg,
-                      unsigned int mask, unsigned int val)
+static int _regmap_update_bits(struct regmap *map, unsigned int reg,
+                              unsigned int mask, unsigned int val,
+                              bool *change)
 {
        int ret;
-       unsigned int tmp;
+       unsigned int tmp, orig;
 
        mutex_lock(&map->lock);
 
-       ret = _regmap_read(map, reg, &tmp);
+       ret = _regmap_read(map, reg, &orig);
        if (ret != 0)
                goto out;
 
-       tmp &= ~mask;
+       tmp = orig & ~mask;
        tmp |= val & mask;
 
-       ret = _regmap_write(map, reg, tmp);
+       if (tmp != orig) {
+               ret = _regmap_write(map, reg, tmp);
+               *change = true;
+       } else {
+               *change = false;
+       }
 
 out:
        mutex_unlock(&map->lock);
 
        return ret;
 }
+
+/**
+ * regmap_update_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_update_bits(struct regmap *map, unsigned int reg,
+                      unsigned int mask, unsigned int val)
+{
+       bool change;
+       return _regmap_update_bits(map, reg, mask, val, &change);
+}
 EXPORT_SYMBOL_GPL(regmap_update_bits);
 
+/**
+ * regmap_update_bits_check: Perform a read/modify/write cycle on the
+ *                           register map and report if updated
+ *
+ * @map: Register map to update
+ * @reg: Register to update
+ * @mask: Bitmask to change
+ * @val: New value for bitmask
+ * @change: Boolean indicating if a write was done
+ *
+ * Returns zero for success, a negative number on error.
+ */
+int regmap_update_bits_check(struct regmap *map, unsigned int reg,
+                            unsigned int mask, unsigned int val,
+                            bool *change)
+{
+       return _regmap_update_bits(map, reg, mask, val, change);
+}
+EXPORT_SYMBOL_GPL(regmap_update_bits_check);
+
 static int __init regmap_initcall(void)
 {
        regmap_debugfs_initcall();
index e7e8953e8c2a459d1126305cc7b324a212ef4398..eb93921cdd30252b1c960cf6872585e308c9e9fc 100644 (file)
@@ -23,9 +23,8 @@ struct spi_device;
 /* An enum of all the supported cache types */
 enum regcache_type {
        REGCACHE_NONE,
-       REGCACHE_INDEXED,
        REGCACHE_RBTREE,
-       REGCACHE_LZO
+       REGCACHE_COMPRESSED
 };
 
 /**
@@ -83,7 +82,7 @@ struct regmap_config {
        bool (*precious_reg)(struct device *dev, unsigned int reg);
 
        unsigned int max_register;
-       struct reg_default *reg_defaults;
+       const struct reg_default *reg_defaults;
        unsigned int num_reg_defaults;
        enum regcache_type cache_type;
        const void *reg_defaults_raw;
@@ -129,6 +128,8 @@ struct regmap *regmap_init_spi(struct spi_device *dev,
                               const struct regmap_config *config);
 
 void regmap_exit(struct regmap *map);
+int regmap_reinit_cache(struct regmap *map,
+                       const struct regmap_config *config);
 int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
 int regmap_raw_write(struct regmap *map, unsigned int reg,
                     const void *val, size_t val_len);
@@ -139,10 +140,14 @@ 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_check(struct regmap *map, unsigned int reg,
+                            unsigned int mask, unsigned int val,
+                            bool *change);
 
 int regcache_sync(struct regmap *map);
 void regcache_cache_only(struct regmap *map, bool enable);
 void regcache_cache_bypass(struct regmap *map, bool enable);
+void regcache_mark_dirty(struct regmap *map);
 
 /**
  * Description of an IRQ for the generic regmap irq_chip.
index 1e3193b8fcc8f5863e665d91f287c4728f036346..12fbf43524e90e77759e80751bfe5ab983b4ad2d 100644 (file)
@@ -55,6 +55,15 @@ DEFINE_EVENT(regmap_reg, regmap_reg_read,
 
 );
 
+DEFINE_EVENT(regmap_reg, regmap_reg_read_cache,
+
+       TP_PROTO(struct device *dev, unsigned int reg,
+                unsigned int val),
+
+       TP_ARGS(dev, reg, val)
+
+);
+
 DECLARE_EVENT_CLASS(regmap_block,
 
        TP_PROTO(struct device *dev, unsigned int reg, int count),