aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Smirnov <andrew.smirnov@gmail.com>2013-01-27 13:49:05 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-01-28 22:42:49 -0500
commitd2a5884a64161b524cc6749ee11b95d252e497f3 (patch)
treecf94ee33306a752e68977324e9b990538b44f8ab
parent07c320dc31d757b8cb59c64dab320215c929bf02 (diff)
regmap: Add "no-bus" option for regmap API
This commit adds provision for "no-bus" usage of the regmap API. In this configuration user can provide API with two callbacks 'reg_read' and 'reg_write' which are to be called when reads and writes to one of device's registers is performed. This is useful for devices that expose registers but whose register access sequence does not fit the 'bus' abstraction. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-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;