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.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index be10a4ff6609..28e89fd7c28d 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -669,6 +669,64 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
669} 669}
670EXPORT_SYMBOL_GPL(regmap_update_bits_check); 670EXPORT_SYMBOL_GPL(regmap_update_bits_check);
671 671
672/**
673 * regmap_register_patch: Register and apply register updates to be applied
674 * on device initialistion
675 *
676 * @map: Register map to apply updates to.
677 * @regs: Values to update.
678 * @num_regs: Number of entries in regs.
679 *
680 * Register a set of register updates to be applied to the device
681 * whenever the device registers are synchronised with the cache and
682 * apply them immediately. Typically this is used to apply
683 * corrections to be applied to the device defaults on startup, such
684 * as the updates some vendors provide to undocumented registers.
685 */
686int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
687 int num_regs)
688{
689 int i, ret;
690 bool bypass;
691
692 /* If needed the implementation can be extended to support this */
693 if (map->patch)
694 return -EBUSY;
695
696 mutex_lock(&map->lock);
697
698 bypass = map->cache_bypass;
699
700 map->cache_bypass = true;
701
702 /* Write out first; it's useful to apply even if we fail later. */
703 for (i = 0; i < num_regs; i++) {
704 ret = _regmap_write(map, regs[i].reg, regs[i].def);
705 if (ret != 0) {
706 dev_err(map->dev, "Failed to write %x = %x: %d\n",
707 regs[i].reg, regs[i].def, ret);
708 goto out;
709 }
710 }
711
712 map->patch = kcalloc(sizeof(struct reg_default), num_regs, GFP_KERNEL);
713 if (map->patch != NULL) {
714 memcpy(map->patch, regs,
715 num_regs * sizeof(struct reg_default));
716 map->patch_regs = num_regs;
717 } else {
718 ret = -ENOMEM;
719 }
720
721out:
722 map->cache_bypass = bypass;
723
724 mutex_unlock(&map->lock);
725
726 return ret;
727}
728EXPORT_SYMBOL_GPL(regmap_register_patch);
729
672static int __init regmap_initcall(void) 730static int __init regmap_initcall(void)
673{ 731{
674 regmap_debugfs_initcall(); 732 regmap_debugfs_initcall();