aboutsummaryrefslogtreecommitdiffstats
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
parenta31f68497e07f5fec7155bc07dc633fc6eaa0adb (diff)
parentd2a5884a64161b524cc6749ee11b95d252e497f3 (diff)
Merge remote-tracking branch 'regmap/topic/no-bus' into regmap-next
-rw-r--r--drivers/base/regmap/internal.h2
-rw-r--r--drivers/base/regmap/regmap.c58
-rw-r--r--include/linux/regmap.h18
3 files changed, 65 insertions, 13 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 70ca270b77e2..5a22bd33ce3d 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -91,6 +91,8 @@ struct regmap {
91 int (*reg_read)(void *context, unsigned int reg, unsigned int *val); 91 int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
92 int (*reg_write)(void *context, unsigned int reg, unsigned int val); 92 int (*reg_write)(void *context, unsigned int reg, unsigned int val);
93 93
94 bool defer_caching;
95
94 u8 read_flag_mask; 96 u8 read_flag_mask;
95 u8 write_flag_mask; 97 u8 write_flag_mask;
96 98
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)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 017b3bd085a2..bf77dfdabef9 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -128,7 +128,18 @@ typedef void (*regmap_unlock)(void *);
128 * @lock_arg: this field is passed as the only argument of lock/unlock 128 * @lock_arg: this field is passed as the only argument of lock/unlock
129 * functions (ignored in case regular lock/unlock functions 129 * functions (ignored in case regular lock/unlock functions
130 * are not overridden). 130 * are not overridden).
131 * 131 * @reg_read: Optional callback that if filled will be used to perform
132 * all the reads from the registers. Should only be provided for
133 * devices whos read operation cannot be represented as a simple read
134 * operation on a bus such as SPI, I2C, etc. Most of the devices do
135 * not need this.
136 * @reg_write: Same as above for writing.
137 * @fast_io: Register IO is fast. Use a spinlock instead of a mutex
138 * to perform locking. This field is ignored if custom lock/unlock
139 * functions are used (see fields lock/unlock of struct regmap_config).
140 * This field is a duplicate of a similar file in
141 * 'struct regmap_bus' and serves exact same purpose.
142 * Use it only for "no-bus" cases.
132 * @max_register: Optional, specifies the maximum valid register index. 143 * @max_register: Optional, specifies the maximum valid register index.
133 * @wr_table: Optional, points to a struct regmap_access_table specifying 144 * @wr_table: Optional, points to a struct regmap_access_table specifying
134 * valid ranges for write access. 145 * valid ranges for write access.
@@ -178,6 +189,11 @@ struct regmap_config {
178 regmap_unlock unlock; 189 regmap_unlock unlock;
179 void *lock_arg; 190 void *lock_arg;
180 191
192 int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
193 int (*reg_write)(void *context, unsigned int reg, unsigned int val);
194
195 bool fast_io;
196
181 unsigned int max_register; 197 unsigned int max_register;
182 const struct regmap_access_table *wr_table; 198 const struct regmap_access_table *wr_table;
183 const struct regmap_access_table *rd_table; 199 const struct regmap_access_table *rd_table;