aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/regmap/internal.h10
-rw-r--r--drivers/base/regmap/regmap.c19
2 files changed, 23 insertions, 6 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 3df977054781..c22b04b2ca17 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -110,6 +110,7 @@ struct regmap {
110 /* number of bits to (left) shift the reg value when formatting*/ 110 /* number of bits to (left) shift the reg value when formatting*/
111 int reg_shift; 111 int reg_shift;
112 int reg_stride; 112 int reg_stride;
113 int reg_stride_order;
113 114
114 /* regcache specific members */ 115 /* regcache specific members */
115 const struct regcache_ops *cache_ops; 116 const struct regcache_ops *cache_ops;
@@ -263,4 +264,13 @@ static inline const char *regmap_name(const struct regmap *map)
263 return map->name; 264 return map->name;
264} 265}
265 266
267static inline unsigned int regmap_get_offset(const struct regmap *map,
268 unsigned int index)
269{
270 if (map->reg_stride_order >= 0)
271 return index << map->reg_stride_order;
272 else
273 return index * map->reg_stride;
274}
275
266#endif 276#endif
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index ee54e841de4a..29d526e0fc0f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -19,6 +19,7 @@
19#include <linux/rbtree.h> 19#include <linux/rbtree.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/log2.h>
22 23
23#define CREATE_TRACE_POINTS 24#define CREATE_TRACE_POINTS
24#include "trace.h" 25#include "trace.h"
@@ -638,6 +639,10 @@ struct regmap *__regmap_init(struct device *dev,
638 map->reg_stride = config->reg_stride; 639 map->reg_stride = config->reg_stride;
639 else 640 else
640 map->reg_stride = 1; 641 map->reg_stride = 1;
642 if (is_power_of_2(map->reg_stride))
643 map->reg_stride_order = ilog2(map->reg_stride);
644 else
645 map->reg_stride_order = -1;
641 map->use_single_read = config->use_single_rw || !bus || !bus->read; 646 map->use_single_read = config->use_single_rw || !bus || !bus->read;
642 map->use_single_write = config->use_single_rw || !bus || !bus->write; 647 map->use_single_write = config->use_single_rw || !bus || !bus->write;
643 map->can_multi_write = config->can_multi_write && bus && bus->write; 648 map->can_multi_write = config->can_multi_write && bus && bus->write;
@@ -1308,7 +1313,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
1308 if (map->writeable_reg) 1313 if (map->writeable_reg)
1309 for (i = 0; i < val_len / map->format.val_bytes; i++) 1314 for (i = 0; i < val_len / map->format.val_bytes; i++)
1310 if (!map->writeable_reg(map->dev, 1315 if (!map->writeable_reg(map->dev,
1311 reg + (i * map->reg_stride))) 1316 reg + regmap_get_offset(map, i)))
1312 return -EINVAL; 1317 return -EINVAL;
1313 1318
1314 if (!map->cache_bypass && map->format.parse_val) { 1319 if (!map->cache_bypass && map->format.parse_val) {
@@ -1316,7 +1321,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
1316 int val_bytes = map->format.val_bytes; 1321 int val_bytes = map->format.val_bytes;
1317 for (i = 0; i < val_len / val_bytes; i++) { 1322 for (i = 0; i < val_len / val_bytes; i++) {
1318 ival = map->format.parse_val(val + (i * val_bytes)); 1323 ival = map->format.parse_val(val + (i * val_bytes));
1319 ret = regcache_write(map, reg + (i * map->reg_stride), 1324 ret = regcache_write(map,
1325 reg + regmap_get_offset(map, i),
1320 ival); 1326 ival);
1321 if (ret) { 1327 if (ret) {
1322 dev_err(map->dev, 1328 dev_err(map->dev,
@@ -1846,8 +1852,9 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1846 goto out; 1852 goto out;
1847 } 1853 }
1848 1854
1849 ret = _regmap_write(map, reg + (i * map->reg_stride), 1855 ret = _regmap_write(map,
1850 ival); 1856 reg + regmap_get_offset(map, i),
1857 ival);
1851 if (ret != 0) 1858 if (ret != 0)
1852 goto out; 1859 goto out;
1853 } 1860 }
@@ -2416,7 +2423,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
2416 * cost as we expect to hit the cache. 2423 * cost as we expect to hit the cache.
2417 */ 2424 */
2418 for (i = 0; i < val_count; i++) { 2425 for (i = 0; i < val_count; i++) {
2419 ret = _regmap_read(map, reg + (i * map->reg_stride), 2426 ret = _regmap_read(map, reg + regmap_get_offset(map, i),
2420 &v); 2427 &v);
2421 if (ret != 0) 2428 if (ret != 0)
2422 goto out; 2429 goto out;
@@ -2568,7 +2575,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
2568 } else { 2575 } else {
2569 for (i = 0; i < val_count; i++) { 2576 for (i = 0; i < val_count; i++) {
2570 unsigned int ival; 2577 unsigned int ival;
2571 ret = regmap_read(map, reg + (i * map->reg_stride), 2578 ret = regmap_read(map, reg + regmap_get_offset(map, i),
2572 &ival); 2579 &ival);
2573 if (ret != 0) 2580 if (ret != 0)
2574 return ret; 2581 return ret;