aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regmap.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-14 12:11:09 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-14 12:11:09 -0500
commita2b37efc4e2aa76a5be29bbde8a2cd1c9c9066bc (patch)
tree0be4360b343ab037666d9b1d4ca326ef59e9615d /drivers/base/regmap/regmap.c
parenta31f68497e07f5fec7155bc07dc633fc6eaa0adb (diff)
parentd2a5884a64161b524cc6749ee11b95d252e497f3 (diff)
Merge remote-tracking branch 'regmap/topic/no-bus' into regmap-next
Diffstat (limited to 'drivers/base/regmap/regmap.c')
-rw-r--r--drivers/base/regmap/regmap.c58
1 files changed, 46 insertions, 12 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index b1d962434cb2..3d2367501fd0 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -389,7 +389,7 @@ struct regmap *regmap_init(struct device *dev,
389 enum regmap_endian reg_endian, val_endian; 389 enum regmap_endian reg_endian, val_endian;
390 int i, j; 390 int i, j;
391 391
392 if (!bus || !config) 392 if (!config)
393 goto err; 393 goto err;
394 394
395 map = kzalloc(sizeof(*map), GFP_KERNEL); 395 map = kzalloc(sizeof(*map), GFP_KERNEL);
@@ -403,7 +403,8 @@ struct regmap *regmap_init(struct device *dev,
403 map->unlock = config->unlock; 403 map->unlock = config->unlock;
404 map->lock_arg = config->lock_arg; 404 map->lock_arg = config->lock_arg;
405 } else { 405 } else {
406 if (bus->fast_io) { 406 if ((bus && bus->fast_io) ||
407 config->fast_io) {
407 spin_lock_init(&map->spinlock); 408 spin_lock_init(&map->spinlock);
408 map->lock = regmap_lock_spinlock; 409 map->lock = regmap_lock_spinlock;
409 map->unlock = regmap_unlock_spinlock; 410 map->unlock = regmap_unlock_spinlock;
@@ -447,11 +448,19 @@ struct regmap *regmap_init(struct device *dev,
447 if (config->read_flag_mask || config->write_flag_mask) { 448 if (config->read_flag_mask || config->write_flag_mask) {
448 map->read_flag_mask = config->read_flag_mask; 449 map->read_flag_mask = config->read_flag_mask;
449 map->write_flag_mask = config->write_flag_mask; 450 map->write_flag_mask = config->write_flag_mask;
450 } else { 451 } else if (bus) {
451 map->read_flag_mask = bus->read_flag_mask; 452 map->read_flag_mask = bus->read_flag_mask;
452 } 453 }
453 454
454 map->reg_read = _regmap_bus_read; 455 if (!bus) {
456 map->reg_read = config->reg_read;
457 map->reg_write = config->reg_write;
458
459 map->defer_caching = false;
460 goto skip_format_initialization;
461 } else {
462 map->reg_read = _regmap_bus_read;
463 }
455 464
456 reg_endian = config->reg_format_endian; 465 reg_endian = config->reg_format_endian;
457 if (reg_endian == REGMAP_ENDIAN_DEFAULT) 466 if (reg_endian == REGMAP_ENDIAN_DEFAULT)
@@ -604,10 +613,15 @@ struct regmap *regmap_init(struct device *dev,
604 goto err_map; 613 goto err_map;
605 } 614 }
606 615
607 if (map->format.format_write) 616 if (map->format.format_write) {
617 map->defer_caching = false;
608 map->reg_write = _regmap_bus_formatted_write; 618 map->reg_write = _regmap_bus_formatted_write;
609 else if (map->format.format_val) 619 } else if (map->format.format_val) {
620 map->defer_caching = true;
610 map->reg_write = _regmap_bus_raw_write; 621 map->reg_write = _regmap_bus_raw_write;
622 }
623
624skip_format_initialization:
611 625
612 map->range_tree = RB_ROOT; 626 map->range_tree = RB_ROOT;
613 for (i = 0; i < config->num_ranges; i++) { 627 for (i = 0; i < config->num_ranges; i++) {
@@ -810,7 +824,7 @@ void regmap_exit(struct regmap *map)
810 regcache_exit(map); 824 regcache_exit(map);
811 regmap_debugfs_exit(map); 825 regmap_debugfs_exit(map);
812 regmap_range_exit(map); 826 regmap_range_exit(map);
813 if (map->bus->free_context) 827 if (map->bus && map->bus->free_context)
814 map->bus->free_context(map->bus_context); 828 map->bus->free_context(map->bus_context);
815 kfree(map->work_buf); 829 kfree(map->work_buf);
816 kfree(map); 830 kfree(map);
@@ -916,6 +930,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
916 size_t len; 930 size_t len;
917 int i; 931 int i;
918 932
933 BUG_ON(!map->bus);
934
919 /* Check for unwritable registers before we start */ 935 /* Check for unwritable registers before we start */
920 if (map->writeable_reg) 936 if (map->writeable_reg)
921 for (i = 0; i < val_len / map->format.val_bytes; i++) 937 for (i = 0; i < val_len / map->format.val_bytes; i++)
@@ -1068,7 +1084,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
1068 struct regmap_range_node *range; 1084 struct regmap_range_node *range;
1069 struct regmap *map = context; 1085 struct regmap *map = context;
1070 1086
1071 BUG_ON(!map->format.format_write); 1087 BUG_ON(!map->bus || !map->format.format_write);
1072 1088
1073 range = _regmap_range_lookup(map, reg); 1089 range = _regmap_range_lookup(map, reg);
1074 if (range) { 1090 if (range) {
@@ -1094,7 +1110,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
1094{ 1110{
1095 struct regmap *map = context; 1111 struct regmap *map = context;
1096 1112
1097 BUG_ON(!map->format.format_val); 1113 BUG_ON(!map->bus || !map->format.format_val);
1098 1114
1099 map->format.format_val(map->work_buf + map->format.reg_bytes 1115 map->format.format_val(map->work_buf + map->format.reg_bytes
1100 + map->format.pad_bytes, val, 0); 1116 + map->format.pad_bytes, val, 0);
@@ -1105,12 +1121,18 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
1105 map->format.val_bytes, false); 1121 map->format.val_bytes, false);
1106} 1122}
1107 1123
1124static inline void *_regmap_map_get_context(struct regmap *map)
1125{
1126 return (map->bus) ? map : map->bus_context;
1127}
1128
1108int _regmap_write(struct regmap *map, unsigned int reg, 1129int _regmap_write(struct regmap *map, unsigned int reg,
1109 unsigned int val) 1130 unsigned int val)
1110{ 1131{
1111 int ret; 1132 int ret;
1133 void *context = _regmap_map_get_context(map);
1112 1134
1113 if (!map->cache_bypass && map->format.format_write) { 1135 if (!map->cache_bypass && !map->defer_caching) {
1114 ret = regcache_write(map, reg, val); 1136 ret = regcache_write(map, reg, val);
1115 if (ret != 0) 1137 if (ret != 0)
1116 return ret; 1138 return ret;
@@ -1127,7 +1149,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
1127 1149
1128 trace_regmap_reg_write(map->dev, reg, val); 1150 trace_regmap_reg_write(map->dev, reg, val);
1129 1151
1130 return map->reg_write(map, reg, val); 1152 return map->reg_write(context, reg, val);
1131} 1153}
1132 1154
1133/** 1155/**
@@ -1178,6 +1200,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
1178{ 1200{
1179 int ret; 1201 int ret;
1180 1202
1203 if (!map->bus)
1204 return -EINVAL;
1181 if (val_len % map->format.val_bytes) 1205 if (val_len % map->format.val_bytes)
1182 return -EINVAL; 1206 return -EINVAL;
1183 if (reg % map->reg_stride) 1207 if (reg % map->reg_stride)
@@ -1214,6 +1238,8 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1214 size_t val_bytes = map->format.val_bytes; 1238 size_t val_bytes = map->format.val_bytes;
1215 void *wval; 1239 void *wval;
1216 1240
1241 if (!map->bus)
1242 return -EINVAL;
1217 if (!map->format.parse_val) 1243 if (!map->format.parse_val)
1218 return -EINVAL; 1244 return -EINVAL;
1219 if (reg % map->reg_stride) 1245 if (reg % map->reg_stride)
@@ -1310,6 +1336,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1310 u8 *u8 = map->work_buf; 1336 u8 *u8 = map->work_buf;
1311 int ret; 1337 int ret;
1312 1338
1339 BUG_ON(!map->bus);
1340
1313 range = _regmap_range_lookup(map, reg); 1341 range = _regmap_range_lookup(map, reg);
1314 if (range) { 1342 if (range) {
1315 ret = _regmap_select_page(map, &reg, range, 1343 ret = _regmap_select_page(map, &reg, range,
@@ -1361,6 +1389,8 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
1361 unsigned int *val) 1389 unsigned int *val)
1362{ 1390{
1363 int ret; 1391 int ret;
1392 void *context = _regmap_map_get_context(map);
1393
1364 BUG_ON(!map->reg_read); 1394 BUG_ON(!map->reg_read);
1365 1395
1366 if (!map->cache_bypass) { 1396 if (!map->cache_bypass) {
@@ -1372,7 +1402,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
1372 if (map->cache_only) 1402 if (map->cache_only)
1373 return -EBUSY; 1403 return -EBUSY;
1374 1404
1375 ret = map->reg_read(map, reg, val); 1405 ret = map->reg_read(context, reg, val);
1376 if (ret == 0) { 1406 if (ret == 0) {
1377#ifdef LOG_DEVICE 1407#ifdef LOG_DEVICE
1378 if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) 1408 if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
@@ -1434,6 +1464,8 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1434 unsigned int v; 1464 unsigned int v;
1435 int ret, i; 1465 int ret, i;
1436 1466
1467 if (!map->bus)
1468 return -EINVAL;
1437 if (val_len % map->format.val_bytes) 1469 if (val_len % map->format.val_bytes)
1438 return -EINVAL; 1470 return -EINVAL;
1439 if (reg % map->reg_stride) 1471 if (reg % map->reg_stride)
@@ -1485,6 +1517,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
1485 size_t val_bytes = map->format.val_bytes; 1517 size_t val_bytes = map->format.val_bytes;
1486 bool vol = regmap_volatile_range(map, reg, val_count); 1518 bool vol = regmap_volatile_range(map, reg, val_count);
1487 1519
1520 if (!map->bus)
1521 return -EINVAL;
1488 if (!map->format.parse_val) 1522 if (!map->format.parse_val)
1489 return -EINVAL; 1523 return -EINVAL;
1490 if (reg % map->reg_stride) 1524 if (reg % map->reg_stride)