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>
This commit is contained in:
Родитель
f722406faa
Коммит
697e85bc6a
|
@ -148,6 +148,7 @@ struct regcache_ops {
|
||||||
int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
|
int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
|
||||||
int (*write)(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 (*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);
|
bool regmap_writeable(struct regmap *map, unsigned int reg);
|
||||||
|
|
|
@ -358,6 +358,43 @@ out:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regcache_sync_region);
|
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
|
* regcache_cache_only: Put a register map into cache only mode
|
||||||
*
|
*
|
||||||
|
|
|
@ -394,6 +394,8 @@ bool regmap_can_raw_write(struct regmap *map);
|
||||||
int regcache_sync(struct regmap *map);
|
int regcache_sync(struct regmap *map);
|
||||||
int regcache_sync_region(struct regmap *map, unsigned int min,
|
int regcache_sync_region(struct regmap *map, unsigned int min,
|
||||||
unsigned int max);
|
unsigned int max);
|
||||||
|
int regcache_drop_region(struct regmap *map, unsigned int min,
|
||||||
|
unsigned int max);
|
||||||
void regcache_cache_only(struct regmap *map, bool enable);
|
void regcache_cache_only(struct regmap *map, bool enable);
|
||||||
void regcache_cache_bypass(struct regmap *map, bool enable);
|
void regcache_cache_bypass(struct regmap *map, bool enable);
|
||||||
void regcache_mark_dirty(struct regmap *map);
|
void regcache_mark_dirty(struct regmap *map);
|
||||||
|
@ -562,6 +564,13 @@ static inline int regcache_sync_region(struct regmap *map, unsigned int min,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int regcache_drop_region(struct regmap *map, unsigned int min,
|
||||||
|
unsigned int max)
|
||||||
|
{
|
||||||
|
WARN_ONCE(1, "regmap API is disabled");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void regcache_cache_only(struct regmap *map, bool enable)
|
static inline void regcache_cache_only(struct regmap *map, bool enable)
|
||||||
{
|
{
|
||||||
WARN_ONCE(1, "regmap API is disabled");
|
WARN_ONCE(1, "regmap API is disabled");
|
||||||
|
|
|
@ -223,6 +223,29 @@ DEFINE_EVENT(regmap_async, regmap_async_complete_done,
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(regcache_drop_region,
|
||||||
|
|
||||||
|
TP_PROTO(struct device *dev, unsigned int from,
|
||||||
|
unsigned int to),
|
||||||
|
|
||||||
|
TP_ARGS(dev, from, to),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__string( name, dev_name(dev) )
|
||||||
|
__field( unsigned int, from )
|
||||||
|
__field( unsigned int, to )
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__assign_str(name, dev_name(dev));
|
||||||
|
__entry->from = from;
|
||||||
|
__entry->to = to;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("%s %u-%u", __get_str(name), (unsigned int)__entry->from,
|
||||||
|
(unsigned int)__entry->to)
|
||||||
|
);
|
||||||
|
|
||||||
#endif /* _TRACE_REGMAP_H */
|
#endif /* _TRACE_REGMAP_H */
|
||||||
|
|
||||||
/* This part must be outside protection */
|
/* This part must be outside protection */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче