diff options
author | Mark Brown <broonie@kernel.org> | 2015-07-10 06:39:23 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-07-10 06:39:23 -0400 |
commit | d1b080290f86d134b97bfe63e499ab9ed3935a02 (patch) | |
tree | 876c01fc58578c00968edbe057b1db2edb8c80ad | |
parent | d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754 (diff) | |
parent | e874e6c7edc43436f73cf84157d9221f8b807c36 (diff) |
Merge tag 'regmap-force' into asoc-rcar
regmap: Force write support
This allows users to use _update_bits() without the write suppression,
useful for some hardware.
-rw-r--r-- | drivers/base/regmap/regmap.c | 51 | ||||
-rw-r--r-- | include/linux/regmap.h | 11 |
2 files changed, 54 insertions, 8 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 7111d04f2621..dd63bcbbf8a5 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | static int _regmap_update_bits(struct regmap *map, unsigned int reg, | 35 | static int _regmap_update_bits(struct regmap *map, unsigned int reg, |
36 | unsigned int mask, unsigned int val, | 36 | unsigned int mask, unsigned int val, |
37 | bool *change); | 37 | bool *change, bool force_write); |
38 | 38 | ||
39 | static int _regmap_bus_reg_read(void *context, unsigned int reg, | 39 | static int _regmap_bus_reg_read(void *context, unsigned int reg, |
40 | unsigned int *val); | 40 | unsigned int *val); |
@@ -1178,7 +1178,7 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg, | |||
1178 | ret = _regmap_update_bits(map, range->selector_reg, | 1178 | ret = _regmap_update_bits(map, range->selector_reg, |
1179 | range->selector_mask, | 1179 | range->selector_mask, |
1180 | win_page << range->selector_shift, | 1180 | win_page << range->selector_shift, |
1181 | &page_chg); | 1181 | &page_chg, false); |
1182 | 1182 | ||
1183 | map->work_buf = orig_work_buf; | 1183 | map->work_buf = orig_work_buf; |
1184 | 1184 | ||
@@ -1624,6 +1624,18 @@ int regmap_fields_write(struct regmap_field *field, unsigned int id, | |||
1624 | } | 1624 | } |
1625 | EXPORT_SYMBOL_GPL(regmap_fields_write); | 1625 | EXPORT_SYMBOL_GPL(regmap_fields_write); |
1626 | 1626 | ||
1627 | int regmap_fields_force_write(struct regmap_field *field, unsigned int id, | ||
1628 | unsigned int val) | ||
1629 | { | ||
1630 | if (id >= field->id_size) | ||
1631 | return -EINVAL; | ||
1632 | |||
1633 | return regmap_write_bits(field->regmap, | ||
1634 | field->reg + (field->id_offset * id), | ||
1635 | field->mask, val << field->shift); | ||
1636 | } | ||
1637 | EXPORT_SYMBOL_GPL(regmap_fields_force_write); | ||
1638 | |||
1627 | /** | 1639 | /** |
1628 | * regmap_fields_update_bits(): Perform a read/modify/write cycle | 1640 | * regmap_fields_update_bits(): Perform a read/modify/write cycle |
1629 | * on the register field | 1641 | * on the register field |
@@ -2327,7 +2339,7 @@ EXPORT_SYMBOL_GPL(regmap_bulk_read); | |||
2327 | 2339 | ||
2328 | static int _regmap_update_bits(struct regmap *map, unsigned int reg, | 2340 | static int _regmap_update_bits(struct regmap *map, unsigned int reg, |
2329 | unsigned int mask, unsigned int val, | 2341 | unsigned int mask, unsigned int val, |
2330 | bool *change) | 2342 | bool *change, bool force_write) |
2331 | { | 2343 | { |
2332 | int ret; | 2344 | int ret; |
2333 | unsigned int tmp, orig; | 2345 | unsigned int tmp, orig; |
@@ -2339,7 +2351,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, | |||
2339 | tmp = orig & ~mask; | 2351 | tmp = orig & ~mask; |
2340 | tmp |= val & mask; | 2352 | tmp |= val & mask; |
2341 | 2353 | ||
2342 | if (tmp != orig) { | 2354 | if (force_write || (tmp != orig)) { |
2343 | ret = _regmap_write(map, reg, tmp); | 2355 | ret = _regmap_write(map, reg, tmp); |
2344 | if (change) | 2356 | if (change) |
2345 | *change = true; | 2357 | *change = true; |
@@ -2367,7 +2379,7 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, | |||
2367 | int ret; | 2379 | int ret; |
2368 | 2380 | ||
2369 | map->lock(map->lock_arg); | 2381 | map->lock(map->lock_arg); |
2370 | ret = _regmap_update_bits(map, reg, mask, val, NULL); | 2382 | ret = _regmap_update_bits(map, reg, mask, val, NULL, false); |
2371 | map->unlock(map->lock_arg); | 2383 | map->unlock(map->lock_arg); |
2372 | 2384 | ||
2373 | return ret; | 2385 | return ret; |
@@ -2375,6 +2387,29 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, | |||
2375 | EXPORT_SYMBOL_GPL(regmap_update_bits); | 2387 | EXPORT_SYMBOL_GPL(regmap_update_bits); |
2376 | 2388 | ||
2377 | /** | 2389 | /** |
2390 | * regmap_write_bits: Perform a read/modify/write cycle on the register map | ||
2391 | * | ||
2392 | * @map: Register map to update | ||
2393 | * @reg: Register to update | ||
2394 | * @mask: Bitmask to change | ||
2395 | * @val: New value for bitmask | ||
2396 | * | ||
2397 | * Returns zero for success, a negative number on error. | ||
2398 | */ | ||
2399 | int regmap_write_bits(struct regmap *map, unsigned int reg, | ||
2400 | unsigned int mask, unsigned int val) | ||
2401 | { | ||
2402 | int ret; | ||
2403 | |||
2404 | map->lock(map->lock_arg); | ||
2405 | ret = _regmap_update_bits(map, reg, mask, val, NULL, true); | ||
2406 | map->unlock(map->lock_arg); | ||
2407 | |||
2408 | return ret; | ||
2409 | } | ||
2410 | EXPORT_SYMBOL_GPL(regmap_write_bits); | ||
2411 | |||
2412 | /** | ||
2378 | * regmap_update_bits_async: Perform a read/modify/write cycle on the register | 2413 | * regmap_update_bits_async: Perform a read/modify/write cycle on the register |
2379 | * map asynchronously | 2414 | * map asynchronously |
2380 | * | 2415 | * |
@@ -2398,7 +2433,7 @@ int regmap_update_bits_async(struct regmap *map, unsigned int reg, | |||
2398 | 2433 | ||
2399 | map->async = true; | 2434 | map->async = true; |
2400 | 2435 | ||
2401 | ret = _regmap_update_bits(map, reg, mask, val, NULL); | 2436 | ret = _regmap_update_bits(map, reg, mask, val, NULL, false); |
2402 | 2437 | ||
2403 | map->async = false; | 2438 | map->async = false; |
2404 | 2439 | ||
@@ -2427,7 +2462,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, | |||
2427 | int ret; | 2462 | int ret; |
2428 | 2463 | ||
2429 | map->lock(map->lock_arg); | 2464 | map->lock(map->lock_arg); |
2430 | ret = _regmap_update_bits(map, reg, mask, val, change); | 2465 | ret = _regmap_update_bits(map, reg, mask, val, change, false); |
2431 | map->unlock(map->lock_arg); | 2466 | map->unlock(map->lock_arg); |
2432 | return ret; | 2467 | return ret; |
2433 | } | 2468 | } |
@@ -2460,7 +2495,7 @@ int regmap_update_bits_check_async(struct regmap *map, unsigned int reg, | |||
2460 | 2495 | ||
2461 | map->async = true; | 2496 | map->async = true; |
2462 | 2497 | ||
2463 | ret = _regmap_update_bits(map, reg, mask, val, change); | 2498 | ret = _regmap_update_bits(map, reg, mask, val, change, false); |
2464 | 2499 | ||
2465 | map->async = false; | 2500 | map->async = false; |
2466 | 2501 | ||
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 59c55ea0f0b5..519c96231a91 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
@@ -424,6 +424,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, | |||
424 | size_t val_count); | 424 | size_t val_count); |
425 | int regmap_update_bits(struct regmap *map, unsigned int reg, | 425 | int regmap_update_bits(struct regmap *map, unsigned int reg, |
426 | unsigned int mask, unsigned int val); | 426 | unsigned int mask, unsigned int val); |
427 | int regmap_write_bits(struct regmap *map, unsigned int reg, | ||
428 | unsigned int mask, unsigned int val); | ||
427 | int regmap_update_bits_async(struct regmap *map, unsigned int reg, | 429 | int regmap_update_bits_async(struct regmap *map, unsigned int reg, |
428 | unsigned int mask, unsigned int val); | 430 | unsigned int mask, unsigned int val); |
429 | int regmap_update_bits_check(struct regmap *map, unsigned int reg, | 431 | int regmap_update_bits_check(struct regmap *map, unsigned int reg, |
@@ -503,6 +505,8 @@ int regmap_field_update_bits(struct regmap_field *field, | |||
503 | 505 | ||
504 | int regmap_fields_write(struct regmap_field *field, unsigned int id, | 506 | int regmap_fields_write(struct regmap_field *field, unsigned int id, |
505 | unsigned int val); | 507 | unsigned int val); |
508 | int regmap_fields_force_write(struct regmap_field *field, unsigned int id, | ||
509 | unsigned int val); | ||
506 | int regmap_fields_read(struct regmap_field *field, unsigned int id, | 510 | int regmap_fields_read(struct regmap_field *field, unsigned int id, |
507 | unsigned int *val); | 511 | unsigned int *val); |
508 | int regmap_fields_update_bits(struct regmap_field *field, unsigned int id, | 512 | int regmap_fields_update_bits(struct regmap_field *field, unsigned int id, |
@@ -645,6 +649,13 @@ static inline int regmap_update_bits(struct regmap *map, unsigned int reg, | |||
645 | return -EINVAL; | 649 | return -EINVAL; |
646 | } | 650 | } |
647 | 651 | ||
652 | static inline int regmap_write_bits(struct regmap *map, unsigned int reg, | ||
653 | unsigned int mask, unsigned int val) | ||
654 | { | ||
655 | WARN_ONCE(1, "regmap API is disabled"); | ||
656 | return -EINVAL; | ||
657 | } | ||
658 | |||
648 | static inline int regmap_update_bits_async(struct regmap *map, | 659 | static inline int regmap_update_bits_async(struct regmap *map, |
649 | unsigned int reg, | 660 | unsigned int reg, |
650 | unsigned int mask, unsigned int val) | 661 | unsigned int mask, unsigned int val) |