Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 697e85bc authored by Mark Brown's avatar Mark Brown
Browse files

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: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent f722406f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+37 −0
Original line number Diff line number Diff line
@@ -358,6 +358,43 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
}
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
 *
+9 −0
Original line number Diff line number Diff line
@@ -394,6 +394,8 @@ bool regmap_can_raw_write(struct regmap *map);
int regcache_sync(struct regmap *map);
int regcache_sync_region(struct regmap *map, unsigned int min,
			 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_bypass(struct regmap *map, bool enable);
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;
}

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)
{
	WARN_ONCE(1, "regmap API is disabled");
+23 −0
Original line number Diff line number Diff line
@@ -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 */

/* This part must be outside protection */