aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-10-26 04:34:22 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-11-08 06:38:15 -0500
commit8ae0d7e8a918e9603748abe9b31984fc5d96abb3 (patch)
tree329564b9bdc3cac89a3ac1586c9e5812ab21bf1c
parent1ea6b8f48918282bdca0b32a34095504ee65bab5 (diff)
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>
-rw-r--r--drivers/base/regmap/internal.h1
-rw-r--r--drivers/base/regmap/regcache.c19
-rw-r--r--drivers/base/regmap/regmap.c4
-rw-r--r--include/linux/regmap.h1
4 files changed, 24 insertions, 1 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 348ff02eb93e..6483e0bda0cf 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -74,6 +74,7 @@ struct regmap {
74 struct reg_default *reg_defaults; 74 struct reg_default *reg_defaults;
75 const void *reg_defaults_raw; 75 const void *reg_defaults_raw;
76 void *cache; 76 void *cache;
77 bool cache_dirty;
77}; 78};
78 79
79struct regcache_ops { 80struct regcache_ops {
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 666f6f5011dc..6ab9f0384d82 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -241,6 +241,8 @@ int regcache_sync(struct regmap *map)
241 map->cache_ops->name); 241 map->cache_ops->name);
242 name = map->cache_ops->name; 242 name = map->cache_ops->name;
243 trace_regcache_sync(map->dev, name, "start"); 243 trace_regcache_sync(map->dev, name, "start");
244 if (!map->cache_dirty)
245 goto out;
244 if (map->cache_ops->sync) { 246 if (map->cache_ops->sync) {
245 ret = map->cache_ops->sync(map); 247 ret = map->cache_ops->sync(map);
246 } else { 248 } else {
@@ -291,6 +293,23 @@ void regcache_cache_only(struct regmap *map, bool enable)
291EXPORT_SYMBOL_GPL(regcache_cache_only); 293EXPORT_SYMBOL_GPL(regcache_cache_only);
292 294
293/** 295/**
296 * regcache_mark_dirty: Mark the register cache as dirty
297 *
298 * @map: map to mark
299 *
300 * Mark the register cache as dirty, for example due to the device
301 * having been powered down for suspend. If the cache is not marked
302 * as dirty then the cache sync will be suppressed.
303 */
304void regcache_mark_dirty(struct regmap *map)
305{
306 mutex_lock(&map->lock);
307 map->cache_dirty = true;
308 mutex_unlock(&map->lock);
309}
310EXPORT_SYMBOL_GPL(regcache_mark_dirty);
311
312/**
294 * regcache_cache_bypass: Put a register map into cache bypass mode 313 * regcache_cache_bypass: Put a register map into cache bypass mode
295 * 314 *
296 * @map: map to configure 315 * @map: map to configure
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index bf441db1ee90..3aca18dbf367 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -306,8 +306,10 @@ int _regmap_write(struct regmap *map, unsigned int reg,
306 ret = regcache_write(map, reg, val); 306 ret = regcache_write(map, reg, val);
307 if (ret != 0) 307 if (ret != 0)
308 return ret; 308 return ret;
309 if (map->cache_only) 309 if (map->cache_only) {
310 map->cache_dirty = true;
310 return 0; 311 return 0;
312 }
311 } 313 }
312 314
313 trace_regmap_reg_write(map->dev, reg, val); 315 trace_regmap_reg_write(map->dev, reg, val);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 690276a642cf..32043a9749e6 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -143,5 +143,6 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
143int regcache_sync(struct regmap *map); 143int regcache_sync(struct regmap *map);
144void regcache_cache_only(struct regmap *map, bool enable); 144void regcache_cache_only(struct regmap *map, bool enable);
145void regcache_cache_bypass(struct regmap *map, bool enable); 145void regcache_cache_bypass(struct regmap *map, bool enable);
146void regcache_mark_dirty(struct regmap *map);
146 147
147#endif 148#endif