diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 348ff02eb93e02a66887b59995900335f7214fc0..6483e0bda0cfb97a48489f13a30e55c36c893e47 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -74,6 +74,7 @@ struct regmap { struct reg_default *reg_defaults; const void *reg_defaults_raw; void *cache; + bool cache_dirty; }; struct regcache_ops { diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 666f6f5011dc85339287f9b982f991e22081626b..6ab9f0384d82c3fa82f6c575d45dac31d4b305ca 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -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 * diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index bf441db1ee90af507ac3597e6a32dd1a3cbfec10..3aca18dbf367389c4e35cac5c38b47d943ee24e4 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, 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); diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 690276a642cf75dd5dbfcd1d620b8a94880714fc..32043a9749e68def3b7486eeb5ef15232d6d299e 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, 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