regmap: Track if the register cache is dirty and suppress unneeded syncs

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>
This commit is contained in:
Mark Brown 2011-10-26 10:34:22 +02:00
parent 1ea6b8f489
commit 8ae0d7e8a9
4 changed files with 24 additions and 1 deletions

View File

@ -74,6 +74,7 @@ struct regmap {
struct reg_default *reg_defaults;
const void *reg_defaults_raw;
void *cache;
bool cache_dirty;
};
struct regcache_ops {

View File

@ -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 {
@ -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
*

View File

@ -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);

View File

@ -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