diff options
| -rw-r--r-- | drivers/base/regmap/internal.h | 10 | ||||
| -rw-r--r-- | drivers/base/regmap/regmap.c | 19 |
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 | ||
| 267 | static 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; |
