Commit 7c90de34 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull regmap fix from Mark Brown:
 "This patch fixes a bad interaction between the support that was added
  for having regmaps without devices for early system controller
  initialization and the trace support.

  There's a very good analysis of the actual issue in the commit message
  for the change"

* tag 'regmap-fix-v4.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  regmap: introduce regmap_name to fix syscon regmap trace events
parents 90a5a895 c6b570d9
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -243,4 +243,12 @@ extern struct regcache_ops regcache_rbtree_ops;
extern struct regcache_ops regcache_lzo_ops;
extern struct regcache_ops regcache_flat_ops;

static inline const char *regmap_name(const struct regmap *map)
{
	if (map->dev)
		return dev_name(map->dev);

	return map->name;
}

#endif
+8 −8
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ int regcache_read(struct regmap *map,
		ret = map->cache_ops->read(map, reg, value);

		if (ret == 0)
			trace_regmap_reg_read_cache(map->dev, reg, *value);
			trace_regmap_reg_read_cache(map, reg, *value);

		return ret;
	}
@@ -311,7 +311,7 @@ int regcache_sync(struct regmap *map)
	dev_dbg(map->dev, "Syncing %s cache\n",
		map->cache_ops->name);
	name = map->cache_ops->name;
	trace_regcache_sync(map->dev, name, "start");
	trace_regcache_sync(map, name, "start");

	if (!map->cache_dirty)
		goto out;
@@ -346,7 +346,7 @@ out:

	regmap_async_complete(map);

	trace_regcache_sync(map->dev, name, "stop");
	trace_regcache_sync(map, name, "stop");

	return ret;
}
@@ -381,7 +381,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
	name = map->cache_ops->name;
	dev_dbg(map->dev, "Syncing %s cache from %d-%d\n", name, min, max);

	trace_regcache_sync(map->dev, name, "start region");
	trace_regcache_sync(map, name, "start region");

	if (!map->cache_dirty)
		goto out;
@@ -401,7 +401,7 @@ out:

	regmap_async_complete(map);

	trace_regcache_sync(map->dev, name, "stop region");
	trace_regcache_sync(map, name, "stop region");

	return ret;
}
@@ -428,7 +428,7 @@ int regcache_drop_region(struct regmap *map, unsigned int min,

	map->lock(map->lock_arg);

	trace_regcache_drop_region(map->dev, min, max);
	trace_regcache_drop_region(map, min, max);

	ret = map->cache_ops->drop(map, min, max);

@@ -455,7 +455,7 @@ void regcache_cache_only(struct regmap *map, bool enable)
	map->lock(map->lock_arg);
	WARN_ON(map->cache_bypass && enable);
	map->cache_only = enable;
	trace_regmap_cache_only(map->dev, enable);
	trace_regmap_cache_only(map, enable);
	map->unlock(map->lock_arg);
}
EXPORT_SYMBOL_GPL(regcache_cache_only);
@@ -493,7 +493,7 @@ void regcache_cache_bypass(struct regmap *map, bool enable)
	map->lock(map->lock_arg);
	WARN_ON(map->cache_only && enable);
	map->cache_bypass = enable;
	trace_regmap_cache_bypass(map->dev, enable);
	trace_regmap_cache_bypass(map, enable);
	map->unlock(map->lock_arg);
}
EXPORT_SYMBOL_GPL(regcache_cache_bypass);
+14 −18
Original line number Diff line number Diff line
@@ -1281,7 +1281,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
	if (map->async && map->bus->async_write) {
		struct regmap_async *async;

		trace_regmap_async_write_start(map->dev, reg, val_len);
		trace_regmap_async_write_start(map, reg, val_len);

		spin_lock_irqsave(&map->async_lock, flags);
		async = list_first_entry_or_null(&map->async_free,
@@ -1339,8 +1339,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
		return ret;
	}

	trace_regmap_hw_write_start(map->dev, reg,
				    val_len / map->format.val_bytes);
	trace_regmap_hw_write_start(map, reg, val_len / map->format.val_bytes);

	/* If we're doing a single register write we can probably just
	 * send the work_buf directly, otherwise try to do a gather
@@ -1372,8 +1371,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
		kfree(buf);
	}

	trace_regmap_hw_write_done(map->dev, reg,
				   val_len / map->format.val_bytes);
	trace_regmap_hw_write_done(map, reg, val_len / map->format.val_bytes);

	return ret;
}
@@ -1407,12 +1405,12 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,

	map->format.format_write(map, reg, val);

	trace_regmap_hw_write_start(map->dev, reg, 1);
	trace_regmap_hw_write_start(map, reg, 1);

	ret = map->bus->write(map->bus_context, map->work_buf,
			      map->format.buf_size);

	trace_regmap_hw_write_done(map->dev, reg, 1);
	trace_regmap_hw_write_done(map, reg, 1);

	return ret;
}
@@ -1470,7 +1468,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
		dev_info(map->dev, "%x <= %x\n", reg, val);
#endif

	trace_regmap_reg_write(map->dev, reg, val);
	trace_regmap_reg_write(map, reg, val);

	return map->reg_write(context, reg, val);
}
@@ -1773,7 +1771,7 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
	for (i = 0; i < num_regs; i++) {
		int reg = regs[i].reg;
		int val = regs[i].def;
		trace_regmap_hw_write_start(map->dev, reg, 1);
		trace_regmap_hw_write_start(map, reg, 1);
		map->format.format_reg(u8, reg, map->reg_shift);
		u8 += reg_bytes + pad_bytes;
		map->format.format_val(u8, val, 0);
@@ -1788,7 +1786,7 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,

	for (i = 0; i < num_regs; i++) {
		int reg = regs[i].reg;
		trace_regmap_hw_write_done(map->dev, reg, 1);
		trace_regmap_hw_write_done(map, reg, 1);
	}
	return ret;
}
@@ -2059,15 +2057,13 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
	 */
	u8[0] |= map->read_flag_mask;

	trace_regmap_hw_read_start(map->dev, reg,
				   val_len / map->format.val_bytes);
	trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);

	ret = map->bus->read(map->bus_context, map->work_buf,
			     map->format.reg_bytes + map->format.pad_bytes,
			     val, val_len);

	trace_regmap_hw_read_done(map->dev, reg,
				  val_len / map->format.val_bytes);
	trace_regmap_hw_read_done(map, reg, val_len / map->format.val_bytes);

	return ret;
}
@@ -2123,7 +2119,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
			dev_info(map->dev, "%x => %x\n", reg, *val);
#endif

		trace_regmap_reg_read(map->dev, reg, *val);
		trace_regmap_reg_read(map, reg, *val);

		if (!map->cache_bypass)
			regcache_write(map, reg, *val);
@@ -2480,7 +2476,7 @@ void regmap_async_complete_cb(struct regmap_async *async, int ret)
	struct regmap *map = async->map;
	bool wake;

	trace_regmap_async_io_complete(map->dev);
	trace_regmap_async_io_complete(map);

	spin_lock(&map->async_lock);
	list_move(&async->list, &map->async_free);
@@ -2525,7 +2521,7 @@ int regmap_async_complete(struct regmap *map)
	if (!map->bus || !map->bus->async_write)
		return 0;

	trace_regmap_async_complete_start(map->dev);
	trace_regmap_async_complete_start(map);

	wait_event(map->async_waitq, regmap_async_is_done(map));

@@ -2534,7 +2530,7 @@ int regmap_async_complete(struct regmap *map)
	map->async_ret = 0;
	spin_unlock_irqrestore(&map->async_lock, flags);

	trace_regmap_async_complete_done(map->dev);
	trace_regmap_async_complete_done(map);

	return ret;
}
+61 −62
Original line number Diff line number Diff line
@@ -7,27 +7,26 @@
#include <linux/ktime.h>
#include <linux/tracepoint.h>

struct device;
struct regmap;
#include "../../../drivers/base/regmap/internal.h"

/*
 * Log register events
 */
DECLARE_EVENT_CLASS(regmap_reg,

	TP_PROTO(struct device *dev, unsigned int reg,
	TP_PROTO(struct regmap *map, unsigned int reg,
		 unsigned int val),

	TP_ARGS(dev, reg, val),
	TP_ARGS(map, reg, val),

	TP_STRUCT__entry(
		__string(	name,		dev_name(dev)	)
		__string(	name,		regmap_name(map)	)
		__field(	unsigned int,	reg			)
		__field(	unsigned int,	val			)
	),

	TP_fast_assign(
		__assign_str(name, dev_name(dev));
		__assign_str(name, regmap_name(map));
		__entry->reg = reg;
		__entry->val = val;
	),
@@ -39,45 +38,45 @@ DECLARE_EVENT_CLASS(regmap_reg,

DEFINE_EVENT(regmap_reg, regmap_reg_write,

	TP_PROTO(struct device *dev, unsigned int reg,
	TP_PROTO(struct regmap *map, unsigned int reg,
		 unsigned int val),

	TP_ARGS(dev, reg, val)
	TP_ARGS(map, reg, val)

);

DEFINE_EVENT(regmap_reg, regmap_reg_read,

	TP_PROTO(struct device *dev, unsigned int reg,
	TP_PROTO(struct regmap *map, unsigned int reg,
		 unsigned int val),

	TP_ARGS(dev, reg, val)
	TP_ARGS(map, reg, val)

);

DEFINE_EVENT(regmap_reg, regmap_reg_read_cache,

	TP_PROTO(struct device *dev, unsigned int reg,
	TP_PROTO(struct regmap *map, unsigned int reg,
		 unsigned int val),

	TP_ARGS(dev, reg, val)
	TP_ARGS(map, reg, val)

);

DECLARE_EVENT_CLASS(regmap_block,

	TP_PROTO(struct device *dev, unsigned int reg, int count),
	TP_PROTO(struct regmap *map, unsigned int reg, int count),

	TP_ARGS(dev, reg, count),
	TP_ARGS(map, reg, count),

	TP_STRUCT__entry(
		__string(	name,		dev_name(dev)	)
		__string(	name,		regmap_name(map)	)
		__field(	unsigned int,	reg			)
		__field(	int,		count			)
	),

	TP_fast_assign(
		__assign_str(name, dev_name(dev));
		__assign_str(name, regmap_name(map));
		__entry->reg = reg;
		__entry->count = count;
	),
@@ -89,48 +88,48 @@ DECLARE_EVENT_CLASS(regmap_block,

DEFINE_EVENT(regmap_block, regmap_hw_read_start,

	TP_PROTO(struct device *dev, unsigned int reg, int count),
	TP_PROTO(struct regmap *map, unsigned int reg, int count),

	TP_ARGS(dev, reg, count)
	TP_ARGS(map, reg, count)
);

DEFINE_EVENT(regmap_block, regmap_hw_read_done,

	TP_PROTO(struct device *dev, unsigned int reg, int count),
	TP_PROTO(struct regmap *map, unsigned int reg, int count),

	TP_ARGS(dev, reg, count)
	TP_ARGS(map, reg, count)
);

DEFINE_EVENT(regmap_block, regmap_hw_write_start,

	TP_PROTO(struct device *dev, unsigned int reg, int count),
	TP_PROTO(struct regmap *map, unsigned int reg, int count),

	TP_ARGS(dev, reg, count)
	TP_ARGS(map, reg, count)
);

DEFINE_EVENT(regmap_block, regmap_hw_write_done,

	TP_PROTO(struct device *dev, unsigned int reg, int count),
	TP_PROTO(struct regmap *map, unsigned int reg, int count),

	TP_ARGS(dev, reg, count)
	TP_ARGS(map, reg, count)
);

TRACE_EVENT(regcache_sync,

	TP_PROTO(struct device *dev, const char *type,
	TP_PROTO(struct regmap *map, const char *type,
		 const char *status),

	TP_ARGS(dev, type, status),
	TP_ARGS(map, type, status),

	TP_STRUCT__entry(
		__string(       name,           dev_name(dev)   )
		__string(       name,           regmap_name(map)	)
		__string(	status,		status			)
		__string(	type,		type			)
		__field(	int,		type			)
	),

	TP_fast_assign(
		__assign_str(name, dev_name(dev));
		__assign_str(name, regmap_name(map));
		__assign_str(status, status);
		__assign_str(type, type);
	),
@@ -141,17 +140,17 @@ TRACE_EVENT(regcache_sync,

DECLARE_EVENT_CLASS(regmap_bool,

	TP_PROTO(struct device *dev, bool flag),
	TP_PROTO(struct regmap *map, bool flag),

	TP_ARGS(dev, flag),
	TP_ARGS(map, flag),

	TP_STRUCT__entry(
		__string(	name,		dev_name(dev)	)
		__string(	name,		regmap_name(map)	)
		__field(	int,		flag			)
	),

	TP_fast_assign(
		__assign_str(name, dev_name(dev));
		__assign_str(name, regmap_name(map));
		__entry->flag = flag;
	),

@@ -161,32 +160,32 @@ DECLARE_EVENT_CLASS(regmap_bool,

DEFINE_EVENT(regmap_bool, regmap_cache_only,

	TP_PROTO(struct device *dev, bool flag),
	TP_PROTO(struct regmap *map, bool flag),

	TP_ARGS(dev, flag)
	TP_ARGS(map, flag)

);

DEFINE_EVENT(regmap_bool, regmap_cache_bypass,

	TP_PROTO(struct device *dev, bool flag),
	TP_PROTO(struct regmap *map, bool flag),

	TP_ARGS(dev, flag)
	TP_ARGS(map, flag)

);

DECLARE_EVENT_CLASS(regmap_async,

	TP_PROTO(struct device *dev),
	TP_PROTO(struct regmap *map),

	TP_ARGS(dev),
	TP_ARGS(map),

	TP_STRUCT__entry(
		__string(	name,		dev_name(dev)	)
		__string(	name,		regmap_name(map)	)
	),

	TP_fast_assign(
		__assign_str(name, dev_name(dev));
		__assign_str(name, regmap_name(map));
	),

	TP_printk("%s", __get_str(name))
@@ -194,50 +193,50 @@ DECLARE_EVENT_CLASS(regmap_async,

DEFINE_EVENT(regmap_block, regmap_async_write_start,

	TP_PROTO(struct device *dev, unsigned int reg, int count),
	TP_PROTO(struct regmap *map, unsigned int reg, int count),

	TP_ARGS(dev, reg, count)
	TP_ARGS(map, reg, count)
);

DEFINE_EVENT(regmap_async, regmap_async_io_complete,

	TP_PROTO(struct device *dev),
	TP_PROTO(struct regmap *map),

	TP_ARGS(dev)
	TP_ARGS(map)

);

DEFINE_EVENT(regmap_async, regmap_async_complete_start,

	TP_PROTO(struct device *dev),
	TP_PROTO(struct regmap *map),

	TP_ARGS(dev)
	TP_ARGS(map)

);

DEFINE_EVENT(regmap_async, regmap_async_complete_done,

	TP_PROTO(struct device *dev),
	TP_PROTO(struct regmap *map),

	TP_ARGS(dev)
	TP_ARGS(map)

);

TRACE_EVENT(regcache_drop_region,

	TP_PROTO(struct device *dev, unsigned int from,
	TP_PROTO(struct regmap *map, unsigned int from,
		 unsigned int to),

	TP_ARGS(dev, from, to),
	TP_ARGS(map, from, to),

	TP_STRUCT__entry(
		__string(       name,           dev_name(dev)   )
		__string(       name,           regmap_name(map)	)
		__field(	unsigned int,	from			)
		__field(	unsigned int,	to			)
	),

	TP_fast_assign(
		__assign_str(name, dev_name(dev));
		__assign_str(name, regmap_name(map));
		__entry->from = from;
		__entry->to = to;
	),