diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-05-08 12:55:22 (GMT) |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-05-12 14:46:47 (GMT) |
commit | 697e85bc6a9aa44ecd73392586fe9cfd7e0467ba (patch) | |
tree | c07e5c212d9eed90f1d80bc5b923755a5f6888ea /drivers/base | |
parent | f722406faae2d073cc1d01063d1123c35425939e (diff) | |
download | linux-697e85bc6a9aa44ecd73392586fe9cfd7e0467ba.tar.xz |
regmap: Add support for discarding parts of the register cache
Allow drivers to discard parts of the register cache, for example if part
of the hardware has been reset.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/regmap/internal.h | 1 | ||||
-rw-r--r-- | drivers/base/regmap/regcache.c | 37 |
2 files changed, 38 insertions, 0 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index c130536..b33a4ff 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -148,6 +148,7 @@ struct regcache_ops { int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); int (*write)(struct regmap *map, unsigned int reg, unsigned int value); int (*sync)(struct regmap *map, unsigned int min, unsigned int max); + int (*drop)(struct regmap *map, unsigned int min, unsigned int max); }; bool regmap_writeable(struct regmap *map, unsigned int reg); diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 75923f2..8a0ab5f 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -359,6 +359,43 @@ out: EXPORT_SYMBOL_GPL(regcache_sync_region); /** + * regcache_drop_region: Discard part of the register cache + * + * @map: map to operate on + * @min: first register to discard + * @max: last register to discard + * + * Discard part of the register cache. + * + * Return a negative value on failure, 0 on success. + */ +int regcache_drop_region(struct regmap *map, unsigned int min, + unsigned int max) +{ + unsigned int reg; + int ret = 0; + + if (!map->cache_present && !(map->cache_ops && map->cache_ops->drop)) + return -EINVAL; + + map->lock(map); + + trace_regcache_drop_region(map->dev, min, max); + + if (map->cache_present) + for (reg = min; reg < max + 1; reg++) + clear_bit(reg, map->cache_present); + + if (map->cache_ops && map->cache_ops->drop) + ret = map->cache_ops->drop(map, min, max); + + map->unlock(map); + + return ret; +} +EXPORT_SYMBOL_GPL(regcache_drop_region); + +/** * regcache_cache_only: Put a register map into cache only mode * * @map: map to configure |