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.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 58f84c3a6fc1..e3ee9cabccb4 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -374,6 +374,9 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
374 374
375 regmap_debugfs_init(map); 375 regmap_debugfs_init(map);
376 376
377 map->cache_bypass = false;
378 map->cache_only = false;
379
377 ret = regcache_init(map, config); 380 ret = regcache_init(map, config);
378 381
379 mutex_unlock(&map->lock); 382 mutex_unlock(&map->lock);
@@ -783,6 +786,64 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
783} 786}
784EXPORT_SYMBOL_GPL(regmap_update_bits_check); 787EXPORT_SYMBOL_GPL(regmap_update_bits_check);
785 788
789/**
790 * regmap_register_patch: Register and apply register updates to be applied
791 * on device initialistion
792 *
793 * @map: Register map to apply updates to.
794 * @regs: Values to update.
795 * @num_regs: Number of entries in regs.
796 *
797 * Register a set of register updates to be applied to the device
798 * whenever the device registers are synchronised with the cache and
799 * apply them immediately. Typically this is used to apply
800 * corrections to be applied to the device defaults on startup, such
801 * as the updates some vendors provide to undocumented registers.
802 */
803int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
804 int num_regs)
805{
806 int i, ret;
807 bool bypass;
808
809 /* If needed the implementation can be extended to support this */
810 if (map->patch)
811 return -EBUSY;
812
813 mutex_lock(&map->lock);
814
815 bypass = map->cache_bypass;
816
817 map->cache_bypass = true;
818
819 /* Write out first; it's useful to apply even if we fail later. */
820 for (i = 0; i < num_regs; i++) {
821 ret = _regmap_write(map, regs[i].reg, regs[i].def);
822 if (ret != 0) {
823 dev_err(map->dev, "Failed to write %x = %x: %d\n",
824 regs[i].reg, regs[i].def, ret);
825 goto out;
826 }
827 }
828
829 map->patch = kcalloc(num_regs, sizeof(struct reg_default), GFP_KERNEL);
830 if (map->patch != NULL) {
831 memcpy(map->patch, regs,
832 num_regs * sizeof(struct reg_default));
833 map->patch_regs = num_regs;
834 } else {
835 ret = -ENOMEM;
836 }
837
838out:
839 map->cache_bypass = bypass;
840
841 mutex_unlock(&map->lock);
842
843 return ret;
844}
845EXPORT_SYMBOL_GPL(regmap_register_patch);
846
786static int __init regmap_initcall(void) 847static int __init regmap_initcall(void)
787{ 848{
788 regmap_debugfs_initcall(); 849 regmap_debugfs_initcall();