diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 02ed1546da21..7d4dc11ad86c 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -17,6 +17,9 @@ #include +#define CREATE_TRACE_POINTS +#include + struct regmap; struct regmap_format { @@ -211,6 +214,9 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, map->format.format_reg(map->work_buf, reg); + trace_regmap_hw_write_start(map->dev, 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 * write. @@ -237,19 +243,31 @@ static 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); + return ret; } static int _regmap_write(struct regmap *map, unsigned int reg, unsigned int val) { + int ret; BUG_ON(!map->format.format_write && !map->format.format_val); + trace_regmap_reg_write(map->dev, reg, val); + if (map->format.format_write) { map->format.format_write(map, reg, val); - return map->bus->write(map->dev, map->work_buf, - map->format.buf_size); + trace_regmap_hw_write_start(map->dev, reg, 1); + + ret = map->bus->write(map->dev, map->work_buf, + map->format.buf_size); + + trace_regmap_hw_write_done(map->dev, reg, 1); + + return ret; } else { map->format.format_val(map->work_buf + map->format.reg_bytes, val); @@ -331,12 +349,16 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, if (map->bus->read_flag_mask) u8[0] |= map->bus->read_flag_mask; + trace_regmap_hw_read_start(map->dev, reg, + val_len / map->format.val_bytes); + ret = map->bus->read(map->dev, map->work_buf, map->format.reg_bytes, val, val_len); - if (ret != 0) - return ret; - return 0; + trace_regmap_hw_read_done(map->dev, reg, + val_len / map->format.val_bytes); + + return ret; } static int _regmap_read(struct regmap *map, unsigned int reg, @@ -348,8 +370,10 @@ static int _regmap_read(struct regmap *map, unsigned int reg, return -EINVAL; ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); - if (ret == 0) + if (ret == 0) { *val = map->format.parse_val(map->work_buf); + trace_regmap_reg_read(map->dev, reg, *val); + } return ret; } diff --git a/include/trace/events/regmap.h b/include/trace/events/regmap.h new file mode 100644 index 000000000000..1c76f40dee44 --- /dev/null +++ b/include/trace/events/regmap.h @@ -0,0 +1,112 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM regmap + +#if !defined(_TRACE_REGMAP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_REGMAP_H + +#include +#include +#include + +struct regmap; + +/* + * Log register events + */ +DECLARE_EVENT_CLASS(regmap_reg, + + TP_PROTO(struct device *dev, unsigned int reg, + unsigned int val), + + TP_ARGS(dev, reg, val), + + TP_STRUCT__entry( + __string( name, dev_name(dev) ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, dev_name(dev)); + __entry->reg = reg; + __entry->val = val; + ), + + TP_printk("%s reg=%x val=%x", __get_str(name), + (unsigned int)__entry->reg, + (unsigned int)__entry->val) +); + +DEFINE_EVENT(regmap_reg, regmap_reg_write, + + TP_PROTO(struct device *dev, unsigned int reg, + unsigned int val), + + TP_ARGS(dev, reg, val) + +); + +DEFINE_EVENT(regmap_reg, regmap_reg_read, + + TP_PROTO(struct device *dev, unsigned int reg, + unsigned int val), + + TP_ARGS(dev, reg, val) + +); + +DECLARE_EVENT_CLASS(regmap_block, + + TP_PROTO(struct device *dev, unsigned int reg, size_t count), + + TP_ARGS(dev, reg, count), + + TP_STRUCT__entry( + __string( name, dev_name(dev) ) + __field( unsigned int, reg ) + __field( size_t, count ) + ), + + TP_fast_assign( + __assign_str(name, dev_name(dev)); + __entry->reg = reg; + __entry->count = count; + ), + + TP_printk("%s reg=%x count=%d", __get_str(name), + (unsigned int)__entry->reg, + (size_t)__entry->count) +); + +DEFINE_EVENT(regmap_block, regmap_hw_read_start, + + TP_PROTO(struct device *dev, unsigned int reg, size_t count), + + TP_ARGS(dev, reg, count) +); + +DEFINE_EVENT(regmap_block, regmap_hw_read_done, + + TP_PROTO(struct device *dev, unsigned int reg, size_t count), + + TP_ARGS(dev, reg, count) +); + +DEFINE_EVENT(regmap_block, regmap_hw_write_start, + + TP_PROTO(struct device *dev, unsigned int reg, size_t count), + + TP_ARGS(dev, reg, count) +); + +DEFINE_EVENT(regmap_block, regmap_hw_write_done, + + TP_PROTO(struct device *dev, unsigned int reg, size_t count), + + TP_ARGS(dev, reg, count) +); + +#endif /* _TRACE_REGMAP_H */ + +/* This part must be outside protection */ +#include