aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/regmap/regmap.c')
-rw-r--r--drivers/base/regmap/regmap.c139
1 files changed, 103 insertions, 36 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7a3f535e481c..40f910162781 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -112,25 +112,36 @@ static void regmap_format_10_14_write(struct regmap *map,
112 out[0] = reg >> 2; 112 out[0] = reg >> 2;
113} 113}
114 114
115static void regmap_format_8(void *buf, unsigned int val) 115static void regmap_format_8(void *buf, unsigned int val, unsigned int shift)
116{ 116{
117 u8 *b = buf; 117 u8 *b = buf;
118 118
119 b[0] = val; 119 b[0] = val << shift;
120} 120}
121 121
122static void regmap_format_16(void *buf, unsigned int val) 122static void regmap_format_16(void *buf, unsigned int val, unsigned int shift)
123{ 123{
124 __be16 *b = buf; 124 __be16 *b = buf;
125 125
126 b[0] = cpu_to_be16(val); 126 b[0] = cpu_to_be16(val << shift);
127} 127}
128 128
129static void regmap_format_32(void *buf, unsigned int val) 129static void regmap_format_24(void *buf, unsigned int val, unsigned int shift)
130{
131 u8 *b = buf;
132
133 val <<= shift;
134
135 b[0] = val >> 16;
136 b[1] = val >> 8;
137 b[2] = val;
138}
139
140static void regmap_format_32(void *buf, unsigned int val, unsigned int shift)
130{ 141{
131 __be32 *b = buf; 142 __be32 *b = buf;
132 143
133 b[0] = cpu_to_be32(val); 144 b[0] = cpu_to_be32(val << shift);
134} 145}
135 146
136static unsigned int regmap_parse_8(void *buf) 147static unsigned int regmap_parse_8(void *buf)
@@ -149,6 +160,16 @@ static unsigned int regmap_parse_16(void *buf)
149 return b[0]; 160 return b[0];
150} 161}
151 162
163static unsigned int regmap_parse_24(void *buf)
164{
165 u8 *b = buf;
166 unsigned int ret = b[2];
167 ret |= ((unsigned int)b[1]) << 8;
168 ret |= ((unsigned int)b[0]) << 16;
169
170 return ret;
171}
172
152static unsigned int regmap_parse_32(void *buf) 173static unsigned int regmap_parse_32(void *buf)
153{ 174{
154 __be32 *b = buf; 175 __be32 *b = buf;
@@ -158,11 +179,32 @@ static unsigned int regmap_parse_32(void *buf)
158 return b[0]; 179 return b[0];
159} 180}
160 181
182static void regmap_lock_mutex(struct regmap *map)
183{
184 mutex_lock(&map->mutex);
185}
186
187static void regmap_unlock_mutex(struct regmap *map)
188{
189 mutex_unlock(&map->mutex);
190}
191
192static void regmap_lock_spinlock(struct regmap *map)
193{
194 spin_lock(&map->spinlock);
195}
196
197static void regmap_unlock_spinlock(struct regmap *map)
198{
199 spin_unlock(&map->spinlock);
200}
201
161/** 202/**
162 * regmap_init(): Initialise register map 203 * regmap_init(): Initialise register map
163 * 204 *
164 * @dev: Device that will be interacted with 205 * @dev: Device that will be interacted with
165 * @bus: Bus-specific callbacks to use with device 206 * @bus: Bus-specific callbacks to use with device
207 * @bus_context: Data passed to bus-specific callbacks
166 * @config: Configuration for register map 208 * @config: Configuration for register map
167 * 209 *
168 * The return value will be an ERR_PTR() on error or a valid pointer to 210 * The return value will be an ERR_PTR() on error or a valid pointer to
@@ -171,6 +213,7 @@ static unsigned int regmap_parse_32(void *buf)
171 */ 213 */
172struct regmap *regmap_init(struct device *dev, 214struct regmap *regmap_init(struct device *dev,
173 const struct regmap_bus *bus, 215 const struct regmap_bus *bus,
216 void *bus_context,
174 const struct regmap_config *config) 217 const struct regmap_config *config)
175{ 218{
176 struct regmap *map; 219 struct regmap *map;
@@ -185,14 +228,24 @@ struct regmap *regmap_init(struct device *dev,
185 goto err; 228 goto err;
186 } 229 }
187 230
188 mutex_init(&map->lock); 231 if (bus->fast_io) {
232 spin_lock_init(&map->spinlock);
233 map->lock = regmap_lock_spinlock;
234 map->unlock = regmap_unlock_spinlock;
235 } else {
236 mutex_init(&map->mutex);
237 map->lock = regmap_lock_mutex;
238 map->unlock = regmap_unlock_mutex;
239 }
189 map->format.buf_size = (config->reg_bits + config->val_bits) / 8; 240 map->format.buf_size = (config->reg_bits + config->val_bits) / 8;
190 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); 241 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
191 map->format.pad_bytes = config->pad_bits / 8; 242 map->format.pad_bytes = config->pad_bits / 8;
192 map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); 243 map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
193 map->format.buf_size += map->format.pad_bytes; 244 map->format.buf_size += map->format.pad_bytes;
245 map->reg_shift = config->pad_bits % 8;
194 map->dev = dev; 246 map->dev = dev;
195 map->bus = bus; 247 map->bus = bus;
248 map->bus_context = bus_context;
196 map->max_register = config->max_register; 249 map->max_register = config->max_register;
197 map->writeable_reg = config->writeable_reg; 250 map->writeable_reg = config->writeable_reg;
198 map->readable_reg = config->readable_reg; 251 map->readable_reg = config->readable_reg;
@@ -207,7 +260,7 @@ struct regmap *regmap_init(struct device *dev,
207 map->read_flag_mask = bus->read_flag_mask; 260 map->read_flag_mask = bus->read_flag_mask;
208 } 261 }
209 262
210 switch (config->reg_bits) { 263 switch (config->reg_bits + map->reg_shift) {
211 case 2: 264 case 2:
212 switch (config->val_bits) { 265 switch (config->val_bits) {
213 case 6: 266 case 6:
@@ -273,6 +326,10 @@ struct regmap *regmap_init(struct device *dev,
273 map->format.format_val = regmap_format_16; 326 map->format.format_val = regmap_format_16;
274 map->format.parse_val = regmap_parse_16; 327 map->format.parse_val = regmap_parse_16;
275 break; 328 break;
329 case 24:
330 map->format.format_val = regmap_format_24;
331 map->format.parse_val = regmap_parse_24;
332 break;
276 case 32: 333 case 32:
277 map->format.format_val = regmap_format_32; 334 map->format.format_val = regmap_format_32;
278 map->format.parse_val = regmap_parse_32; 335 map->format.parse_val = regmap_parse_32;
@@ -289,7 +346,7 @@ struct regmap *regmap_init(struct device *dev,
289 goto err_map; 346 goto err_map;
290 } 347 }
291 348
292 regmap_debugfs_init(map); 349 regmap_debugfs_init(map, config->name);
293 350
294 ret = regcache_init(map, config); 351 ret = regcache_init(map, config);
295 if (ret < 0) 352 if (ret < 0)
@@ -316,6 +373,7 @@ static void devm_regmap_release(struct device *dev, void *res)
316 * 373 *
317 * @dev: Device that will be interacted with 374 * @dev: Device that will be interacted with
318 * @bus: Bus-specific callbacks to use with device 375 * @bus: Bus-specific callbacks to use with device
376 * @bus_context: Data passed to bus-specific callbacks
319 * @config: Configuration for register map 377 * @config: Configuration for register map
320 * 378 *
321 * The return value will be an ERR_PTR() on error or a valid pointer 379 * The return value will be an ERR_PTR() on error or a valid pointer
@@ -325,6 +383,7 @@ static void devm_regmap_release(struct device *dev, void *res)
325 */ 383 */
326struct regmap *devm_regmap_init(struct device *dev, 384struct regmap *devm_regmap_init(struct device *dev,
327 const struct regmap_bus *bus, 385 const struct regmap_bus *bus,
386 void *bus_context,
328 const struct regmap_config *config) 387 const struct regmap_config *config)
329{ 388{
330 struct regmap **ptr, *regmap; 389 struct regmap **ptr, *regmap;
@@ -333,7 +392,7 @@ struct regmap *devm_regmap_init(struct device *dev,
333 if (!ptr) 392 if (!ptr)
334 return ERR_PTR(-ENOMEM); 393 return ERR_PTR(-ENOMEM);
335 394
336 regmap = regmap_init(dev, bus, config); 395 regmap = regmap_init(dev, bus, bus_context, config);
337 if (!IS_ERR(regmap)) { 396 if (!IS_ERR(regmap)) {
338 *ptr = regmap; 397 *ptr = regmap;
339 devres_add(dev, ptr); 398 devres_add(dev, ptr);
@@ -360,7 +419,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
360{ 419{
361 int ret; 420 int ret;
362 421
363 mutex_lock(&map->lock); 422 map->lock(map);
364 423
365 regcache_exit(map); 424 regcache_exit(map);
366 regmap_debugfs_exit(map); 425 regmap_debugfs_exit(map);
@@ -372,14 +431,14 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
372 map->precious_reg = config->precious_reg; 431 map->precious_reg = config->precious_reg;
373 map->cache_type = config->cache_type; 432 map->cache_type = config->cache_type;
374 433
375 regmap_debugfs_init(map); 434 regmap_debugfs_init(map, config->name);
376 435
377 map->cache_bypass = false; 436 map->cache_bypass = false;
378 map->cache_only = false; 437 map->cache_only = false;
379 438
380 ret = regcache_init(map, config); 439 ret = regcache_init(map, config);
381 440
382 mutex_unlock(&map->lock); 441 map->unlock(map);
383 442
384 return ret; 443 return ret;
385} 444}
@@ -391,6 +450,8 @@ void regmap_exit(struct regmap *map)
391{ 450{
392 regcache_exit(map); 451 regcache_exit(map);
393 regmap_debugfs_exit(map); 452 regmap_debugfs_exit(map);
453 if (map->bus->free_context)
454 map->bus->free_context(map->bus_context);
394 kfree(map->work_buf); 455 kfree(map->work_buf);
395 kfree(map); 456 kfree(map);
396} 457}
@@ -431,7 +492,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
431 } 492 }
432 } 493 }
433 494
434 map->format.format_reg(map->work_buf, reg); 495 map->format.format_reg(map->work_buf, reg, map->reg_shift);
435 496
436 u8[0] |= map->write_flag_mask; 497 u8[0] |= map->write_flag_mask;
437 498
@@ -444,12 +505,12 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
444 */ 505 */
445 if (val == (map->work_buf + map->format.pad_bytes + 506 if (val == (map->work_buf + map->format.pad_bytes +
446 map->format.reg_bytes)) 507 map->format.reg_bytes))
447 ret = map->bus->write(map->dev, map->work_buf, 508 ret = map->bus->write(map->bus_context, map->work_buf,
448 map->format.reg_bytes + 509 map->format.reg_bytes +
449 map->format.pad_bytes + 510 map->format.pad_bytes +
450 val_len); 511 val_len);
451 else if (map->bus->gather_write) 512 else if (map->bus->gather_write)
452 ret = map->bus->gather_write(map->dev, map->work_buf, 513 ret = map->bus->gather_write(map->bus_context, map->work_buf,
453 map->format.reg_bytes + 514 map->format.reg_bytes +
454 map->format.pad_bytes, 515 map->format.pad_bytes,
455 val, val_len); 516 val, val_len);
@@ -464,7 +525,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
464 memcpy(buf, map->work_buf, map->format.reg_bytes); 525 memcpy(buf, map->work_buf, map->format.reg_bytes);
465 memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, 526 memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
466 val, val_len); 527 val, val_len);
467 ret = map->bus->write(map->dev, buf, len); 528 ret = map->bus->write(map->bus_context, buf, len);
468 529
469 kfree(buf); 530 kfree(buf);
470 } 531 }
@@ -498,7 +559,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
498 559
499 trace_regmap_hw_write_start(map->dev, reg, 1); 560 trace_regmap_hw_write_start(map->dev, reg, 1);
500 561
501 ret = map->bus->write(map->dev, map->work_buf, 562 ret = map->bus->write(map->bus_context, map->work_buf,
502 map->format.buf_size); 563 map->format.buf_size);
503 564
504 trace_regmap_hw_write_done(map->dev, reg, 1); 565 trace_regmap_hw_write_done(map->dev, reg, 1);
@@ -506,7 +567,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
506 return ret; 567 return ret;
507 } else { 568 } else {
508 map->format.format_val(map->work_buf + map->format.reg_bytes 569 map->format.format_val(map->work_buf + map->format.reg_bytes
509 + map->format.pad_bytes, val); 570 + map->format.pad_bytes, val, 0);
510 return _regmap_raw_write(map, reg, 571 return _regmap_raw_write(map, reg,
511 map->work_buf + 572 map->work_buf +
512 map->format.reg_bytes + 573 map->format.reg_bytes +
@@ -529,11 +590,11 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
529{ 590{
530 int ret; 591 int ret;
531 592
532 mutex_lock(&map->lock); 593 map->lock(map);
533 594
534 ret = _regmap_write(map, reg, val); 595 ret = _regmap_write(map, reg, val);
535 596
536 mutex_unlock(&map->lock); 597 map->unlock(map);
537 598
538 return ret; 599 return ret;
539} 600}
@@ -560,11 +621,14 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
560{ 621{
561 int ret; 622 int ret;
562 623
563 mutex_lock(&map->lock); 624 if (val_len % map->format.val_bytes)
625 return -EINVAL;
626
627 map->lock(map);
564 628
565 ret = _regmap_raw_write(map, reg, val, val_len); 629 ret = _regmap_raw_write(map, reg, val, val_len);
566 630
567 mutex_unlock(&map->lock); 631 map->unlock(map);
568 632
569 return ret; 633 return ret;
570} 634}
@@ -594,7 +658,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
594 if (!map->format.parse_val) 658 if (!map->format.parse_val)
595 return -EINVAL; 659 return -EINVAL;
596 660
597 mutex_lock(&map->lock); 661 map->lock(map);
598 662
599 /* No formatting is require if val_byte is 1 */ 663 /* No formatting is require if val_byte is 1 */
600 if (val_bytes == 1) { 664 if (val_bytes == 1) {
@@ -615,7 +679,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
615 kfree(wval); 679 kfree(wval);
616 680
617out: 681out:
618 mutex_unlock(&map->lock); 682 map->unlock(map);
619 return ret; 683 return ret;
620} 684}
621EXPORT_SYMBOL_GPL(regmap_bulk_write); 685EXPORT_SYMBOL_GPL(regmap_bulk_write);
@@ -626,7 +690,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
626 u8 *u8 = map->work_buf; 690 u8 *u8 = map->work_buf;
627 int ret; 691 int ret;
628 692
629 map->format.format_reg(map->work_buf, reg); 693 map->format.format_reg(map->work_buf, reg, map->reg_shift);
630 694
631 /* 695 /*
632 * Some buses or devices flag reads by setting the high bits in the 696 * Some buses or devices flag reads by setting the high bits in the
@@ -639,7 +703,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
639 trace_regmap_hw_read_start(map->dev, reg, 703 trace_regmap_hw_read_start(map->dev, reg,
640 val_len / map->format.val_bytes); 704 val_len / map->format.val_bytes);
641 705
642 ret = map->bus->read(map->dev, map->work_buf, 706 ret = map->bus->read(map->bus_context, map->work_buf,
643 map->format.reg_bytes + map->format.pad_bytes, 707 map->format.reg_bytes + map->format.pad_bytes,
644 val, val_len); 708 val, val_len);
645 709
@@ -689,11 +753,11 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
689{ 753{
690 int ret; 754 int ret;
691 755
692 mutex_lock(&map->lock); 756 map->lock(map);
693 757
694 ret = _regmap_read(map, reg, val); 758 ret = _regmap_read(map, reg, val);
695 759
696 mutex_unlock(&map->lock); 760 map->unlock(map);
697 761
698 return ret; 762 return ret;
699} 763}
@@ -718,7 +782,10 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
718 unsigned int v; 782 unsigned int v;
719 int ret, i; 783 int ret, i;
720 784
721 mutex_lock(&map->lock); 785 if (val_len % map->format.val_bytes)
786 return -EINVAL;
787
788 map->lock(map);
722 789
723 if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || 790 if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
724 map->cache_type == REGCACHE_NONE) { 791 map->cache_type == REGCACHE_NONE) {
@@ -734,12 +801,12 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
734 if (ret != 0) 801 if (ret != 0)
735 goto out; 802 goto out;
736 803
737 map->format.format_val(val + (i * val_bytes), v); 804 map->format.format_val(val + (i * val_bytes), v, 0);
738 } 805 }
739 } 806 }
740 807
741 out: 808 out:
742 mutex_unlock(&map->lock); 809 map->unlock(map);
743 810
744 return ret; 811 return ret;
745} 812}
@@ -792,7 +859,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
792 int ret; 859 int ret;
793 unsigned int tmp, orig; 860 unsigned int tmp, orig;
794 861
795 mutex_lock(&map->lock); 862 map->lock(map);
796 863
797 ret = _regmap_read(map, reg, &orig); 864 ret = _regmap_read(map, reg, &orig);
798 if (ret != 0) 865 if (ret != 0)
@@ -809,7 +876,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
809 } 876 }
810 877
811out: 878out:
812 mutex_unlock(&map->lock); 879 map->unlock(map);
813 880
814 return ret; 881 return ret;
815} 882}
@@ -876,7 +943,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
876 if (map->patch) 943 if (map->patch)
877 return -EBUSY; 944 return -EBUSY;
878 945
879 mutex_lock(&map->lock); 946 map->lock(map);
880 947
881 bypass = map->cache_bypass; 948 bypass = map->cache_bypass;
882 949
@@ -904,7 +971,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
904out: 971out:
905 map->cache_bypass = bypass; 972 map->cache_bypass = bypass;
906 973
907 mutex_unlock(&map->lock); 974 map->unlock(map);
908 975
909 return ret; 976 return ret;
910} 977}