Skip to content

Commit

Permalink
regmap: Track if the register cache is dirty and suppress unneeded syncs
Browse files Browse the repository at this point in the history
Allow drivers to optimise out the register cache sync if they didn't need
to do one. If the hardware is desynced from the register cache (by power
loss for example) then the driver should call regcache_mark_dirty() to
let the core know about this.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Mark Brown committed Nov 8, 2011
1 parent 1ea6b8f commit 8ae0d7e
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/base/regmap/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct regmap {
struct reg_default *reg_defaults;
const void *reg_defaults_raw;
void *cache;
bool cache_dirty;
};

struct regcache_ops {
Expand Down
19 changes: 19 additions & 0 deletions drivers/base/regmap/regcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ int regcache_sync(struct regmap *map)
map->cache_ops->name);
name = map->cache_ops->name;
trace_regcache_sync(map->dev, name, "start");
if (!map->cache_dirty)
goto out;
if (map->cache_ops->sync) {
ret = map->cache_ops->sync(map);
} else {
Expand Down Expand Up @@ -290,6 +292,23 @@ void regcache_cache_only(struct regmap *map, bool enable)
}
EXPORT_SYMBOL_GPL(regcache_cache_only);

/**
* regcache_mark_dirty: Mark the register cache as dirty
*
* @map: map to mark
*
* Mark the register cache as dirty, for example due to the device
* having been powered down for suspend. If the cache is not marked
* as dirty then the cache sync will be suppressed.
*/
void regcache_mark_dirty(struct regmap *map)
{
mutex_lock(&map->lock);
map->cache_dirty = true;
mutex_unlock(&map->lock);
}
EXPORT_SYMBOL_GPL(regcache_mark_dirty);

/**
* regcache_cache_bypass: Put a register map into cache bypass mode
*
Expand Down
4 changes: 3 additions & 1 deletion drivers/base/regmap/regmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,10 @@ int _regmap_write(struct regmap *map, unsigned int reg,
ret = regcache_write(map, reg, val);
if (ret != 0)
return ret;
if (map->cache_only)
if (map->cache_only) {
map->cache_dirty = true;
return 0;
}
}

trace_regmap_reg_write(map->dev, reg, val);
Expand Down
1 change: 1 addition & 0 deletions include/linux/regmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,6 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
int regcache_sync(struct regmap *map);
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);

#endif

0 comments on commit 8ae0d7e

Please sign in to comment.