diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-12-12 11:10:45 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-12-12 11:10:45 -0500 |
commit | 4412823a0ac768679c0f31bd9585ebc23b317138 (patch) | |
tree | ef45db21145ae9bb0f746f99939061cf96a4b116 | |
parent | 01ed260f22c429337272bf9d25d393a4efd37d51 (diff) | |
parent | bf315173359b2f3b8b8ccca4264815e91f30be12 (diff) |
Merge branch 'topic/cache' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into HEAD
-rw-r--r-- | drivers/base/regmap/internal.h | 1 | ||||
-rw-r--r-- | drivers/base/regmap/regcache-lzo.c | 2 | ||||
-rw-r--r-- | drivers/base/regmap/regcache.c | 19 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 37 | ||||
-rw-r--r-- | include/linux/regmap.h | 5 |
5 files changed, 61 insertions, 3 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 | ||
79 | struct regcache_ops { | 80 | struct regcache_ops { |
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c index 066aeece3626..854448d09293 100644 --- a/drivers/base/regmap/regcache-lzo.c +++ b/drivers/base/regmap/regcache-lzo.c | |||
@@ -351,7 +351,7 @@ static int regcache_lzo_sync(struct regmap *map) | |||
351 | } | 351 | } |
352 | 352 | ||
353 | struct regcache_ops regcache_lzo_ops = { | 353 | struct regcache_ops regcache_lzo_ops = { |
354 | .type = REGCACHE_LZO, | 354 | .type = REGCACHE_COMPRESSED, |
355 | .name = "lzo", | 355 | .name = "lzo", |
356 | .init = regcache_lzo_init, | 356 | .init = regcache_lzo_init, |
357 | .exit = regcache_lzo_exit, | 357 | .exit = regcache_lzo_exit, |
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) | |||
291 | EXPORT_SYMBOL_GPL(regcache_cache_only); | 293 | EXPORT_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 | */ | ||
304 | void regcache_mark_dirty(struct regmap *map) | ||
305 | { | ||
306 | mutex_lock(&map->lock); | ||
307 | map->cache_dirty = true; | ||
308 | mutex_unlock(&map->lock); | ||
309 | } | ||
310 | EXPORT_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..579e85b8a684 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -231,6 +231,39 @@ err: | |||
231 | EXPORT_SYMBOL_GPL(regmap_init); | 231 | EXPORT_SYMBOL_GPL(regmap_init); |
232 | 232 | ||
233 | /** | 233 | /** |
234 | * regmap_reinit_cache(): Reinitialise the current register cache | ||
235 | * | ||
236 | * @map: Register map to operate on. | ||
237 | * @config: New configuration. Only the cache data will be used. | ||
238 | * | ||
239 | * Discard any existing register cache for the map and initialize a | ||
240 | * new cache. This can be used to restore the cache to defaults or to | ||
241 | * update the cache configuration to reflect runtime discovery of the | ||
242 | * hardware. | ||
243 | */ | ||
244 | int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) | ||
245 | { | ||
246 | int ret; | ||
247 | |||
248 | mutex_lock(&map->lock); | ||
249 | |||
250 | regcache_exit(map); | ||
251 | |||
252 | map->max_register = config->max_register; | ||
253 | map->writeable_reg = config->writeable_reg; | ||
254 | map->readable_reg = config->readable_reg; | ||
255 | map->volatile_reg = config->volatile_reg; | ||
256 | map->precious_reg = config->precious_reg; | ||
257 | map->cache_type = config->cache_type; | ||
258 | |||
259 | ret = regcache_init(map, config); | ||
260 | |||
261 | mutex_unlock(&map->lock); | ||
262 | |||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | /** | ||
234 | * regmap_exit(): Free a previously allocated register map | 267 | * regmap_exit(): Free a previously allocated register map |
235 | */ | 268 | */ |
236 | void regmap_exit(struct regmap *map) | 269 | void regmap_exit(struct regmap *map) |
@@ -306,8 +339,10 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
306 | ret = regcache_write(map, reg, val); | 339 | ret = regcache_write(map, reg, val); |
307 | if (ret != 0) | 340 | if (ret != 0) |
308 | return ret; | 341 | return ret; |
309 | if (map->cache_only) | 342 | if (map->cache_only) { |
343 | map->cache_dirty = true; | ||
310 | return 0; | 344 | return 0; |
345 | } | ||
311 | } | 346 | } |
312 | 347 | ||
313 | trace_regmap_reg_write(map->dev, reg, val); | 348 | trace_regmap_reg_write(map->dev, reg, val); |
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 690276a642cf..86923a98a766 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
@@ -25,7 +25,7 @@ enum regcache_type { | |||
25 | REGCACHE_NONE, | 25 | REGCACHE_NONE, |
26 | REGCACHE_INDEXED, | 26 | REGCACHE_INDEXED, |
27 | REGCACHE_RBTREE, | 27 | REGCACHE_RBTREE, |
28 | REGCACHE_LZO | 28 | REGCACHE_COMPRESSED |
29 | }; | 29 | }; |
30 | 30 | ||
31 | /** | 31 | /** |
@@ -129,6 +129,8 @@ struct regmap *regmap_init_spi(struct spi_device *dev, | |||
129 | const struct regmap_config *config); | 129 | const struct regmap_config *config); |
130 | 130 | ||
131 | void regmap_exit(struct regmap *map); | 131 | void regmap_exit(struct regmap *map); |
132 | int regmap_reinit_cache(struct regmap *map, | ||
133 | const struct regmap_config *config); | ||
132 | int regmap_write(struct regmap *map, unsigned int reg, unsigned int val); | 134 | int regmap_write(struct regmap *map, unsigned int reg, unsigned int val); |
133 | int regmap_raw_write(struct regmap *map, unsigned int reg, | 135 | int regmap_raw_write(struct regmap *map, unsigned int reg, |
134 | const void *val, size_t val_len); | 136 | const void *val, size_t val_len); |
@@ -143,5 +145,6 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, | |||
143 | int regcache_sync(struct regmap *map); | 145 | int regcache_sync(struct regmap *map); |
144 | void regcache_cache_only(struct regmap *map, bool enable); | 146 | void regcache_cache_only(struct regmap *map, bool enable); |
145 | void regcache_cache_bypass(struct regmap *map, bool enable); | 147 | void regcache_cache_bypass(struct regmap *map, bool enable); |
148 | void regcache_mark_dirty(struct regmap *map); | ||
146 | 149 | ||
147 | #endif | 150 | #endif |