]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge remote-tracking branches 'regmap/topic/core' and 'regmap/topic/debugfs' into...
authorMark Brown <broonie@kernel.org>
Tue, 4 Oct 2016 03:17:12 +0000 (05:17 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 4 Oct 2016 03:17:12 +0000 (05:17 +0200)
drivers/base/regmap/internal.h
drivers/base/regmap/regmap-debugfs.c
drivers/base/regmap/regmap.c
include/linux/regmap.h

index a0380338946a1dbd6cb7e54ab70b001edc77eef7..2a4435d760289118f00882fb89693346972ae996 100644 (file)
@@ -105,8 +105,8 @@ struct regmap {
 
        bool defer_caching;
 
-       u8 read_flag_mask;
-       u8 write_flag_mask;
+       unsigned long read_flag_mask;
+       unsigned long write_flag_mask;
 
        /* number of bits to (left) shift the reg value when formatting*/
        int reg_shift;
@@ -173,6 +173,7 @@ struct regcache_ops {
        int (*drop)(struct regmap *map, unsigned int min, unsigned int max);
 };
 
+bool regmap_cached(struct regmap *map, unsigned int reg);
 bool regmap_writeable(struct regmap *map, unsigned int reg);
 bool regmap_readable(struct regmap *map, unsigned int reg);
 bool regmap_volatile(struct regmap *map, unsigned int reg);
index 1ee3d40861c7ee77b819e9ae0118fb5f774bb215..36ce3511c733f62193a32fe3b63fd4d195209092 100644 (file)
@@ -77,6 +77,17 @@ static void regmap_debugfs_free_dump_cache(struct regmap *map)
        }
 }
 
+static bool regmap_printable(struct regmap *map, unsigned int reg)
+{
+       if (regmap_precious(map, reg))
+               return false;
+
+       if (!regmap_readable(map, reg) && !regmap_cached(map, reg))
+               return false;
+
+       return true;
+}
+
 /*
  * Work out where the start offset maps into register numbers, bearing
  * in mind that we suppress hidden registers.
@@ -105,8 +116,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
        if (list_empty(&map->debugfs_off_cache)) {
                for (; i <= map->max_register; i += map->reg_stride) {
                        /* Skip unprinted registers, closing off cache entry */
-                       if (!regmap_readable(map, i) ||
-                           regmap_precious(map, i)) {
+                       if (!regmap_printable(map, i)) {
                                if (c) {
                                        c->max = p - 1;
                                        c->max_reg = i - map->reg_stride;
@@ -204,7 +214,7 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
        start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p);
 
        for (i = start_reg; i <= to; i += map->reg_stride) {
-               if (!regmap_readable(map, i))
+               if (!regmap_readable(map, i) && !regmap_cached(map, i))
                        continue;
 
                if (regmap_precious(map, i))
index e964d068874dea77f0282d58e0dd97501f7481a6..ae63bb0875ea8388227b0b2285fc61993e34a367 100644 (file)
@@ -93,6 +93,29 @@ bool regmap_writeable(struct regmap *map, unsigned int reg)
        return true;
 }
 
+bool regmap_cached(struct regmap *map, unsigned int reg)
+{
+       int ret;
+       unsigned int val;
+
+       if (map->cache == REGCACHE_NONE)
+               return false;
+
+       if (!map->cache_ops)
+               return false;
+
+       if (map->max_register && reg > map->max_register)
+               return false;
+
+       map->lock(map->lock_arg);
+       ret = regcache_read(map, reg, &val);
+       map->unlock(map->lock_arg);
+       if (ret)
+               return false;
+
+       return true;
+}
+
 bool regmap_readable(struct regmap *map, unsigned int reg)
 {
        if (!map->reg_read)
@@ -749,6 +772,9 @@ struct regmap *__regmap_init(struct device *dev,
                case REGMAP_ENDIAN_BIG:
                        map->format.format_reg = regmap_format_16_be;
                        break;
+               case REGMAP_ENDIAN_LITTLE:
+                       map->format.format_reg = regmap_format_16_le;
+                       break;
                case REGMAP_ENDIAN_NATIVE:
                        map->format.format_reg = regmap_format_16_native;
                        break;
@@ -768,6 +794,9 @@ struct regmap *__regmap_init(struct device *dev,
                case REGMAP_ENDIAN_BIG:
                        map->format.format_reg = regmap_format_32_be;
                        break;
+               case REGMAP_ENDIAN_LITTLE:
+                       map->format.format_reg = regmap_format_32_le;
+                       break;
                case REGMAP_ENDIAN_NATIVE:
                        map->format.format_reg = regmap_format_32_native;
                        break;
@@ -782,6 +811,9 @@ struct regmap *__regmap_init(struct device *dev,
                case REGMAP_ENDIAN_BIG:
                        map->format.format_reg = regmap_format_64_be;
                        break;
+               case REGMAP_ENDIAN_LITTLE:
+                       map->format.format_reg = regmap_format_64_le;
+                       break;
                case REGMAP_ENDIAN_NATIVE:
                        map->format.format_reg = regmap_format_64_native;
                        break;
@@ -1296,12 +1328,26 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
        return 0;
 }
 
+static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes,
+                                         unsigned long mask)
+{
+       u8 *buf;
+       int i;
+
+       if (!mask || !map->work_buf)
+               return;
+
+       buf = map->work_buf;
+
+       for (i = 0; i < max_bytes; i++)
+               buf[i] |= (mask >> (8 * i)) & 0xff;
+}
+
 int _regmap_raw_write(struct regmap *map, unsigned int reg,
                      const void *val, size_t val_len)
 {
        struct regmap_range_node *range;
        unsigned long flags;
-       u8 *u8 = map->work_buf;
        void *work_val = map->work_buf + map->format.reg_bytes +
                map->format.pad_bytes;
        void *buf;
@@ -1370,8 +1416,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
        }
 
        map->format.format_reg(map->work_buf, reg, map->reg_shift);
-
-       u8[0] |= map->write_flag_mask;
+       regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
+                                     map->write_flag_mask);
 
        /*
         * Essentially all I/O mechanisms will be faster with a single
@@ -2251,7 +2297,6 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
                            unsigned int val_len)
 {
        struct regmap_range_node *range;
-       u8 *u8 = map->work_buf;
        int ret;
 
        WARN_ON(!map->bus);
@@ -2268,15 +2313,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
        }
 
        map->format.format_reg(map->work_buf, reg, map->reg_shift);
-
-       /*
-        * Some buses or devices flag reads by setting the high bits in the
-        * 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.
-        */
-       u8[0] |= map->read_flag_mask;
-
+       regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
+                                     map->read_flag_mask);
        trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);
 
        ret = map->bus->read(map->bus_context, map->work_buf,
index 2c12cc5af744d13cbfef6c29e65c0009e748e06f..9adc7b21903d3dc97987bbcdcd6caa7b449cecc6 100644 (file)
@@ -241,9 +241,9 @@ typedef void (*regmap_unlock)(void *);
  *                register cache support).
  * @num_reg_defaults: Number of elements in reg_defaults.
  *
- * @read_flag_mask: Mask to be set in the top byte of the register when doing
+ * @read_flag_mask: Mask to be set in the top bytes of the register when doing
  *                  a read.
- * @write_flag_mask: Mask to be set in the top byte of the register when doing
+ * @write_flag_mask: Mask to be set in the top bytes of the register when doing
  *                   a write. If both read_flag_mask and write_flag_mask are
  *                   empty the regmap_bus default masks are used.
  * @use_single_rw: If set, converts the bulk read and write operations into
@@ -299,8 +299,8 @@ struct regmap_config {
        const void *reg_defaults_raw;
        unsigned int num_reg_defaults_raw;
 
-       u8 read_flag_mask;
-       u8 write_flag_mask;
+       unsigned long read_flag_mask;
+       unsigned long write_flag_mask;
 
        bool use_single_rw;
        bool can_multi_write;