Loading drivers/base/regmap/internal.h +1 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ struct regcache_ops { int (*exit)(struct regmap *map); int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); int (*write)(struct regmap *map, unsigned int reg, unsigned int value); int (*sync)(struct regmap *map); int (*sync)(struct regmap *map, unsigned int min, unsigned int max); }; bool regmap_writeable(struct regmap *map, unsigned int reg); Loading drivers/base/regmap/regcache-lzo.c +8 −2 Original line number Diff line number Diff line Loading @@ -331,7 +331,8 @@ out: return ret; } static int regcache_lzo_sync(struct regmap *map) static int regcache_lzo_sync(struct regmap *map, unsigned int min, unsigned int max) { struct regcache_lzo_ctx **lzo_blocks; unsigned int val; Loading @@ -339,7 +340,12 @@ static int regcache_lzo_sync(struct regmap *map) int ret; lzo_blocks = map->cache; for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { i = min; for_each_set_bit_cont(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { if (i > max) continue; ret = regcache_read(map, i, &val); if (ret) return ret; Loading drivers/base/regmap/regcache-rbtree.c +22 −3 Original line number Diff line number Diff line Loading @@ -357,7 +357,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, return 0; } static int regcache_rbtree_sync(struct regmap *map) static int regcache_rbtree_sync(struct regmap *map, unsigned int min, unsigned int max) { struct regcache_rbtree_ctx *rbtree_ctx; struct rb_node *node; Loading @@ -365,12 +366,30 @@ static int regcache_rbtree_sync(struct regmap *map) unsigned int regtmp; unsigned int val; int ret; int i; int i, base, end; rbtree_ctx = map->cache; for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { rbnode = rb_entry(node, struct regcache_rbtree_node, node); for (i = 0; i < rbnode->blklen; i++) { if (rbnode->base_reg < min) continue; if (rbnode->base_reg > max) break; if (rbnode->base_reg + rbnode->blklen < min) continue; if (min > rbnode->base_reg) base = min - rbnode->base_reg; else base = 0; if (max < rbnode->base_reg + rbnode->blklen) end = rbnode->base_reg + rbnode->blklen - max; else end = rbnode->blklen; for (i = base; i < end; i++) { regtmp = rbnode->base_reg + i; val = regcache_rbtree_get_register(rbnode, i, map->cache_word_size); Loading drivers/base/regmap/regcache.c +50 −19 Original line number Diff line number Diff line Loading @@ -252,12 +252,11 @@ int regcache_write(struct regmap *map, int regcache_sync(struct regmap *map) { int ret = 0; unsigned int val; unsigned int i; const char *name; unsigned int bypass; BUG_ON(!map->cache_ops); BUG_ON(!map->cache_ops || !map->cache_ops->sync); mutex_lock(&map->lock); /* Remember the initial bypass state */ Loading @@ -282,24 +281,11 @@ int regcache_sync(struct regmap *map) } map->cache_bypass = 0; if (map->cache_ops->sync) { ret = map->cache_ops->sync(map); } else { for (i = 0; i < map->num_reg_defaults; i++) { ret = regcache_read(map, i, &val); if (ret < 0) goto out; map->cache_bypass = 1; ret = _regmap_write(map, i, val); map->cache_bypass = 0; if (ret < 0) goto out; dev_dbg(map->dev, "Synced register %#x, value %#x\n", map->reg_defaults[i].reg, map->reg_defaults[i].def); } ret = map->cache_ops->sync(map, 0, map->max_register); if (ret == 0) map->cache_dirty = false; } out: trace_regcache_sync(map->dev, name, "stop"); /* Restore the bypass state */ Loading @@ -310,6 +296,51 @@ out: } EXPORT_SYMBOL_GPL(regcache_sync); /** * regcache_sync_region: Sync part of the register cache with the hardware. * * @map: map to sync. * @min: first register to sync * @max: last register to sync * * Write all non-default register values in the specified region to * the hardware. * * Return a negative value on failure, 0 on success. */ int regcache_sync_region(struct regmap *map, unsigned int min, unsigned int max) { int ret = 0; const char *name; unsigned int bypass; BUG_ON(!map->cache_ops || !map->cache_ops->sync); mutex_lock(&map->lock); /* Remember the initial bypass state */ bypass = map->cache_bypass; name = map->cache_ops->name; dev_dbg(map->dev, "Syncing %s cache from %d-%d\n", name, min, max); trace_regcache_sync(map->dev, name, "start region"); if (!map->cache_dirty) goto out; ret = map->cache_ops->sync(map, min, max); out: trace_regcache_sync(map->dev, name, "stop region"); /* Restore the bypass state */ map->cache_bypass = bypass; mutex_unlock(&map->lock); return ret; } /** * regcache_cache_only: Put a register map into cache only mode * Loading include/linux/regmap.h +2 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,8 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, bool *change); int regcache_sync(struct regmap *map); int regcache_sync_region(struct regmap *map, unsigned int min, unsigned int max); void regcache_cache_only(struct regmap *map, bool enable); void regcache_cache_bypass(struct regmap *map, bool enable); void regcache_mark_dirty(struct regmap *map); Loading Loading
drivers/base/regmap/internal.h +1 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ struct regcache_ops { int (*exit)(struct regmap *map); int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); int (*write)(struct regmap *map, unsigned int reg, unsigned int value); int (*sync)(struct regmap *map); int (*sync)(struct regmap *map, unsigned int min, unsigned int max); }; bool regmap_writeable(struct regmap *map, unsigned int reg); Loading
drivers/base/regmap/regcache-lzo.c +8 −2 Original line number Diff line number Diff line Loading @@ -331,7 +331,8 @@ out: return ret; } static int regcache_lzo_sync(struct regmap *map) static int regcache_lzo_sync(struct regmap *map, unsigned int min, unsigned int max) { struct regcache_lzo_ctx **lzo_blocks; unsigned int val; Loading @@ -339,7 +340,12 @@ static int regcache_lzo_sync(struct regmap *map) int ret; lzo_blocks = map->cache; for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { i = min; for_each_set_bit_cont(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { if (i > max) continue; ret = regcache_read(map, i, &val); if (ret) return ret; Loading
drivers/base/regmap/regcache-rbtree.c +22 −3 Original line number Diff line number Diff line Loading @@ -357,7 +357,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, return 0; } static int regcache_rbtree_sync(struct regmap *map) static int regcache_rbtree_sync(struct regmap *map, unsigned int min, unsigned int max) { struct regcache_rbtree_ctx *rbtree_ctx; struct rb_node *node; Loading @@ -365,12 +366,30 @@ static int regcache_rbtree_sync(struct regmap *map) unsigned int regtmp; unsigned int val; int ret; int i; int i, base, end; rbtree_ctx = map->cache; for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { rbnode = rb_entry(node, struct regcache_rbtree_node, node); for (i = 0; i < rbnode->blklen; i++) { if (rbnode->base_reg < min) continue; if (rbnode->base_reg > max) break; if (rbnode->base_reg + rbnode->blklen < min) continue; if (min > rbnode->base_reg) base = min - rbnode->base_reg; else base = 0; if (max < rbnode->base_reg + rbnode->blklen) end = rbnode->base_reg + rbnode->blklen - max; else end = rbnode->blklen; for (i = base; i < end; i++) { regtmp = rbnode->base_reg + i; val = regcache_rbtree_get_register(rbnode, i, map->cache_word_size); Loading
drivers/base/regmap/regcache.c +50 −19 Original line number Diff line number Diff line Loading @@ -252,12 +252,11 @@ int regcache_write(struct regmap *map, int regcache_sync(struct regmap *map) { int ret = 0; unsigned int val; unsigned int i; const char *name; unsigned int bypass; BUG_ON(!map->cache_ops); BUG_ON(!map->cache_ops || !map->cache_ops->sync); mutex_lock(&map->lock); /* Remember the initial bypass state */ Loading @@ -282,24 +281,11 @@ int regcache_sync(struct regmap *map) } map->cache_bypass = 0; if (map->cache_ops->sync) { ret = map->cache_ops->sync(map); } else { for (i = 0; i < map->num_reg_defaults; i++) { ret = regcache_read(map, i, &val); if (ret < 0) goto out; map->cache_bypass = 1; ret = _regmap_write(map, i, val); map->cache_bypass = 0; if (ret < 0) goto out; dev_dbg(map->dev, "Synced register %#x, value %#x\n", map->reg_defaults[i].reg, map->reg_defaults[i].def); } ret = map->cache_ops->sync(map, 0, map->max_register); if (ret == 0) map->cache_dirty = false; } out: trace_regcache_sync(map->dev, name, "stop"); /* Restore the bypass state */ Loading @@ -310,6 +296,51 @@ out: } EXPORT_SYMBOL_GPL(regcache_sync); /** * regcache_sync_region: Sync part of the register cache with the hardware. * * @map: map to sync. * @min: first register to sync * @max: last register to sync * * Write all non-default register values in the specified region to * the hardware. * * Return a negative value on failure, 0 on success. */ int regcache_sync_region(struct regmap *map, unsigned int min, unsigned int max) { int ret = 0; const char *name; unsigned int bypass; BUG_ON(!map->cache_ops || !map->cache_ops->sync); mutex_lock(&map->lock); /* Remember the initial bypass state */ bypass = map->cache_bypass; name = map->cache_ops->name; dev_dbg(map->dev, "Syncing %s cache from %d-%d\n", name, min, max); trace_regcache_sync(map->dev, name, "start region"); if (!map->cache_dirty) goto out; ret = map->cache_ops->sync(map, min, max); out: trace_regcache_sync(map->dev, name, "stop region"); /* Restore the bypass state */ map->cache_bypass = bypass; mutex_unlock(&map->lock); return ret; } /** * regcache_cache_only: Put a register map into cache only mode * Loading
include/linux/regmap.h +2 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,8 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, bool *change); int regcache_sync(struct regmap *map); int regcache_sync_region(struct regmap *map, unsigned int min, unsigned int max); void regcache_cache_only(struct regmap *map, bool enable); void regcache_cache_bypass(struct regmap *map, bool enable); void regcache_mark_dirty(struct regmap *map); Loading