diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-05-08 08:55:22 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-05-12 10:46:47 -0400 |
commit | 697e85bc6a9aa44ecd73392586fe9cfd7e0467ba (patch) | |
tree | c07e5c212d9eed90f1d80bc5b923755a5f6888ea | |
parent | f722406faae2d073cc1d01063d1123c35425939e (diff) |
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>
-rw-r--r-- | drivers/base/regmap/internal.h | 1 | ||||
-rw-r--r-- | drivers/base/regmap/regcache.c | 37 | ||||
-rw-r--r-- | include/linux/regmap.h | 9 | ||||
-rw-r--r-- | include/trace/events/regmap.h | 23 |
4 files changed, 70 insertions, 0 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index c130536e0ab0..b33a4ff67adf 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
@@ -148,6 +148,7 @@ struct regcache_ops { | |||
148 | int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); | 148 | int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); |
149 | int (*write)(struct regmap *map, unsigned int reg, unsigned int value); | 149 | int (*write)(struct regmap *map, unsigned int reg, unsigned int value); |
150 | int (*sync)(struct regmap *map, unsigned int min, unsigned int max); | 150 | int (*sync)(struct regmap *map, unsigned int min, unsigned int max); |
151 | int (*drop)(struct regmap *map, unsigned int min, unsigned int max); | ||
151 | }; | 152 | }; |
152 | 153 | ||
153 | bool regmap_writeable(struct regmap *map, unsigned int reg); | 154 | bool regmap_writeable(struct regmap *map, unsigned int reg); |
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 75923f2396bd..8a0ab5fa75f5 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c | |||
@@ -359,6 +359,43 @@ out: | |||
359 | EXPORT_SYMBOL_GPL(regcache_sync_region); | 359 | EXPORT_SYMBOL_GPL(regcache_sync_region); |
360 | 360 | ||
361 | /** | 361 | /** |
362 | * regcache_drop_region: Discard part of the register cache | ||
363 | * | ||
364 | * @map: map to operate on | ||
365 | * @min: first register to discard | ||
366 | * @max: last register to discard | ||
367 | * | ||
368 | * Discard part of the register cache. | ||
369 | * | ||
370 | * Return a negative value on failure, 0 on success. | ||
371 | */ | ||
372 | int regcache_drop_region(struct regmap *map, unsigned int min, | ||
373 | unsigned int max) | ||
374 | { | ||
375 | unsigned int reg; | ||
376 | int ret = 0; | ||
377 | |||
378 | if (!map->cache_present && !(map->cache_ops && map->cache_ops->drop)) | ||
379 | return -EINVAL; | ||
380 | |||
381 | map->lock(map); | ||
382 | |||
383 | trace_regcache_drop_region(map->dev, min, max); | ||
384 | |||
385 | if (map->cache_present) | ||
386 | for (reg = min; reg < max + 1; reg++) | ||
387 | clear_bit(reg, map->cache_present); | ||
388 | |||
389 | if (map->cache_ops && map->cache_ops->drop) | ||
390 | ret = map->cache_ops->drop(map, min, max); | ||
391 | |||
392 | map->unlock(map); | ||
393 | |||
394 | return ret; | ||
395 | } | ||
396 | EXPORT_SYMBOL_GPL(regcache_drop_region); | ||
397 | |||
398 | /** | ||
362 | * regcache_cache_only: Put a register map into cache only mode | 399 | * regcache_cache_only: Put a register map into cache only mode |
363 | * | 400 | * |
364 | * @map: map to configure | 401 | * @map: map to configure |
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 02d84e24b7c2..5067ee94eb92 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
@@ -394,6 +394,8 @@ bool regmap_can_raw_write(struct regmap *map); | |||
394 | int regcache_sync(struct regmap *map); | 394 | int regcache_sync(struct regmap *map); |
395 | int regcache_sync_region(struct regmap *map, unsigned int min, | 395 | int regcache_sync_region(struct regmap *map, unsigned int min, |
396 | unsigned int max); | 396 | unsigned int max); |
397 | int regcache_drop_region(struct regmap *map, unsigned int min, | ||
398 | unsigned int max); | ||
397 | void regcache_cache_only(struct regmap *map, bool enable); | 399 | void regcache_cache_only(struct regmap *map, bool enable); |
398 | void regcache_cache_bypass(struct regmap *map, bool enable); | 400 | void regcache_cache_bypass(struct regmap *map, bool enable); |
399 | void regcache_mark_dirty(struct regmap *map); | 401 | void regcache_mark_dirty(struct regmap *map); |
@@ -562,6 +564,13 @@ static inline int regcache_sync_region(struct regmap *map, unsigned int min, | |||
562 | return -EINVAL; | 564 | return -EINVAL; |
563 | } | 565 | } |
564 | 566 | ||
567 | static inline int regcache_drop_region(struct regmap *map, unsigned int min, | ||
568 | unsigned int max) | ||
569 | { | ||
570 | WARN_ONCE(1, "regmap API is disabled"); | ||
571 | return -EINVAL; | ||
572 | } | ||
573 | |||
565 | static inline void regcache_cache_only(struct regmap *map, bool enable) | 574 | static inline void regcache_cache_only(struct regmap *map, bool enable) |
566 | { | 575 | { |
567 | WARN_ONCE(1, "regmap API is disabled"); | 576 | WARN_ONCE(1, "regmap API is disabled"); |
diff --git a/include/trace/events/regmap.h b/include/trace/events/regmap.h index a43a2f67bd8e..23d561512f64 100644 --- a/include/trace/events/regmap.h +++ b/include/trace/events/regmap.h | |||
@@ -223,6 +223,29 @@ DEFINE_EVENT(regmap_async, regmap_async_complete_done, | |||
223 | 223 | ||
224 | ); | 224 | ); |
225 | 225 | ||
226 | TRACE_EVENT(regcache_drop_region, | ||
227 | |||
228 | TP_PROTO(struct device *dev, unsigned int from, | ||
229 | unsigned int to), | ||
230 | |||
231 | TP_ARGS(dev, from, to), | ||
232 | |||
233 | TP_STRUCT__entry( | ||
234 | __string( name, dev_name(dev) ) | ||
235 | __field( unsigned int, from ) | ||
236 | __field( unsigned int, to ) | ||
237 | ), | ||
238 | |||
239 | TP_fast_assign( | ||
240 | __assign_str(name, dev_name(dev)); | ||
241 | __entry->from = from; | ||
242 | __entry->to = to; | ||
243 | ), | ||
244 | |||
245 | TP_printk("%s %u-%u", __get_str(name), (unsigned int)__entry->from, | ||
246 | (unsigned int)__entry->to) | ||
247 | ); | ||
248 | |||
226 | #endif /* _TRACE_REGMAP_H */ | 249 | #endif /* _TRACE_REGMAP_H */ |
227 | 250 | ||
228 | /* This part must be outside protection */ | 251 | /* This part must be outside protection */ |