regmap: Lock the sync path, ensure we use the lockless _regmap_write()
Subsystems (2)
PATCH 1/4 regmap: Lock the sync path, ensure we use the lockless _regmap_write()
Signed-off-by Dimitris Papastamos <[email protected]>
--- drivers/base/regmap/regcache-indexed.c | 4 ++-- drivers/base/regmap/regcache-lzo.c | 2 +- drivers/base/regmap/regcache-rbtree.c | 2 +- drivers/base/regmap/regcache.c | 4 +++- 4 files changed, 7 insertions(+), 5 deletions(-)
drivers/base/regmap/regcache-indexed.c +2 -2
@@ -45,8 +45,8 @@ static int regcache_indexed_sync(struct regmap *map)int ret;for (i =0 ; i < map->num_reg_defaults; i++) { - ret =regmap_write (map, map->reg_defaults[i].reg, - map->reg_defaults[i].def); + ret =_regmap_write (map, map->reg_defaults[i].reg, + map->reg_defaults[i].def);if (ret <0 )return ret; dev_dbg(map->dev, "Synced register %#x, value %#x\n",
drivers/base/regmap/regcache-lzo.c +1 -1
@@ -339,7 +339,7 @@ static int regcache_lzo_sync(struct regmap *map)if (ret)return ret; map->cache_bypass =1 ; - ret =regmap_write (map, i, val); + ret =_regmap_write (map, i, val); map->cache_bypass =0 ;if (ret)return ret;
drivers/base/regmap/regcache-rbtree.c +1 -1
@@ -327,7 +327,7 @@ static int regcache_rbtree_sync(struct regmap *map)if (val == def)continue ; map->cache_bypass =1 ; - ret =regmap_write (map, regtmp, val); + ret =_regmap_write (map, regtmp, val); map->cache_bypass =0 ;if (ret)return ret;
drivers/base/regmap/regcache.c +3 -1
@@ -230,6 +230,7 @@ int regcache_sync(struct regmap *map)BUG_ON (!map->cache_ops); +mutex_lock (&map->lock);dev_dbg (map->dev,"Syncing %s cache\n" , map->cache_ops->name); name = map->cache_ops->name;
@@ -242,7 +243,7 @@ int regcache_sync(struct regmap *map)if (ret <0 ) goto out; map->cache_bypass =1 ; - ret =regmap_write (map, i, val); + ret =_regmap_write (map, i, val); map->cache_bypass =0 ;if (ret <0 ) goto out;
@@ -254,6 +255,7 @@ int regcache_sync(struct regmap *map) } out:trace_regcache_sync (map->dev, name,"stop" ); +mutex_unlock (&map->lock);return ret; }
Signature · 1 line
1.7.6.4
PATCH 2/4 regmap: Save/restore the bypass state upon syncing
Signed-off-by Dimitris Papastamos <[email protected]>
--- drivers/base/regmap/regcache.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
drivers/base/regmap/regcache.c +5 -0
@@ -227,10 +227,13 @@ int regcache_sync(struct regmap *map)unsigned int val;unsigned int i;const char *name; +unsigned int bypass;BUG_ON (!map->cache_ops);mutex_lock (&map->lock); +/* Remember the initial bypass state */ + bypass = map->cache_bypass;dev_dbg (map->dev,"Syncing %s cache\n" , map->cache_ops->name); name = map->cache_ops->name;
@@ -255,6 +258,8 @@ int regcache_sync(struct regmap *map) } out:trace_regcache_sync (map->dev, name,"stop" ); +/* Restore the bypass state */ + map->cache_bypass = bypass;mutex_unlock (&map->lock);return ret;
Signature · 1 line
1.7.6.4
PATCH 3/4 regmap: Implement regcache_cache_bypass helper function
In reply to Dimitris PapastamosEnsure we've got a function so users can enable/disable the cache bypass option.
Signed-off-by Dimitris Papastamos <[email protected]>
--- drivers/base/regmap/regcache.c | 19 +++++++++++++++++++ include/linux/regmap.h | 1 + 2 files changed, 20 insertions(+), 0 deletions(-)
drivers/base/regmap/regcache.c +19 -0
@@ -286,6 +286,25 @@ void regcache_cache_only(struct regmap *map, bool enable) }EXPORT_SYMBOL_GPL (regcache_cache_only); +/** +* regcache_cache_bypass: Put a register map into cache bypass mode +* +* @map: map to configure +* @cache_only: flag if changes should not be written to the hardware +* +* When a register map is marked with the cache bypass option, writes +* to the register map API will only update the hardware and not the +* the cache directly. This is useful when syncing the cache back to +* the hardware. +*/ +void regcache_cache_bypass (struct regmap *map,bool enable) +{ +mutex_lock (&map->lock); + map->cache_bypass = enable; +mutex_unlock (&map->lock); +} +EXPORT_SYMBOL_GPL (regcache_cache_bypass); +bool regcache_set_val (void *base,unsigned int idx,unsigned int val,unsigned int word_size) {
include/linux/regmap.h +1 -0
@@ -142,5 +142,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);#endif
Signature · 1 line
1.7.6.4
PATCH 4/4 regmap: Ensure we scream if we enable cache bypass/only at the same time
In reply to Dimitris PapastamosSigned-off-by Dimitris Papastamos <[email protected]>
--- drivers/base/regmap/regcache.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/base/regmap/regcache.c +2 -0
@@ -281,6 +281,7 @@ EXPORT_SYMBOL_GPL(regcache_sync);void regcache_cache_only (struct regmap *map,bool enable) {mutex_lock (&map->lock); +WARN_ON (map->cache_bypass && enable); map->cache_only = enable;mutex_unlock (&map->lock); }
@@ -300,6 +301,7 @@ EXPORT_SYMBOL_GPL(regcache_cache_only);void regcache_cache_bypass (struct regmap *map,bool enable) {mutex_lock (&map->lock); +WARN_ON (map->cache_only && enable); map->cache_bypass = enable;mutex_unlock (&map->lock); }
Signature · 1 line
1.7.6.4
Mark Brown
AppliedQuoted 1 line · Dimitris Papastamos
Signed-off-by Dimitris Papastamos <[email protected]>
Applied all, thanks.
If you're finding your commit subjects are getting as long as this one you really should be writing a longer commit body rather than trying to squeeze everything into the subject.