diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-11-20 21:09:46 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-11-20 21:09:46 -0500 |
commit | 3afa24f7ad0a1ab5478f1e9a6c4df1acf52171d1 (patch) | |
tree | d8a4bebef173659a9f1605fec1c7eab06a016583 /drivers/base/regmap | |
parent | 869e4a5f5848f6308cc5651d4bdc3e545d676b98 (diff) | |
parent | 0d4529c534c1c664f25088eb5f5b4d7ce0ee2510 (diff) |
Merge branch 'topic/lock' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into regmap-table
Diffstat (limited to 'drivers/base/regmap')
-rw-r--r-- | drivers/base/regmap/internal.h | 4 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 65 |
2 files changed, 39 insertions, 30 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index ac869d28d5ba..2cd01b57b1c4 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 | ||
34 | typedef void (*regmap_lock)(struct regmap *map); | ||
35 | typedef void (*regmap_unlock)(struct regmap *map); | ||
36 | |||
37 | struct regmap { | 34 | struct 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 c7465f19f674..64eb8350a074 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 | ||
217 | static void regmap_lock_mutex(struct regmap *map) | 217 | static 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 | ||
222 | static void regmap_unlock_mutex(struct regmap *map) | 223 | static 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 | ||
227 | static void regmap_lock_spinlock(struct regmap *map) | 229 | static 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 | ||
232 | static void regmap_unlock_spinlock(struct regmap *map) | 235 | static 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; |
@@ -994,11 +1005,11 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val) | |||
994 | if (reg % map->reg_stride) | 1005 | if (reg % map->reg_stride) |
995 | return -EINVAL; | 1006 | return -EINVAL; |
996 | 1007 | ||
997 | map->lock(map); | 1008 | map->lock(map->lock_arg); |
998 | 1009 | ||
999 | ret = _regmap_write(map, reg, val); | 1010 | ret = _regmap_write(map, reg, val); |
1000 | 1011 | ||
1001 | map->unlock(map); | 1012 | map->unlock(map->lock_arg); |
1002 | 1013 | ||
1003 | return ret; | 1014 | return ret; |
1004 | } | 1015 | } |
@@ -1030,11 +1041,11 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, | |||
1030 | if (reg % map->reg_stride) | 1041 | if (reg % map->reg_stride) |
1031 | return -EINVAL; | 1042 | return -EINVAL; |
1032 | 1043 | ||
1033 | map->lock(map); | 1044 | map->lock(map->lock_arg); |
1034 | 1045 | ||
1035 | ret = _regmap_raw_write(map, reg, val, val_len); | 1046 | ret = _regmap_raw_write(map, reg, val, val_len); |
1036 | 1047 | ||
1037 | map->unlock(map); | 1048 | map->unlock(map->lock_arg); |
1038 | 1049 | ||
1039 | return ret; | 1050 | return ret; |
1040 | } | 1051 | } |
@@ -1066,7 +1077,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, | |||
1066 | if (reg % map->reg_stride) | 1077 | if (reg % map->reg_stride) |
1067 | return -EINVAL; | 1078 | return -EINVAL; |
1068 | 1079 | ||
1069 | map->lock(map); | 1080 | map->lock(map->lock_arg); |
1070 | 1081 | ||
1071 | /* No formatting is require if val_byte is 1 */ | 1082 | /* No formatting is require if val_byte is 1 */ |
1072 | if (val_bytes == 1) { | 1083 | if (val_bytes == 1) { |
@@ -1102,7 +1113,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, | |||
1102 | kfree(wval); | 1113 | kfree(wval); |
1103 | 1114 | ||
1104 | out: | 1115 | out: |
1105 | map->unlock(map); | 1116 | map->unlock(map->lock_arg); |
1106 | return ret; | 1117 | return ret; |
1107 | } | 1118 | } |
1108 | EXPORT_SYMBOL_GPL(regmap_bulk_write); | 1119 | EXPORT_SYMBOL_GPL(regmap_bulk_write); |
@@ -1197,11 +1208,11 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) | |||
1197 | if (reg % map->reg_stride) | 1208 | if (reg % map->reg_stride) |
1198 | return -EINVAL; | 1209 | return -EINVAL; |
1199 | 1210 | ||
1200 | map->lock(map); | 1211 | map->lock(map->lock_arg); |
1201 | 1212 | ||
1202 | ret = _regmap_read(map, reg, val); | 1213 | ret = _regmap_read(map, reg, val); |
1203 | 1214 | ||
1204 | map->unlock(map); | 1215 | map->unlock(map->lock_arg); |
1205 | 1216 | ||
1206 | return ret; | 1217 | return ret; |
1207 | } | 1218 | } |
@@ -1231,7 +1242,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
1231 | if (reg % map->reg_stride) | 1242 | if (reg % map->reg_stride) |
1232 | return -EINVAL; | 1243 | return -EINVAL; |
1233 | 1244 | ||
1234 | map->lock(map); | 1245 | map->lock(map->lock_arg); |
1235 | 1246 | ||
1236 | if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || | 1247 | if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || |
1237 | map->cache_type == REGCACHE_NONE) { | 1248 | map->cache_type == REGCACHE_NONE) { |
@@ -1253,7 +1264,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
1253 | } | 1264 | } |
1254 | 1265 | ||
1255 | out: | 1266 | out: |
1256 | map->unlock(map); | 1267 | map->unlock(map->lock_arg); |
1257 | 1268 | ||
1258 | return ret; | 1269 | return ret; |
1259 | } | 1270 | } |
@@ -1360,9 +1371,9 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, | |||
1360 | bool change; | 1371 | bool change; |
1361 | int ret; | 1372 | int ret; |
1362 | 1373 | ||
1363 | map->lock(map); | 1374 | map->lock(map->lock_arg); |
1364 | ret = _regmap_update_bits(map, reg, mask, val, &change); | 1375 | ret = _regmap_update_bits(map, reg, mask, val, &change); |
1365 | map->unlock(map); | 1376 | map->unlock(map->lock_arg); |
1366 | 1377 | ||
1367 | return ret; | 1378 | return ret; |
1368 | } | 1379 | } |
@@ -1386,9 +1397,9 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, | |||
1386 | { | 1397 | { |
1387 | int ret; | 1398 | int ret; |
1388 | 1399 | ||
1389 | map->lock(map); | 1400 | map->lock(map->lock_arg); |
1390 | ret = _regmap_update_bits(map, reg, mask, val, change); | 1401 | ret = _regmap_update_bits(map, reg, mask, val, change); |
1391 | map->unlock(map); | 1402 | map->unlock(map->lock_arg); |
1392 | return ret; | 1403 | return ret; |
1393 | } | 1404 | } |
1394 | EXPORT_SYMBOL_GPL(regmap_update_bits_check); | 1405 | EXPORT_SYMBOL_GPL(regmap_update_bits_check); |
@@ -1417,7 +1428,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, | |||
1417 | if (map->patch) | 1428 | if (map->patch) |
1418 | return -EBUSY; | 1429 | return -EBUSY; |
1419 | 1430 | ||
1420 | map->lock(map); | 1431 | map->lock(map->lock_arg); |
1421 | 1432 | ||
1422 | bypass = map->cache_bypass; | 1433 | bypass = map->cache_bypass; |
1423 | 1434 | ||
@@ -1445,7 +1456,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, | |||
1445 | out: | 1456 | out: |
1446 | map->cache_bypass = bypass; | 1457 | map->cache_bypass = bypass; |
1447 | 1458 | ||
1448 | map->unlock(map); | 1459 | map->unlock(map->lock_arg); |
1449 | 1460 | ||
1450 | return ret; | 1461 | return ret; |
1451 | } | 1462 | } |