aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-04 14:52:17 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-04 14:52:17 -0500
commit4c47c2b0f82c5ebe2187768b8ed05281d13b438e (patch)
tree9046ba012ad917a6edf46fe0056df56a99a3c758
parent31522764c6b57e41b79220156efc5d208f2f841a (diff)
parentf804fb562b0d9f4a8546fa2808d14e80aea8ff26 (diff)
Merge tag 'async' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into asoc-adsp
regmap: Add async I/O support Allow drivers to take advantage of any support the underlying transports may have for pipelining data.
-rw-r--r--drivers/base/regmap/internal.h18
-rw-r--r--drivers/base/regmap/regmap-spi.c52
-rw-r--r--drivers/base/regmap/regmap.c300
-rw-r--r--include/linux/regmap.h28
4 files changed, 351 insertions, 47 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 401d1919635a..202518641779 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -16,6 +16,7 @@
16#include <linux/regmap.h> 16#include <linux/regmap.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/wait.h>
19 20
20struct regmap; 21struct regmap;
21struct regcache_ops; 22struct regcache_ops;
@@ -39,6 +40,13 @@ struct regmap_format {
39 unsigned int (*parse_val)(void *buf); 40 unsigned int (*parse_val)(void *buf);
40}; 41};
41 42
43struct regmap_async {
44 struct list_head list;
45 struct work_struct cleanup;
46 struct regmap *map;
47 void *work_buf;
48};
49
42struct regmap { 50struct regmap {
43 struct mutex mutex; 51 struct mutex mutex;
44 spinlock_t spinlock; 52 spinlock_t spinlock;
@@ -53,6 +61,11 @@ struct regmap {
53 void *bus_context; 61 void *bus_context;
54 const char *name; 62 const char *name;
55 63
64 spinlock_t async_lock;
65 wait_queue_head_t async_waitq;
66 struct list_head async_list;
67 int async_ret;
68
56#ifdef CONFIG_DEBUG_FS 69#ifdef CONFIG_DEBUG_FS
57 struct dentry *debugfs; 70 struct dentry *debugfs;
58 const char *debugfs_name; 71 const char *debugfs_name;
@@ -74,6 +87,9 @@ struct regmap {
74 const struct regmap_access_table *volatile_table; 87 const struct regmap_access_table *volatile_table;
75 const struct regmap_access_table *precious_table; 88 const struct regmap_access_table *precious_table;
76 89
90 int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
91 int (*reg_write)(void *context, unsigned int reg, unsigned int val);
92
77 u8 read_flag_mask; 93 u8 read_flag_mask;
78 u8 write_flag_mask; 94 u8 write_flag_mask;
79 95
@@ -175,6 +191,8 @@ bool regcache_set_val(void *base, unsigned int idx,
175 unsigned int val, unsigned int word_size); 191 unsigned int val, unsigned int word_size);
176int regcache_lookup_reg(struct regmap *map, unsigned int reg); 192int regcache_lookup_reg(struct regmap *map, unsigned int reg);
177 193
194void regmap_async_complete_cb(struct regmap_async *async, int ret);
195
178extern struct regcache_ops regcache_rbtree_ops; 196extern struct regcache_ops regcache_rbtree_ops;
179extern struct regcache_ops regcache_lzo_ops; 197extern struct regcache_ops regcache_lzo_ops;
180 198
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c
index ffa46a92ad33..913274b5f00a 100644
--- a/drivers/base/regmap/regmap-spi.c
+++ b/drivers/base/regmap/regmap-spi.c
@@ -15,6 +15,21 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17 17
18#include "internal.h"
19
20struct regmap_async_spi {
21 struct regmap_async core;
22 struct spi_message m;
23 struct spi_transfer t[2];
24};
25
26static void regmap_spi_complete(void *data)
27{
28 struct regmap_async_spi *async = data;
29
30 regmap_async_complete_cb(&async->core, async->m.status);
31}
32
18static int regmap_spi_write(void *context, const void *data, size_t count) 33static int regmap_spi_write(void *context, const void *data, size_t count)
19{ 34{
20 struct device *dev = context; 35 struct device *dev = context;
@@ -40,6 +55,41 @@ static int regmap_spi_gather_write(void *context,
40 return spi_sync(spi, &m); 55 return spi_sync(spi, &m);
41} 56}
42 57
58static int regmap_spi_async_write(void *context,
59 const void *reg, size_t reg_len,
60 const void *val, size_t val_len,
61 struct regmap_async *a)
62{
63 struct regmap_async_spi *async = container_of(a,
64 struct regmap_async_spi,
65 core);
66 struct device *dev = context;
67 struct spi_device *spi = to_spi_device(dev);
68
69 async->t[0].tx_buf = reg;
70 async->t[0].len = reg_len;
71 async->t[1].tx_buf = val;
72 async->t[1].len = val_len;
73
74 spi_message_init(&async->m);
75 spi_message_add_tail(&async->t[0], &async->m);
76 spi_message_add_tail(&async->t[1], &async->m);
77
78 async->m.complete = regmap_spi_complete;
79 async->m.context = async;
80
81 return spi_async(spi, &async->m);
82}
83
84static struct regmap_async *regmap_spi_async_alloc(void)
85{
86 struct regmap_async_spi *async_spi;
87
88 async_spi = kzalloc(sizeof(*async_spi), GFP_KERNEL);
89
90 return &async_spi->core;
91}
92
43static int regmap_spi_read(void *context, 93static int regmap_spi_read(void *context,
44 const void *reg, size_t reg_size, 94 const void *reg, size_t reg_size,
45 void *val, size_t val_size) 95 void *val, size_t val_size)
@@ -53,6 +103,8 @@ static int regmap_spi_read(void *context,
53static struct regmap_bus regmap_spi = { 103static struct regmap_bus regmap_spi = {
54 .write = regmap_spi_write, 104 .write = regmap_spi_write,
55 .gather_write = regmap_spi_gather_write, 105 .gather_write = regmap_spi_gather_write,
106 .async_write = regmap_spi_async_write,
107 .async_alloc = regmap_spi_async_alloc,
56 .read = regmap_spi_read, 108 .read = regmap_spi_read,
57 .read_flag_mask = 0x80, 109 .read_flag_mask = 0x80,
58}; 110};
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 42d5cb0f503f..6d1e756e90ad 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;
@@ -575,6 +598,11 @@ struct regmap *regmap_init(struct device *dev,
575 goto err_map; 598 goto err_map;
576 } 599 }
577 600
601 if (map->format.format_write)
602 map->reg_write = _regmap_bus_formatted_write;
603 else if (map->format.format_val)
604 map->reg_write = _regmap_bus_raw_write;
605
578 map->range_tree = RB_ROOT; 606 map->range_tree = RB_ROOT;
579 for (i = 0; i < config->num_ranges; i++) { 607 for (i = 0; i < config->num_ranges; i++) {
580 const struct regmap_range_cfg *range_cfg = &config->ranges[i]; 608 const struct regmap_range_cfg *range_cfg = &config->ranges[i];
@@ -870,10 +898,13 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
870} 898}
871 899
872static int _regmap_raw_write(struct regmap *map, unsigned int reg, 900static int _regmap_raw_write(struct regmap *map, unsigned int reg,
873 const void *val, size_t val_len) 901 const void *val, size_t val_len, bool async)
874{ 902{
875 struct regmap_range_node *range; 903 struct regmap_range_node *range;
904 unsigned long flags;
876 u8 *u8 = map->work_buf; 905 u8 *u8 = map->work_buf;
906 void *work_val = map->work_buf + map->format.reg_bytes +
907 map->format.pad_bytes;
877 void *buf; 908 void *buf;
878 int ret = -ENOTSUPP; 909 int ret = -ENOTSUPP;
879 size_t len; 910 size_t len;
@@ -918,7 +949,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
918 dev_dbg(map->dev, "Writing window %d/%zu\n", 949 dev_dbg(map->dev, "Writing window %d/%zu\n",
919 win_residue, val_len / map->format.val_bytes); 950 win_residue, val_len / map->format.val_bytes);
920 ret = _regmap_raw_write(map, reg, val, win_residue * 951 ret = _regmap_raw_write(map, reg, val, win_residue *
921 map->format.val_bytes); 952 map->format.val_bytes, async);
922 if (ret != 0) 953 if (ret != 0)
923 return ret; 954 return ret;
924 955
@@ -941,6 +972,50 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
941 972
942 u8[0] |= map->write_flag_mask; 973 u8[0] |= map->write_flag_mask;
943 974
975 if (async && map->bus->async_write) {
976 struct regmap_async *async = map->bus->async_alloc();
977 if (!async)
978 return -ENOMEM;
979
980 async->work_buf = kzalloc(map->format.buf_size,
981 GFP_KERNEL | GFP_DMA);
982 if (!async->work_buf) {
983 kfree(async);
984 return -ENOMEM;
985 }
986
987 INIT_WORK(&async->cleanup, async_cleanup);
988 async->map = map;
989
990 /* If the caller supplied the value we can use it safely. */
991 memcpy(async->work_buf, map->work_buf, map->format.pad_bytes +
992 map->format.reg_bytes + map->format.val_bytes);
993 if (val == work_val)
994 val = async->work_buf + map->format.pad_bytes +
995 map->format.reg_bytes;
996
997 spin_lock_irqsave(&map->async_lock, flags);
998 list_add_tail(&async->list, &map->async_list);
999 spin_unlock_irqrestore(&map->async_lock, flags);
1000
1001 ret = map->bus->async_write(map->bus_context, async->work_buf,
1002 map->format.reg_bytes +
1003 map->format.pad_bytes,
1004 val, val_len, async);
1005
1006 if (ret != 0) {
1007 dev_err(map->dev, "Failed to schedule write: %d\n",
1008 ret);
1009
1010 spin_lock_irqsave(&map->async_lock, flags);
1011 list_del(&async->list);
1012 spin_unlock_irqrestore(&map->async_lock, flags);
1013
1014 kfree(async->work_buf);
1015 kfree(async);
1016 }
1017 }
1018
944 trace_regmap_hw_write_start(map->dev, reg, 1019 trace_regmap_hw_write_start(map->dev, reg,
945 val_len / map->format.val_bytes); 1020 val_len / map->format.val_bytes);
946 1021
@@ -948,8 +1023,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
948 * send the work_buf directly, otherwise try to do a gather 1023 * send the work_buf directly, otherwise try to do a gather
949 * write. 1024 * write.
950 */ 1025 */
951 if (val == (map->work_buf + map->format.pad_bytes + 1026 if (val == work_val)
952 map->format.reg_bytes))
953 ret = map->bus->write(map->bus_context, map->work_buf, 1027 ret = map->bus->write(map->bus_context, map->work_buf,
954 map->format.reg_bytes + 1028 map->format.reg_bytes +
955 map->format.pad_bytes + 1029 map->format.pad_bytes +
@@ -981,12 +1055,54 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
981 return ret; 1055 return ret;
982} 1056}
983 1057
1058static int _regmap_bus_formatted_write(void *context, unsigned int reg,
1059 unsigned int val)
1060{
1061 int ret;
1062 struct regmap_range_node *range;
1063 struct regmap *map = context;
1064
1065 BUG_ON(!map->format.format_write);
1066
1067 range = _regmap_range_lookup(map, reg);
1068 if (range) {
1069 ret = _regmap_select_page(map, &reg, range, 1);
1070 if (ret != 0)
1071 return ret;
1072 }
1073
1074 map->format.format_write(map, reg, val);
1075
1076 trace_regmap_hw_write_start(map->dev, reg, 1);
1077
1078 ret = map->bus->write(map->bus_context, map->work_buf,
1079 map->format.buf_size);
1080
1081 trace_regmap_hw_write_done(map->dev, reg, 1);
1082
1083 return ret;
1084}
1085
1086static int _regmap_bus_raw_write(void *context, unsigned int reg,
1087 unsigned int val)
1088{
1089 struct regmap *map = context;
1090
1091 BUG_ON(!map->format.format_val);
1092
1093 map->format.format_val(map->work_buf + map->format.reg_bytes
1094 + map->format.pad_bytes, val, 0);
1095 return _regmap_raw_write(map, reg,
1096 map->work_buf +
1097 map->format.reg_bytes +
1098 map->format.pad_bytes,
1099 map->format.val_bytes, false);
1100}
1101
984int _regmap_write(struct regmap *map, unsigned int reg, 1102int _regmap_write(struct regmap *map, unsigned int reg,
985 unsigned int val) 1103 unsigned int val)
986{ 1104{
987 struct regmap_range_node *range;
988 int ret; 1105 int ret;
989 BUG_ON(!map->format.format_write && !map->format.format_val);
990 1106
991 if (!map->cache_bypass && map->format.format_write) { 1107 if (!map->cache_bypass && map->format.format_write) {
992 ret = regcache_write(map, reg, val); 1108 ret = regcache_write(map, reg, val);
@@ -1005,33 +1121,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
1005 1121
1006 trace_regmap_reg_write(map->dev, reg, val); 1122 trace_regmap_reg_write(map->dev, reg, val);
1007 1123
1008 if (map->format.format_write) { 1124 return map->reg_write(map, reg, val);
1009 range = _regmap_range_lookup(map, reg);
1010 if (range) {
1011 ret = _regmap_select_page(map, &reg, range, 1);
1012 if (ret != 0)
1013 return ret;
1014 }
1015
1016 map->format.format_write(map, reg, val);
1017
1018 trace_regmap_hw_write_start(map->dev, reg, 1);
1019
1020 ret = map->bus->write(map->bus_context, map->work_buf,
1021 map->format.buf_size);
1022
1023 trace_regmap_hw_write_done(map->dev, reg, 1);
1024
1025 return ret;
1026 } else {
1027 map->format.format_val(map->work_buf + map->format.reg_bytes
1028 + map->format.pad_bytes, val, 0);
1029 return _regmap_raw_write(map, reg,
1030 map->work_buf +
1031 map->format.reg_bytes +
1032 map->format.pad_bytes,
1033 map->format.val_bytes);
1034 }
1035} 1125}
1036 1126
1037/** 1127/**
@@ -1089,7 +1179,7 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
1089 1179
1090 map->lock(map->lock_arg); 1180 map->lock(map->lock_arg);
1091 1181
1092 ret = _regmap_raw_write(map, reg, val, val_len); 1182 ret = _regmap_raw_write(map, reg, val, val_len, false);
1093 1183
1094 map->unlock(map->lock_arg); 1184 map->unlock(map->lock_arg);
1095 1185
@@ -1145,14 +1235,15 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1145 if (map->use_single_rw) { 1235 if (map->use_single_rw) {
1146 for (i = 0; i < val_count; i++) { 1236 for (i = 0; i < val_count; i++) {
1147 ret = regmap_raw_write(map, 1237 ret = regmap_raw_write(map,
1148 reg + (i * map->reg_stride), 1238 reg + (i * map->reg_stride),
1149 val + (i * val_bytes), 1239 val + (i * val_bytes),
1150 val_bytes); 1240 val_bytes);
1151 if (ret != 0) 1241 if (ret != 0)
1152 return ret; 1242 return ret;
1153 } 1243 }
1154 } else { 1244 } else {
1155 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); 1245 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count,
1246 false);
1156 } 1247 }
1157 1248
1158 if (val_bytes != 1) 1249 if (val_bytes != 1)
@@ -1164,6 +1255,48 @@ out:
1164} 1255}
1165EXPORT_SYMBOL_GPL(regmap_bulk_write); 1256EXPORT_SYMBOL_GPL(regmap_bulk_write);
1166 1257
1258/**
1259 * regmap_raw_write_async(): Write raw values to one or more registers
1260 * asynchronously
1261 *
1262 * @map: Register map to write to
1263 * @reg: Initial register to write to
1264 * @val: Block of data to be written, laid out for direct transmission to the
1265 * device. Must be valid until regmap_async_complete() is called.
1266 * @val_len: Length of data pointed to by val.
1267 *
1268 * This function is intended to be used for things like firmware
1269 * download where a large block of data needs to be transferred to the
1270 * device. No formatting will be done on the data provided.
1271 *
1272 * If supported by the underlying bus the write will be scheduled
1273 * asynchronously, helping maximise I/O speed on higher speed buses
1274 * like SPI. regmap_async_complete() can be called to ensure that all
1275 * asynchrnous writes have been completed.
1276 *
1277 * A value of zero will be returned on success, a negative errno will
1278 * be returned in error cases.
1279 */
1280int regmap_raw_write_async(struct regmap *map, unsigned int reg,
1281 const void *val, size_t val_len)
1282{
1283 int ret;
1284
1285 if (val_len % map->format.val_bytes)
1286 return -EINVAL;
1287 if (reg % map->reg_stride)
1288 return -EINVAL;
1289
1290 map->lock(map->lock_arg);
1291
1292 ret = _regmap_raw_write(map, reg, val, val_len, true);
1293
1294 map->unlock(map->lock_arg);
1295
1296 return ret;
1297}
1298EXPORT_SYMBOL_GPL(regmap_raw_write_async);
1299
1167static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, 1300static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1168 unsigned int val_len) 1301 unsigned int val_len)
1169{ 1302{
@@ -1202,10 +1335,27 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1202 return ret; 1335 return ret;
1203} 1336}
1204 1337
1338static int _regmap_bus_read(void *context, unsigned int reg,
1339 unsigned int *val)
1340{
1341 int ret;
1342 struct regmap *map = context;
1343
1344 if (!map->format.parse_val)
1345 return -EINVAL;
1346
1347 ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes);
1348 if (ret == 0)
1349 *val = map->format.parse_val(map->work_buf);
1350
1351 return ret;
1352}
1353
1205static int _regmap_read(struct regmap *map, unsigned int reg, 1354static int _regmap_read(struct regmap *map, unsigned int reg,
1206 unsigned int *val) 1355 unsigned int *val)
1207{ 1356{
1208 int ret; 1357 int ret;
1358 BUG_ON(!map->reg_read);
1209 1359
1210 if (!map->cache_bypass) { 1360 if (!map->cache_bypass) {
1211 ret = regcache_read(map, reg, val); 1361 ret = regcache_read(map, reg, val);
@@ -1213,26 +1363,21 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
1213 return 0; 1363 return 0;
1214 } 1364 }
1215 1365
1216 if (!map->format.parse_val)
1217 return -EINVAL;
1218
1219 if (map->cache_only) 1366 if (map->cache_only)
1220 return -EBUSY; 1367 return -EBUSY;
1221 1368
1222 ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); 1369 ret = map->reg_read(map, reg, val);
1223 if (ret == 0) { 1370 if (ret == 0) {
1224 *val = map->format.parse_val(map->work_buf);
1225
1226#ifdef LOG_DEVICE 1371#ifdef LOG_DEVICE
1227 if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) 1372 if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
1228 dev_info(map->dev, "%x => %x\n", reg, *val); 1373 dev_info(map->dev, "%x => %x\n", reg, *val);
1229#endif 1374#endif
1230 1375
1231 trace_regmap_reg_read(map->dev, reg, *val); 1376 trace_regmap_reg_read(map->dev, reg, *val);
1232 }
1233 1377
1234 if (ret == 0 && !map->cache_bypass) 1378 if (!map->cache_bypass)
1235 regcache_write(map, reg, *val); 1379 regcache_write(map, reg, *val);
1380 }
1236 1381
1237 return ret; 1382 return ret;
1238} 1383}
@@ -1450,6 +1595,67 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
1450} 1595}
1451EXPORT_SYMBOL_GPL(regmap_update_bits_check); 1596EXPORT_SYMBOL_GPL(regmap_update_bits_check);
1452 1597
1598void regmap_async_complete_cb(struct regmap_async *async, int ret)
1599{
1600 struct regmap *map = async->map;
1601 bool wake;
1602
1603 spin_lock(&map->async_lock);
1604
1605 list_del(&async->list);
1606 wake = list_empty(&map->async_list);
1607
1608 if (ret != 0)
1609 map->async_ret = ret;
1610
1611 spin_unlock(&map->async_lock);
1612
1613 schedule_work(&async->cleanup);
1614
1615 if (wake)
1616 wake_up(&map->async_waitq);
1617}
1618EXPORT_SYMBOL_GPL(regmap_async_complete_cb);
1619
1620static int regmap_async_is_done(struct regmap *map)
1621{
1622 unsigned long flags;
1623 int ret;
1624
1625 spin_lock_irqsave(&map->async_lock, flags);
1626 ret = list_empty(&map->async_list);
1627 spin_unlock_irqrestore(&map->async_lock, flags);
1628
1629 return ret;
1630}
1631
1632/**
1633 * regmap_async_complete: Ensure all asynchronous I/O has completed.
1634 *
1635 * @map: Map to operate on.
1636 *
1637 * Blocks until any pending asynchronous I/O has completed. Returns
1638 * an error code for any failed I/O operations.
1639 */
1640int regmap_async_complete(struct regmap *map)
1641{
1642 unsigned long flags;
1643 int ret;
1644
1645 /* Nothing to do with no async support */
1646 if (!map->bus->async_write)
1647 return 0;
1648
1649 wait_event(map->async_waitq, regmap_async_is_done(map));
1650
1651 spin_lock_irqsave(&map->async_lock, flags);
1652 ret = map->async_ret;
1653 map->async_ret = 0;
1654 spin_unlock_irqrestore(&map->async_lock, flags);
1655
1656 return ret;
1657}
1658
1453/** 1659/**
1454 * regmap_register_patch: Register and apply register updates to be applied 1660 * regmap_register_patch: Register and apply register updates to be applied
1455 * on device initialistion 1661 * on device initialistion
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index b7e95bf942c9..f9b7fbe35ab1 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -235,14 +235,21 @@ struct regmap_range_cfg {
235 unsigned int window_len; 235 unsigned int window_len;
236}; 236};
237 237
238struct regmap_async;
239
238typedef int (*regmap_hw_write)(void *context, const void *data, 240typedef int (*regmap_hw_write)(void *context, const void *data,
239 size_t count); 241 size_t count);
240typedef int (*regmap_hw_gather_write)(void *context, 242typedef int (*regmap_hw_gather_write)(void *context,
241 const void *reg, size_t reg_len, 243 const void *reg, size_t reg_len,
242 const void *val, size_t val_len); 244 const void *val, size_t val_len);
245typedef int (*regmap_hw_async_write)(void *context,
246 const void *reg, size_t reg_len,
247 const void *val, size_t val_len,
248 struct regmap_async *async);
243typedef int (*regmap_hw_read)(void *context, 249typedef int (*regmap_hw_read)(void *context,
244 const void *reg_buf, size_t reg_size, 250 const void *reg_buf, size_t reg_size,
245 void *val_buf, size_t val_size); 251 void *val_buf, size_t val_size);
252typedef struct regmap_async *(*regmap_hw_async_alloc)(void);
246typedef void (*regmap_hw_free_context)(void *context); 253typedef void (*regmap_hw_free_context)(void *context);
247 254
248/** 255/**
@@ -255,8 +262,11 @@ typedef void (*regmap_hw_free_context)(void *context);
255 * @write: Write operation. 262 * @write: Write operation.
256 * @gather_write: Write operation with split register/value, return -ENOTSUPP 263 * @gather_write: Write operation with split register/value, return -ENOTSUPP
257 * if not implemented on a given device. 264 * if not implemented on a given device.
265 * @async_write: Write operation which completes asynchronously, optional and
266 * must serialise with respect to non-async I/O.
258 * @read: Read operation. Data is returned in the buffer used to transmit 267 * @read: Read operation. Data is returned in the buffer used to transmit
259 * data. 268 * data.
269 * @async_alloc: Allocate a regmap_async() structure.
260 * @read_flag_mask: Mask to be set in the top byte of the register when doing 270 * @read_flag_mask: Mask to be set in the top byte of the register when doing
261 * a read. 271 * a read.
262 * @reg_format_endian_default: Default endianness for formatted register 272 * @reg_format_endian_default: Default endianness for formatted register
@@ -265,13 +275,16 @@ typedef void (*regmap_hw_free_context)(void *context);
265 * @val_format_endian_default: Default endianness for formatted register 275 * @val_format_endian_default: Default endianness for formatted register
266 * values. Used when the regmap_config specifies DEFAULT. If this is 276 * values. Used when the regmap_config specifies DEFAULT. If this is
267 * DEFAULT, BIG is assumed. 277 * DEFAULT, BIG is assumed.
278 * @async_size: Size of struct used for async work.
268 */ 279 */
269struct regmap_bus { 280struct regmap_bus {
270 bool fast_io; 281 bool fast_io;
271 regmap_hw_write write; 282 regmap_hw_write write;
272 regmap_hw_gather_write gather_write; 283 regmap_hw_gather_write gather_write;
284 regmap_hw_async_write async_write;
273 regmap_hw_read read; 285 regmap_hw_read read;
274 regmap_hw_free_context free_context; 286 regmap_hw_free_context free_context;
287 regmap_hw_async_alloc async_alloc;
275 u8 read_flag_mask; 288 u8 read_flag_mask;
276 enum regmap_endian reg_format_endian_default; 289 enum regmap_endian reg_format_endian_default;
277 enum regmap_endian val_format_endian_default; 290 enum regmap_endian val_format_endian_default;
@@ -310,6 +323,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
310 const void *val, size_t val_len); 323 const void *val, size_t val_len);
311int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, 324int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
312 size_t val_count); 325 size_t val_count);
326int regmap_raw_write_async(struct regmap *map, unsigned int reg,
327 const void *val, size_t val_len);
313int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val); 328int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
314int regmap_raw_read(struct regmap *map, unsigned int reg, 329int regmap_raw_read(struct regmap *map, unsigned int reg,
315 void *val, size_t val_len); 330 void *val, size_t val_len);
@@ -321,6 +336,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
321 unsigned int mask, unsigned int val, 336 unsigned int mask, unsigned int val,
322 bool *change); 337 bool *change);
323int regmap_get_val_bytes(struct regmap *map); 338int regmap_get_val_bytes(struct regmap *map);
339int regmap_async_complete(struct regmap *map);
324 340
325int regcache_sync(struct regmap *map); 341int regcache_sync(struct regmap *map);
326int regcache_sync_region(struct regmap *map, unsigned int min, 342int regcache_sync_region(struct regmap *map, unsigned int min,
@@ -422,6 +438,13 @@ static inline int regmap_raw_write(struct regmap *map, unsigned int reg,
422 return -EINVAL; 438 return -EINVAL;
423} 439}
424 440
441static inline int regmap_raw_write_async(struct regmap *map, unsigned int reg,
442 const void *val, size_t val_len)
443{
444 WARN_ONCE(1, "regmap API is disabled");
445 return -EINVAL;
446}
447
425static inline int regmap_bulk_write(struct regmap *map, unsigned int reg, 448static inline int regmap_bulk_write(struct regmap *map, unsigned int reg,
426 const void *val, size_t val_count) 449 const void *val, size_t val_count)
427{ 450{
@@ -500,6 +523,11 @@ static inline void regcache_mark_dirty(struct regmap *map)
500 WARN_ONCE(1, "regmap API is disabled"); 523 WARN_ONCE(1, "regmap API is disabled");
501} 524}
502 525
526static inline void regmap_async_complete(struct regmap *map)
527{
528 WARN_ONCE(1, "regmap API is disabled");
529}
530
503static inline int regmap_register_patch(struct regmap *map, 531static inline int regmap_register_patch(struct regmap *map,
504 const struct reg_default *regs, 532 const struct reg_default *regs,
505 int num_regs) 533 int num_regs)