aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regmap.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-14 12:11:03 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-14 12:11:03 -0500
commit3689cf7fd17ea50850f9036f398bd56e08c8806d (patch)
tree18006137f618f7a2ff99417bb1029081bcc88fbf /drivers/base/regmap/regmap.c
parent3bef9059dd8d50c011ea22ae60eaa03996bd4ad1 (diff)
parent95601d65a1aa0902f838a2919e11ee6311efe371 (diff)
Merge remote-tracking branch 'regmap/topic/async' into regmap-next
Diffstat (limited to 'drivers/base/regmap/regmap.c')
-rw-r--r--drivers/base/regmap/regmap.c301
1 files changed, 254 insertions, 47 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index dc19026d28e9..b1d962434cb2 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -16,6 +16,7 @@
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/rbtree.h> 18#include <linux/rbtree.h>
19#include <linux/sched.h>
19 20
20#define CREATE_TRACE_POINTS 21#define CREATE_TRACE_POINTS
21#include <trace/events/regmap.h> 22#include <trace/events/regmap.h>
@@ -34,6 +35,22 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
34 unsigned int mask, unsigned int val, 35 unsigned int mask, unsigned int val,
35 bool *change); 36 bool *change);
36 37
38static int _regmap_bus_read(void *context, unsigned int reg,
39 unsigned int *val);
40static int _regmap_bus_formatted_write(void *context, unsigned int reg,
41 unsigned int val);
42static int _regmap_bus_raw_write(void *context, unsigned int reg,
43 unsigned int val);
44
45static void async_cleanup(struct work_struct *work)
46{
47 struct regmap_async *async = container_of(work, struct regmap_async,
48 cleanup);
49
50 kfree(async->work_buf);
51 kfree(async);
52}
53
37bool regmap_reg_in_ranges(unsigned int reg, 54bool regmap_reg_in_ranges(unsigned int reg,
38 const struct regmap_range *ranges, 55 const struct regmap_range *ranges,
39 unsigned int nranges) 56 unsigned int nranges)
@@ -423,6 +440,10 @@ struct regmap *regmap_init(struct device *dev,
423 map->cache_type = config->cache_type; 440 map->cache_type = config->cache_type;
424 map->name = config->name; 441 map->name = config->name;
425 442
443 spin_lock_init(&map->async_lock);
444 INIT_LIST_HEAD(&map->async_list);
445 init_waitqueue_head(&map->async_waitq);
446
426 if (config->read_flag_mask || config->write_flag_mask) { 447 if (config->read_flag_mask || config->write_flag_mask) {
427 map->read_flag_mask = config->read_flag_mask; 448 map->read_flag_mask = config->read_flag_mask;
428 map->write_flag_mask = config->write_flag_mask; 449 map->write_flag_mask = config->write_flag_mask;
@@ -430,6 +451,8 @@ struct regmap *regmap_init(struct device *dev,
430 map->read_flag_mask = bus->read_flag_mask; 451 map->read_flag_mask = bus->read_flag_mask;
431 } 452 }
432 453
454 map->reg_read = _regmap_bus_read;
455
433 reg_endian = config->reg_format_endian; 456 reg_endian = config->reg_format_endian;
434 if (reg_endian == REGMAP_ENDIAN_DEFAULT) 457 if (reg_endian == REGMAP_ENDIAN_DEFAULT)
435 reg_endian = bus->reg_format_endian_default; 458 reg_endian = bus->reg_format_endian_default;
@@ -581,6 +604,11 @@ struct regmap *regmap_init(struct device *dev,
581 goto err_map; 604 goto err_map;
582 } 605 }
583 606
607 if (map->format.format_write)
608 map->reg_write = _regmap_bus_formatted_write;
609 else if (map->format.format_val)
610 map->reg_write = _regmap_bus_raw_write;
611
584 map->range_tree = RB_ROOT; 612 map->range_tree = RB_ROOT;
585 for (i = 0; i < config->num_ranges; i++) { 613 for (i = 0; i < config->num_ranges; i++) {
586 const struct regmap_range_cfg *range_cfg = &config->ranges[i]; 614 const struct regmap_range_cfg *range_cfg = &config->ranges[i];
@@ -876,10 +904,13 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
876} 904}
877 905
878static int _regmap_raw_write(struct regmap *map, unsigned int reg, 906static int _regmap_raw_write(struct regmap *map, unsigned int reg,
879 const void *val, size_t val_len) 907 const void *val, size_t val_len, bool async)
880{ 908{
881 struct regmap_range_node *range; 909 struct regmap_range_node *range;
910 unsigned long flags;
882 u8 *u8 = map->work_buf; 911 u8 *u8 = map->work_buf;
912 void *work_val = map->work_buf + map->format.reg_bytes +
913 map->format.pad_bytes;
883 void *buf; 914 void *buf;
884 int ret = -ENOTSUPP; 915 int ret = -ENOTSUPP;
885 size_t len; 916 size_t len;
@@ -924,7 +955,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
924 dev_dbg(map->dev, "Writing window %d/%zu\n", 955 dev_dbg(map->dev, "Writing window %d/%zu\n",
925 win_residue, val_len / map->format.val_bytes); 956 win_residue, val_len / map->format.val_bytes);
926 ret = _regmap_raw_write(map, reg, val, win_residue * 957 ret = _regmap_raw_write(map, reg, val, win_residue *
927 map->format.val_bytes); 958 map->format.val_bytes, async);
928 if (ret != 0) 959 if (ret != 0)
929 return ret; 960 return ret;
930 961
@@ -947,6 +978,50 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
947 978
948 u8[0] |= map->write_flag_mask; 979 u8[0] |= map->write_flag_mask;
949 980
981 if (async && map->bus->async_write) {
982 struct regmap_async *async = map->bus->async_alloc();
983 if (!async)
984 return -ENOMEM;
985
986 async->work_buf = kzalloc(map->format.buf_size,
987 GFP_KERNEL | GFP_DMA);
988 if (!async->work_buf) {
989 kfree(async);
990 return -ENOMEM;
991 }
992
993 INIT_WORK(&async->cleanup, async_cleanup);
994 async->map = map;
995
996 /* If the caller supplied the value we can use it safely. */
997 memcpy(async->work_buf, map->work_buf, map->format.pad_bytes +
998 map->format.reg_bytes + map->format.val_bytes);
999 if (val == work_val)
1000 val = async->work_buf + map->format.pad_bytes +
1001 map->format.reg_bytes;
1002
1003 spin_lock_irqsave(&map->async_lock, flags);
1004 list_add_tail(&async->list, &map->async_list);
1005 spin_unlock_irqrestore(&map->async_lock, flags);
1006
1007 ret = map->bus->async_write(map->bus_context, async->work_buf,
1008 map->format.reg_bytes +
1009 map->format.pad_bytes,
1010 val, val_len, async);
1011
1012 if (ret != 0) {
1013 dev_err(map->dev, "Failed to schedule write: %d\n",
1014 ret);
1015
1016 spin_lock_irqsave(&map->async_lock, flags);
1017 list_del(&async->list);
1018 spin_unlock_irqrestore(&map->async_lock, flags);
1019
1020 kfree(async->work_buf);
1021 kfree(async);
1022 }
1023 }
1024
950 trace_regmap_hw_write_start(map->dev, reg, 1025 trace_regmap_hw_write_start(map->dev, reg,
951 val_len / map->format.val_bytes); 1026 val_len / map->format.val_bytes);
952 1027
@@ -954,8 +1029,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
954 * send the work_buf directly, otherwise try to do a gather 1029 * send the work_buf directly, otherwise try to do a gather
955 * write. 1030 * write.
956 */ 1031 */
957 if (val == (map->work_buf + map->format.pad_bytes + 1032 if (val == work_val)
958 map->format.reg_bytes))
959 ret = map->bus->write(map->bus_context, map->work_buf, 1033 ret = map->bus->write(map->bus_context, map->work_buf,
960 map->format.reg_bytes + 1034 map->format.reg_bytes +
961 map->format.pad_bytes + 1035 map->format.pad_bytes +
@@ -987,12 +1061,54 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
987 return ret; 1061 return ret;
988} 1062}
989 1063
1064static int _regmap_bus_formatted_write(void *context, unsigned int reg,
1065 unsigned int val)
1066{
1067 int ret;
1068 struct regmap_range_node *range;
1069 struct regmap *map = context;
1070
1071 BUG_ON(!map->format.format_write);
1072
1073 range = _regmap_range_lookup(map, reg);
1074 if (range) {
1075 ret = _regmap_select_page(map, &reg, range, 1);
1076 if (ret != 0)
1077 return ret;
1078 }
1079
1080 map->format.format_write(map, reg, val);
1081
1082 trace_regmap_hw_write_start(map->dev, reg, 1);
1083
1084 ret = map->bus->write(map->bus_context, map->work_buf,
1085 map->format.buf_size);
1086
1087 trace_regmap_hw_write_done(map->dev, reg, 1);
1088
1089 return ret;
1090}
1091
1092static int _regmap_bus_raw_write(void *context, unsigned int reg,
1093 unsigned int val)
1094{
1095 struct regmap *map = context;
1096
1097 BUG_ON(!map->format.format_val);
1098
1099 map->format.format_val(map->work_buf + map->format.reg_bytes
1100 + map->format.pad_bytes, val, 0);
1101 return _regmap_raw_write(map, reg,
1102 map->work_buf +
1103 map->format.reg_bytes +
1104 map->format.pad_bytes,
1105 map->format.val_bytes, false);
1106}
1107
990int _regmap_write(struct regmap *map, unsigned int reg, 1108int _regmap_write(struct regmap *map, unsigned int reg,
991 unsigned int val) 1109 unsigned int val)
992{ 1110{
993 struct regmap_range_node *range;
994 int ret; 1111 int ret;
995 BUG_ON(!map->format.format_write && !map->format.format_val);
996 1112
997 if (!map->cache_bypass && map->format.format_write) { 1113 if (!map->cache_bypass && map->format.format_write) {
998 ret = regcache_write(map, reg, val); 1114 ret = regcache_write(map, reg, val);
@@ -1011,33 +1127,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
1011 1127
1012 trace_regmap_reg_write(map->dev, reg, val); 1128 trace_regmap_reg_write(map->dev, reg, val);
1013 1129
1014 if (map->format.format_write) { 1130 return map->reg_write(map, reg, val);
1015 range = _regmap_range_lookup(map, reg);
1016 if (range) {
1017 ret = _regmap_select_page(map, &reg, range, 1);
1018 if (ret != 0)
1019 return ret;
1020 }
1021
1022 map->format.format_write(map, reg, val);
1023
1024 trace_regmap_hw_write_start(map->dev, reg, 1);
1025
1026 ret = map->bus->write(map->bus_context, map->work_buf,
1027 map->format.buf_size);
1028
1029 trace_regmap_hw_write_done(map->dev, reg, 1);
1030
1031 return ret;
1032 } else {
1033 map->format.format_val(map->work_buf + map->format.reg_bytes
1034 + map->format.pad_bytes, val, 0);
1035 return _regmap_raw_write(map, reg,
1036 map->work_buf +
1037 map->format.reg_bytes +
1038 map->format.pad_bytes,
1039 map->format.val_bytes);
1040 }
1041} 1131}
1042 1132
1043/** 1133/**
@@ -1095,7 +1185,7 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
1095 1185
1096 map->lock(map->lock_arg); 1186 map->lock(map->lock_arg);
1097 1187
1098 ret = _regmap_raw_write(map, reg, val, val_len); 1188 ret = _regmap_raw_write(map, reg, val, val_len, false);
1099 1189
1100 map->unlock(map->lock_arg); 1190 map->unlock(map->lock_arg);
1101 1191
@@ -1151,14 +1241,15 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1151 if (map->use_single_rw) { 1241 if (map->use_single_rw) {
1152 for (i = 0; i < val_count; i++) { 1242 for (i = 0; i < val_count; i++) {
1153 ret = regmap_raw_write(map, 1243 ret = regmap_raw_write(map,
1154 reg + (i * map->reg_stride), 1244 reg + (i * map->reg_stride),
1155 val + (i * val_bytes), 1245 val + (i * val_bytes),
1156 val_bytes); 1246 val_bytes);
1157 if (ret != 0) 1247 if (ret != 0)
1158 return ret; 1248 return ret;
1159 } 1249 }
1160 } else { 1250 } else {
1161 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); 1251 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count,
1252 false);
1162 } 1253 }
1163 1254
1164 if (val_bytes != 1) 1255 if (val_bytes != 1)
@@ -1170,6 +1261,48 @@ out:
1170} 1261}
1171EXPORT_SYMBOL_GPL(regmap_bulk_write); 1262EXPORT_SYMBOL_GPL(regmap_bulk_write);
1172 1263
1264/**
1265 * regmap_raw_write_async(): Write raw values to one or more registers
1266 * asynchronously
1267 *
1268 * @map: Register map to write to
1269 * @reg: Initial register to write to
1270 * @val: Block of data to be written, laid out for direct transmission to the
1271 * device. Must be valid until regmap_async_complete() is called.
1272 * @val_len: Length of data pointed to by val.
1273 *
1274 * This function is intended to be used for things like firmware
1275 * download where a large block of data needs to be transferred to the
1276 * device. No formatting will be done on the data provided.
1277 *
1278 * If supported by the underlying bus the write will be scheduled
1279 * asynchronously, helping maximise I/O speed on higher speed buses
1280 * like SPI. regmap_async_complete() can be called to ensure that all
1281 * asynchrnous writes have been completed.
1282 *
1283 * A value of zero will be returned on success, a negative errno will
1284 * be returned in error cases.
1285 */
1286int regmap_raw_write_async(struct regmap *map, unsigned int reg,
1287 const void *val, size_t val_len)
1288{
1289 int ret;
1290
1291 if (val_len % map->format.val_bytes)
1292 return -EINVAL;
1293 if (reg % map->reg_stride)
1294 return -EINVAL;
1295
1296 map->lock(map->lock_arg);
1297
1298 ret = _regmap_raw_write(map, reg, val, val_len, true);
1299
1300 map->unlock(map->lock_arg);
1301
1302 return ret;
1303}
1304EXPORT_SYMBOL_GPL(regmap_raw_write_async);
1305
1173static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, 1306static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1174 unsigned int val_len) 1307 unsigned int val_len)
1175{ 1308{
@@ -1208,10 +1341,27 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1208 return ret; 1341 return ret;
1209} 1342}
1210 1343
1344static int _regmap_bus_read(void *context, unsigned int reg,
1345 unsigned int *val)
1346{
1347 int ret;
1348 struct regmap *map = context;
1349
1350 if (!map->format.parse_val)
1351 return -EINVAL;
1352
1353 ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes);
1354 if (ret == 0)
1355 *val = map->format.parse_val(map->work_buf);
1356
1357 return ret;
1358}
1359
1211static int _regmap_read(struct regmap *map, unsigned int reg, 1360static int _regmap_read(struct regmap *map, unsigned int reg,
1212 unsigned int *val) 1361 unsigned int *val)
1213{ 1362{
1214 int ret; 1363 int ret;
1364 BUG_ON(!map->reg_read);
1215 1365
1216 if (!map->cache_bypass) { 1366 if (!map->cache_bypass) {
1217 ret = regcache_read(map, reg, val); 1367 ret = regcache_read(map, reg, val);
@@ -1219,26 +1369,21 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
1219 return 0; 1369 return 0;
1220 } 1370 }
1221 1371
1222 if (!map->format.parse_val)
1223 return -EINVAL;
1224
1225 if (map->cache_only) 1372 if (map->cache_only)
1226 return -EBUSY; 1373 return -EBUSY;
1227 1374
1228 ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); 1375 ret = map->reg_read(map, reg, val);
1229 if (ret == 0) { 1376 if (ret == 0) {
1230 *val = map->format.parse_val(map->work_buf);
1231
1232#ifdef LOG_DEVICE 1377#ifdef LOG_DEVICE
1233 if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) 1378 if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
1234 dev_info(map->dev, "%x => %x\n", reg, *val); 1379 dev_info(map->dev, "%x => %x\n", reg, *val);
1235#endif 1380#endif
1236 1381
1237 trace_regmap_reg_read(map->dev, reg, *val); 1382 trace_regmap_reg_read(map->dev, reg, *val);
1238 }
1239 1383
1240 if (ret == 0 && !map->cache_bypass) 1384 if (!map->cache_bypass)
1241 regcache_write(map, reg, *val); 1385 regcache_write(map, reg, *val);
1386 }
1242 1387
1243 return ret; 1388 return ret;
1244} 1389}
@@ -1456,6 +1601,68 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
1456} 1601}
1457EXPORT_SYMBOL_GPL(regmap_update_bits_check); 1602EXPORT_SYMBOL_GPL(regmap_update_bits_check);
1458 1603
1604void regmap_async_complete_cb(struct regmap_async *async, int ret)
1605{
1606 struct regmap *map = async->map;
1607 bool wake;
1608
1609 spin_lock(&map->async_lock);
1610
1611 list_del(&async->list);
1612 wake = list_empty(&map->async_list);
1613
1614 if (ret != 0)
1615 map->async_ret = ret;
1616
1617 spin_unlock(&map->async_lock);
1618
1619 schedule_work(&async->cleanup);
1620
1621 if (wake)
1622 wake_up(&map->async_waitq);
1623}
1624EXPORT_SYMBOL_GPL(regmap_async_complete_cb);
1625
1626static int regmap_async_is_done(struct regmap *map)
1627{
1628 unsigned long flags;
1629 int ret;
1630
1631 spin_lock_irqsave(&map->async_lock, flags);
1632 ret = list_empty(&map->async_list);
1633 spin_unlock_irqrestore(&map->async_lock, flags);
1634
1635 return ret;
1636}
1637
1638/**
1639 * regmap_async_complete: Ensure all asynchronous I/O has completed.
1640 *
1641 * @map: Map to operate on.
1642 *
1643 * Blocks until any pending asynchronous I/O has completed. Returns
1644 * an error code for any failed I/O operations.
1645 */
1646int regmap_async_complete(struct regmap *map)
1647{
1648 unsigned long flags;
1649 int ret;
1650
1651 /* Nothing to do with no async support */
1652 if (!map->bus->async_write)
1653 return 0;
1654
1655 wait_event(map->async_waitq, regmap_async_is_done(map));
1656
1657 spin_lock_irqsave(&map->async_lock, flags);
1658 ret = map->async_ret;
1659 map->async_ret = 0;
1660 spin_unlock_irqrestore(&map->async_lock, flags);
1661
1662 return ret;
1663}
1664EXPORT_SYMBOL_GPL(regmap_async_complete);
1665
1459/** 1666/**
1460 * regmap_register_patch: Register and apply register updates to be applied 1667 * regmap_register_patch: Register and apply register updates to be applied
1461 * on device initialistion 1668 * on device initialistion