aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavide Ciminaghi <ciminaghi@gnudd.com>2012-10-16 09:56:59 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-10-17 03:52:02 -0400
commit0d4529c534c1c664f25088eb5f5b4d7ce0ee2510 (patch)
tree5b080ef0a319b90fbcb0ab4eb768aae54851915e /drivers
parentddffeb8c4d0331609ef2581d84de4d763607bd37 (diff)
regmap: make lock/unlock functions customizable
It is sometimes convenient for a regmap user to override the standard regmap lock/unlock functions with custom functions. For instance this can be useful in case an already existing spinlock or mutex has to be used for locking a set of registers instead of the internal regmap spinlock/mutex. Note that the fast_io field of struct regmap_bus is ignored in case custom locking functions are used. Signed-off-by: Davide Ciminaghi <ciminaghi@gnudd.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/regmap/internal.h4
-rw-r--r--drivers/base/regmap/regmap.c65
2 files changed, 39 insertions, 30 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 80f9ab9c3aa4..b1ee824e2a5f 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -31,14 +31,12 @@ struct regmap_format {
31 unsigned int (*parse_val)(void *buf); 31 unsigned int (*parse_val)(void *buf);
32}; 32};
33 33
34typedef void (*regmap_lock)(struct regmap *map);
35typedef void (*regmap_unlock)(struct regmap *map);
36
37struct regmap { 34struct regmap {
38 struct mutex mutex; 35 struct mutex mutex;
39 spinlock_t spinlock; 36 spinlock_t spinlock;
40 regmap_lock lock; 37 regmap_lock lock;
41 regmap_unlock unlock; 38 regmap_unlock unlock;
39 void *lock_arg; /* This is passed to lock/unlock functions */
42 40
43 struct device *dev; /* Device we do I/O on */ 41 struct device *dev; /* Device we do I/O on */
44 void *work_buf; /* Scratch buffer used to format I/O */ 42 void *work_buf; /* Scratch buffer used to format I/O */
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 52069d29ff12..5d8b75255b50 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -214,23 +214,27 @@ static unsigned int regmap_parse_32_native(void *buf)
214 return *(u32 *)buf; 214 return *(u32 *)buf;
215} 215}
216 216
217static void regmap_lock_mutex(struct regmap *map) 217static void regmap_lock_mutex(void *__map)
218{ 218{
219 struct regmap *map = __map;
219 mutex_lock(&map->mutex); 220 mutex_lock(&map->mutex);
220} 221}
221 222
222static void regmap_unlock_mutex(struct regmap *map) 223static void regmap_unlock_mutex(void *__map)
223{ 224{
225 struct regmap *map = __map;
224 mutex_unlock(&map->mutex); 226 mutex_unlock(&map->mutex);
225} 227}
226 228
227static void regmap_lock_spinlock(struct regmap *map) 229static void regmap_lock_spinlock(void *__map)
228{ 230{
231 struct regmap *map = __map;
229 spin_lock(&map->spinlock); 232 spin_lock(&map->spinlock);
230} 233}
231 234
232static void regmap_unlock_spinlock(struct regmap *map) 235static void regmap_unlock_spinlock(void *__map)
233{ 236{
237 struct regmap *map = __map;
234 spin_unlock(&map->spinlock); 238 spin_unlock(&map->spinlock);
235} 239}
236 240
@@ -335,14 +339,21 @@ struct regmap *regmap_init(struct device *dev,
335 goto err; 339 goto err;
336 } 340 }
337 341
338 if (bus->fast_io) { 342 if (config->lock && config->unlock) {
339 spin_lock_init(&map->spinlock); 343 map->lock = config->lock;
340 map->lock = regmap_lock_spinlock; 344 map->unlock = config->unlock;
341 map->unlock = regmap_unlock_spinlock; 345 map->lock_arg = config->lock_arg;
342 } else { 346 } else {
343 mutex_init(&map->mutex); 347 if (bus->fast_io) {
344 map->lock = regmap_lock_mutex; 348 spin_lock_init(&map->spinlock);
345 map->unlock = regmap_unlock_mutex; 349 map->lock = regmap_lock_spinlock;
350 map->unlock = regmap_unlock_spinlock;
351 } else {
352 mutex_init(&map->mutex);
353 map->lock = regmap_lock_mutex;
354 map->unlock = regmap_unlock_mutex;
355 }
356 map->lock_arg = map;
346 } 357 }
347 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); 358 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
348 map->format.pad_bytes = config->pad_bits / 8; 359 map->format.pad_bytes = config->pad_bits / 8;
@@ -939,11 +950,11 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
939 if (reg % map->reg_stride) 950 if (reg % map->reg_stride)
940 return -EINVAL; 951 return -EINVAL;
941 952
942 map->lock(map); 953 map->lock(map->lock_arg);
943 954
944 ret = _regmap_write(map, reg, val); 955 ret = _regmap_write(map, reg, val);
945 956
946 map->unlock(map); 957 map->unlock(map->lock_arg);
947 958
948 return ret; 959 return ret;
949} 960}
@@ -975,11 +986,11 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
975 if (reg % map->reg_stride) 986 if (reg % map->reg_stride)
976 return -EINVAL; 987 return -EINVAL;
977 988
978 map->lock(map); 989 map->lock(map->lock_arg);
979 990
980 ret = _regmap_raw_write(map, reg, val, val_len); 991 ret = _regmap_raw_write(map, reg, val, val_len);
981 992
982 map->unlock(map); 993 map->unlock(map->lock_arg);
983 994
984 return ret; 995 return ret;
985} 996}
@@ -1011,7 +1022,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1011 if (reg % map->reg_stride) 1022 if (reg % map->reg_stride)
1012 return -EINVAL; 1023 return -EINVAL;
1013 1024
1014 map->lock(map); 1025 map->lock(map->lock_arg);
1015 1026
1016 /* No formatting is require if val_byte is 1 */ 1027 /* No formatting is require if val_byte is 1 */
1017 if (val_bytes == 1) { 1028 if (val_bytes == 1) {
@@ -1047,7 +1058,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1047 kfree(wval); 1058 kfree(wval);
1048 1059
1049out: 1060out:
1050 map->unlock(map); 1061 map->unlock(map->lock_arg);
1051 return ret; 1062 return ret;
1052} 1063}
1053EXPORT_SYMBOL_GPL(regmap_bulk_write); 1064EXPORT_SYMBOL_GPL(regmap_bulk_write);
@@ -1137,11 +1148,11 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
1137 if (reg % map->reg_stride) 1148 if (reg % map->reg_stride)
1138 return -EINVAL; 1149 return -EINVAL;
1139 1150
1140 map->lock(map); 1151 map->lock(map->lock_arg);
1141 1152
1142 ret = _regmap_read(map, reg, val); 1153 ret = _regmap_read(map, reg, val);
1143 1154
1144 map->unlock(map); 1155 map->unlock(map->lock_arg);
1145 1156
1146 return ret; 1157 return ret;
1147} 1158}
@@ -1171,7 +1182,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1171 if (reg % map->reg_stride) 1182 if (reg % map->reg_stride)
1172 return -EINVAL; 1183 return -EINVAL;
1173 1184
1174 map->lock(map); 1185 map->lock(map->lock_arg);
1175 1186
1176 if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || 1187 if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
1177 map->cache_type == REGCACHE_NONE) { 1188 map->cache_type == REGCACHE_NONE) {
@@ -1193,7 +1204,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1193 } 1204 }
1194 1205
1195 out: 1206 out:
1196 map->unlock(map); 1207 map->unlock(map->lock_arg);
1197 1208
1198 return ret; 1209 return ret;
1199} 1210}
@@ -1300,9 +1311,9 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
1300 bool change; 1311 bool change;
1301 int ret; 1312 int ret;
1302 1313
1303 map->lock(map); 1314 map->lock(map->lock_arg);
1304 ret = _regmap_update_bits(map, reg, mask, val, &change); 1315 ret = _regmap_update_bits(map, reg, mask, val, &change);
1305 map->unlock(map); 1316 map->unlock(map->lock_arg);
1306 1317
1307 return ret; 1318 return ret;
1308} 1319}
@@ -1326,9 +1337,9 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
1326{ 1337{
1327 int ret; 1338 int ret;
1328 1339
1329 map->lock(map); 1340 map->lock(map->lock_arg);
1330 ret = _regmap_update_bits(map, reg, mask, val, change); 1341 ret = _regmap_update_bits(map, reg, mask, val, change);
1331 map->unlock(map); 1342 map->unlock(map->lock_arg);
1332 return ret; 1343 return ret;
1333} 1344}
1334EXPORT_SYMBOL_GPL(regmap_update_bits_check); 1345EXPORT_SYMBOL_GPL(regmap_update_bits_check);
@@ -1357,7 +1368,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
1357 if (map->patch) 1368 if (map->patch)
1358 return -EBUSY; 1369 return -EBUSY;
1359 1370
1360 map->lock(map); 1371 map->lock(map->lock_arg);
1361 1372
1362 bypass = map->cache_bypass; 1373 bypass = map->cache_bypass;
1363 1374
@@ -1385,7 +1396,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
1385out: 1396out:
1386 map->cache_bypass = bypass; 1397 map->cache_bypass = bypass;
1387 1398
1388 map->unlock(map); 1399 map->unlock(map->lock_arg);
1389 1400
1390 return ret; 1401 return ret;
1391} 1402}