diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-02-14 12:11:09 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-02-14 12:11:09 -0500 |
commit | a2b37efc4e2aa76a5be29bbde8a2cd1c9c9066bc (patch) | |
tree | 0be4360b343ab037666d9b1d4ca326ef59e9615d /drivers/base/regmap/regmap.c | |
parent | a31f68497e07f5fec7155bc07dc633fc6eaa0adb (diff) | |
parent | d2a5884a64161b524cc6749ee11b95d252e497f3 (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.c | 58 |
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 | |||
624 | skip_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 | ||
1124 | static inline void *_regmap_map_get_context(struct regmap *map) | ||
1125 | { | ||
1126 | return (map->bus) ? map : map->bus_context; | ||
1127 | } | ||
1128 | |||
1108 | int _regmap_write(struct regmap *map, unsigned int reg, | 1129 | int _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, ®, range, | 1343 | ret = _regmap_select_page(map, ®, 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) |