Commit 018690d33ecf4aa1eb1415e38c40e2b0b6c7808e
1 parent
c86845dc7b
Exists in
master
and in
6 other branches
regmap: Allow regmap_update_bits() users to detect changes
Some users of regmap_update_bits() would like to be able to tell their users if they actually did an update so provide a variant which also returns a flag indicating if an update took place. We could return a tristate in the return value of regmap_update_bits() but this makes the API more cumbersome to use and doesn't fit with the general zero for success idiom we have. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Showing 2 changed files with 48 additions and 13 deletions Side-by-side Diff
drivers/base/regmap/regmap.c
... | ... | @@ -569,18 +569,9 @@ |
569 | 569 | } |
570 | 570 | EXPORT_SYMBOL_GPL(regmap_bulk_read); |
571 | 571 | |
572 | -/** | |
573 | - * regmap_update_bits: Perform a read/modify/write cycle on the register map | |
574 | - * | |
575 | - * @map: Register map to update | |
576 | - * @reg: Register to update | |
577 | - * @mask: Bitmask to change | |
578 | - * @val: New value for bitmask | |
579 | - * | |
580 | - * Returns zero for success, a negative number on error. | |
581 | - */ | |
582 | -int regmap_update_bits(struct regmap *map, unsigned int reg, | |
583 | - unsigned int mask, unsigned int val) | |
572 | +static int _regmap_update_bits(struct regmap *map, unsigned int reg, | |
573 | + unsigned int mask, unsigned int val, | |
574 | + bool *change) | |
584 | 575 | { |
585 | 576 | int ret; |
586 | 577 | unsigned int tmp, orig; |
587 | 578 | |
588 | 579 | |
589 | 580 | |
... | ... | @@ -594,15 +585,56 @@ |
594 | 585 | tmp = orig & ~mask; |
595 | 586 | tmp |= val & mask; |
596 | 587 | |
597 | - if (tmp != orig) | |
588 | + if (tmp != orig) { | |
598 | 589 | ret = _regmap_write(map, reg, tmp); |
590 | + *change = true; | |
591 | + } else { | |
592 | + *change = false; | |
593 | + } | |
599 | 594 | |
600 | 595 | out: |
601 | 596 | mutex_unlock(&map->lock); |
602 | 597 | |
603 | 598 | return ret; |
604 | 599 | } |
600 | + | |
601 | +/** | |
602 | + * regmap_update_bits: Perform a read/modify/write cycle on the register map | |
603 | + * | |
604 | + * @map: Register map to update | |
605 | + * @reg: Register to update | |
606 | + * @mask: Bitmask to change | |
607 | + * @val: New value for bitmask | |
608 | + * | |
609 | + * Returns zero for success, a negative number on error. | |
610 | + */ | |
611 | +int regmap_update_bits(struct regmap *map, unsigned int reg, | |
612 | + unsigned int mask, unsigned int val) | |
613 | +{ | |
614 | + bool change; | |
615 | + return _regmap_update_bits(map, reg, mask, val, &change); | |
616 | +} | |
605 | 617 | EXPORT_SYMBOL_GPL(regmap_update_bits); |
618 | + | |
619 | +/** | |
620 | + * regmap_update_bits_check: Perform a read/modify/write cycle on the | |
621 | + * register map and report if updated | |
622 | + * | |
623 | + * @map: Register map to update | |
624 | + * @reg: Register to update | |
625 | + * @mask: Bitmask to change | |
626 | + * @val: New value for bitmask | |
627 | + * @change: Boolean indicating if a write was done | |
628 | + * | |
629 | + * Returns zero for success, a negative number on error. | |
630 | + */ | |
631 | +int regmap_update_bits_check(struct regmap *map, unsigned int reg, | |
632 | + unsigned int mask, unsigned int val, | |
633 | + bool *change) | |
634 | +{ | |
635 | + return _regmap_update_bits(map, reg, mask, val, change); | |
636 | +} | |
637 | +EXPORT_SYMBOL_GPL(regmap_update_bits_check); | |
606 | 638 | |
607 | 639 | static int __init regmap_initcall(void) |
608 | 640 | { |
include/linux/regmap.h
... | ... | @@ -138,6 +138,9 @@ |
138 | 138 | size_t val_count); |
139 | 139 | int regmap_update_bits(struct regmap *map, unsigned int reg, |
140 | 140 | unsigned int mask, unsigned int val); |
141 | +int regmap_update_bits_check(struct regmap *map, unsigned int reg, | |
142 | + unsigned int mask, unsigned int val, | |
143 | + bool *change); | |
141 | 144 | |
142 | 145 | int regcache_sync(struct regmap *map); |
143 | 146 | void regcache_cache_only(struct regmap *map, bool enable); |