aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/regmap/internal.h2
-rw-r--r--drivers/base/regmap/regmap.c58
-rw-r--r--include/linux/regmap.h18
3 files changed, 65 insertions, 13 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 51f057405647..b55fde5d216a 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -77,6 +77,8 @@ struct regmap {
77 int (*reg_read)(void *context, unsigned int reg, unsigned int *val); 77 int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
78 int (*reg_write)(void *context, unsigned int reg, unsigned int val); 78 int (*reg_write)(void *context, unsigned int reg, unsigned int val);
79 79
80 bool defer_caching;
81
80 u8 read_flag_mask; 82 u8 read_flag_mask;
81 u8 write_flag_mask; 83 u8 write_flag_mask;
82 84
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 6845a077bd84..9592030a0dc3 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -379,7 +379,7 @@ struct regmap *regmap_init(struct device *dev,
379 enum regmap_endian reg_endian, val_endian; 379 enum regmap_endian reg_endian, val_endian;
380 int i, j; 380 int i, j;
381 381
382 if (!bus || !config) 382 if (!config)
383 goto err; 383 goto err;
384 384
385 map = kzalloc(sizeof(*map), GFP_KERNEL); 385 map = kzalloc(sizeof(*map), GFP_KERNEL);
@@ -393,7 +393,8 @@ struct regmap *regmap_init(struct device *dev,
393 map->unlock = config->unlock; 393 map->unlock = config->unlock;
394 map->lock_arg = config->lock_arg; 394 map->lock_arg = config->lock_arg;
395 } else { 395 } else {
396 if (bus->fast_io) { 396 if ((bus && bus->fast_io) ||
397 config->fast_io) {
397 spin_lock_init(&map->spinlock); 398 spin_lock_init(&map->spinlock);
398 map->lock = regmap_lock_spinlock; 399 map->lock = regmap_lock_spinlock;
399 map->unlock = regmap_unlock_spinlock; 400 map->unlock = regmap_unlock_spinlock;
@@ -433,11 +434,19 @@ struct regmap *regmap_init(struct device *dev,
433 if (config->read_flag_mask || config->write_flag_mask) { 434 if (config->read_flag_mask || config->write_flag_mask) {
434 map->read_flag_mask = config->read_flag_mask; 435 map->read_flag_mask = config->read_flag_mask;
435 map->write_flag_mask = config->write_flag_mask; 436 map->write_flag_mask = config->write_flag_mask;
436 } else { 437 } else if (bus) {
437 map->read_flag_mask = bus->read_flag_mask; 438 map->read_flag_mask = bus->read_flag_mask;
438 } 439 }
439 440
440 map->reg_read = _regmap_bus_read; 441 if (!bus) {
442 map->reg_read = config->reg_read;
443 map->reg_write = config->reg_write;
444
445 map->defer_caching = false;
446 goto skip_format_initialization;
447 } else {
448 map->reg_read = _regmap_bus_read;
449 }
441 450
442 reg_endian = config->reg_format_endian; 451 reg_endian = config->reg_format_endian;
443 if (reg_endian == REGMAP_ENDIAN_DEFAULT) 452 if (reg_endian == REGMAP_ENDIAN_DEFAULT)
@@ -584,10 +593,15 @@ struct regmap *regmap_init(struct device *dev,
584 goto err_map; 593 goto err_map;
585 } 594 }
586 595
587 if (map->format.format_write) 596 if (map->format.format_write) {
597 map->defer_caching = false;
588 map->reg_write = _regmap_bus_formatted_write; 598 map->reg_write = _regmap_bus_formatted_write;
589 else if (map->format.format_val) 599 } else if (map->format.format_val) {
600 map->defer_caching = true;
590 map->reg_write = _regmap_bus_raw_write; 601 map->reg_write = _regmap_bus_raw_write;
602 }
603
604skip_format_initialization:
591 605
592 map->range_tree = RB_ROOT; 606 map->range_tree = RB_ROOT;
593 for (i = 0; i < config->num_ranges; i++) { 607 for (i = 0; i < config->num_ranges; i++) {
@@ -790,7 +804,7 @@ void regmap_exit(struct regmap *map)
790 regcache_exit(map); 804 regcache_exit(map);
791 regmap_debugfs_exit(map); 805 regmap_debugfs_exit(map);
792 regmap_range_exit(map); 806 regmap_range_exit(map);
793 if (map->bus->free_context) 807 if (map->bus && map->bus->free_context)
794 map->bus->free_context(map->bus_context); 808 map->bus->free_context(map->bus_context);
795 kfree(map->work_buf); 809 kfree(map->work_buf);
796 kfree(map); 810 kfree(map);
@@ -893,6 +907,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
893 size_t len; 907 size_t len;
894 int i; 908 int i;
895 909
910 BUG_ON(!map->bus);
911
896 /* Check for unwritable registers before we start */ 912 /* Check for unwritable registers before we start */
897 if (map->writeable_reg) 913 if (map->writeable_reg)
898 for (i = 0; i < val_len / map->format.val_bytes; i++) 914 for (i = 0; i < val_len / map->format.val_bytes; i++)
@@ -1002,7 +1018,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
1002 struct regmap_range_node *range; 1018 struct regmap_range_node *range;
1003 struct regmap *map = context; 1019 struct regmap *map = context;
1004 1020
1005 BUG_ON(!map->format.format_write); 1021 BUG_ON(!map->bus || !map->format.format_write);
1006 1022
1007 range = _regmap_range_lookup(map, reg); 1023 range = _regmap_range_lookup(map, reg);
1008 if (range) { 1024 if (range) {
@@ -1028,7 +1044,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
1028{ 1044{
1029 struct regmap *map = context; 1045 struct regmap *map = context;
1030 1046
1031 BUG_ON(!map->format.format_val); 1047 BUG_ON(!map->bus || !map->format.format_val);
1032 1048
1033 map->format.format_val(map->work_buf + map->format.reg_bytes 1049 map->format.format_val(map->work_buf + map->format.reg_bytes
1034 + map->format.pad_bytes, val, 0); 1050 + map->format.pad_bytes, val, 0);
@@ -1039,12 +1055,18 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
1039 map->format.val_bytes); 1055 map->format.val_bytes);
1040} 1056}
1041 1057
1058static inline void *_regmap_map_get_context(struct regmap *map)
1059{
1060 return (map->bus) ? map : map->bus_context;
1061}
1062
1042int _regmap_write(struct regmap *map, unsigned int reg, 1063int _regmap_write(struct regmap *map, unsigned int reg,
1043 unsigned int val) 1064 unsigned int val)
1044{ 1065{
1045 int ret; 1066 int ret;
1067 void *context = _regmap_map_get_context(map);
1046 1068
1047 if (!map->cache_bypass && map->format.format_write) { 1069 if (!map->cache_bypass && !map->defer_caching) {
1048 ret = regcache_write(map, reg, val); 1070 ret = regcache_write(map, reg, val);
1049 if (ret != 0) 1071 if (ret != 0)
1050 return ret; 1072 return ret;
@@ -1061,7 +1083,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
1061 1083
1062 trace_regmap_reg_write(map->dev, reg, val); 1084 trace_regmap_reg_write(map->dev, reg, val);
1063 1085
1064 return map->reg_write(map, reg, val); 1086 return map->reg_write(context, reg, val);
1065} 1087}
1066 1088
1067/** 1089/**
@@ -1112,6 +1134,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
1112{ 1134{
1113 int ret; 1135 int ret;
1114 1136
1137 if (!map->bus)
1138 return -EINVAL;
1115 if (val_len % map->format.val_bytes) 1139 if (val_len % map->format.val_bytes)
1116 return -EINVAL; 1140 return -EINVAL;
1117 if (reg % map->reg_stride) 1141 if (reg % map->reg_stride)
@@ -1148,6 +1172,8 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1148 size_t val_bytes = map->format.val_bytes; 1172 size_t val_bytes = map->format.val_bytes;
1149 void *wval; 1173 void *wval;
1150 1174
1175 if (!map->bus)
1176 return -EINVAL;
1151 if (!map->format.parse_val) 1177 if (!map->format.parse_val)
1152 return -EINVAL; 1178 return -EINVAL;
1153 if (reg % map->reg_stride) 1179 if (reg % map->reg_stride)
@@ -1201,6 +1227,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1201 u8 *u8 = map->work_buf; 1227 u8 *u8 = map->work_buf;
1202 int ret; 1228 int ret;
1203 1229
1230 BUG_ON(!map->bus);
1231
1204 range = _regmap_range_lookup(map, reg); 1232 range = _regmap_range_lookup(map, reg);
1205 if (range) { 1233 if (range) {
1206 ret = _regmap_select_page(map, &reg, range, 1234 ret = _regmap_select_page(map, &reg, range,
@@ -1252,6 +1280,8 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
1252 unsigned int *val) 1280 unsigned int *val)
1253{ 1281{
1254 int ret; 1282 int ret;
1283 void *context = _regmap_map_get_context(map);
1284
1255 BUG_ON(!map->reg_read); 1285 BUG_ON(!map->reg_read);
1256 1286
1257 if (!map->cache_bypass) { 1287 if (!map->cache_bypass) {
@@ -1263,7 +1293,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
1263 if (map->cache_only) 1293 if (map->cache_only)
1264 return -EBUSY; 1294 return -EBUSY;
1265 1295
1266 ret = map->reg_read(map, reg, val); 1296 ret = map->reg_read(context, reg, val);
1267 if (ret == 0) { 1297 if (ret == 0) {
1268#ifdef LOG_DEVICE 1298#ifdef LOG_DEVICE
1269 if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) 1299 if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
@@ -1325,6 +1355,8 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1325 unsigned int v; 1355 unsigned int v;
1326 int ret, i; 1356 int ret, i;
1327 1357
1358 if (!map->bus)
1359 return -EINVAL;
1328 if (val_len % map->format.val_bytes) 1360 if (val_len % map->format.val_bytes)
1329 return -EINVAL; 1361 return -EINVAL;
1330 if (reg % map->reg_stride) 1362 if (reg % map->reg_stride)
@@ -1376,6 +1408,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
1376 size_t val_bytes = map->format.val_bytes; 1408 size_t val_bytes = map->format.val_bytes;
1377 bool vol = regmap_volatile_range(map, reg, val_count); 1409 bool vol = regmap_volatile_range(map, reg, val_count);
1378 1410
1411 if (!map->bus)
1412 return -EINVAL;
1379 if (!map->format.parse_val) 1413 if (!map->format.parse_val)
1380 return -EINVAL; 1414 return -EINVAL;
1381 if (reg % map->reg_stride) 1415 if (reg % map->reg_stride)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index b7e95bf942c9..28dde941c783 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -127,7 +127,18 @@ typedef void (*regmap_unlock)(void *);
127 * @lock_arg: this field is passed as the only argument of lock/unlock 127 * @lock_arg: this field is passed as the only argument of lock/unlock
128 * functions (ignored in case regular lock/unlock functions 128 * functions (ignored in case regular lock/unlock functions
129 * are not overridden). 129 * are not overridden).
130 * 130 * @reg_read: Optional callback that if filled will be used to perform
131 * all the reads from the registers. Should only be provided for
132 * devices whos read operation cannot be represented as a simple read
133 * operation on a bus such as SPI, I2C, etc. Most of the devices do
134 * not need this.
135 * @reg_write: Same as above for writing.
136 * @fast_io: Register IO is fast. Use a spinlock instead of a mutex
137 * to perform locking. This field is ignored if custom lock/unlock
138 * functions are used (see fields lock/unlock of struct regmap_config).
139 * This field is a duplicate of a similar file in
140 * 'struct regmap_bus' and serves exact same purpose.
141 * Use it only for "no-bus" cases.
131 * @max_register: Optional, specifies the maximum valid register index. 142 * @max_register: Optional, specifies the maximum valid register index.
132 * @wr_table: Optional, points to a struct regmap_access_table specifying 143 * @wr_table: Optional, points to a struct regmap_access_table specifying
133 * valid ranges for write access. 144 * valid ranges for write access.
@@ -177,6 +188,11 @@ struct regmap_config {
177 regmap_unlock unlock; 188 regmap_unlock unlock;
178 void *lock_arg; 189 void *lock_arg;
179 190
191 int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
192 int (*reg_write)(void *context, unsigned int reg, unsigned int val);
193
194 bool fast_io;
195
180 unsigned int max_register; 196 unsigned int max_register;
181 const struct regmap_access_table *wr_table; 197 const struct regmap_access_table *wr_table;
182 const struct regmap_access_table *rd_table; 198 const struct regmap_access_table *rd_table;