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

Commit 0f70c6b8 authored by Amit Nischal's avatar Amit Nischal
Browse files

clk: Add support to dump state of all clocks into ftrace



Add clk_state event to record the state of all the clocks
into ftrace. The clock event could be triggered by using
the "trace_clocks" debugfs entry and it would dump the
current state of all clocks in ftrace logs.

Change-Id: I28b6574fe1d96472833a93e7b251dbba6c6eae49
Signed-off-by: default avatarAmit Nischal <anischal@codeaurora.org>
parent 1ccabf65
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -2326,6 +2326,56 @@ static struct hlist_head *orphan_list[] = {
	NULL,
};

static void clk_state_subtree(struct clk_core *c)
{
	int vdd_level = 0;
	struct clk_core *child;

	if (!c)
		return;

	if (c->vdd_class) {
		vdd_level = clk_find_vdd_level(c, c->rate);
		if (vdd_level < 0)
			vdd_level = 0;
	}

	trace_clk_state(c->name, c->prepare_count, c->enable_count,
						c->rate, vdd_level);

	hlist_for_each_entry(child, &c->children, child_node)
		clk_state_subtree(child);
}

static int clk_state_show(struct seq_file *s, void *data)
{
	struct clk_core *c;
	struct hlist_head **lists = (struct hlist_head **)s->private;

	clk_prepare_lock();

	for (; *lists; lists++)
		hlist_for_each_entry(c, *lists, child_node)
			clk_state_subtree(c);

	clk_prepare_unlock();

	return 0;
}


static int clk_state_open(struct inode *inode, struct file *file)
{
	return single_open(file, clk_state_show, inode->i_private);
}

static const struct file_operations clk_state_fops = {
	.open		= clk_state_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
				 int level)
{
@@ -3002,6 +3052,11 @@ static int __init clk_debug_init(void)
	if (!d)
		return -ENOMEM;

	d = debugfs_create_file("trace_clocks", S_IRUGO, rootdir, &all_lists,
				&clk_state_fops);
	if (!d)
		return -ENOMEM;

	mutex_lock(&clk_debug_lock);
	hlist_for_each_entry(core, &clk_debug_list, debug_node)
		clk_debug_create_one(core, rootdir);
+37 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -192,6 +192,42 @@ DEFINE_EVENT(clk_phase, clk_set_phase_complete,
	TP_ARGS(core, phase)
);

DECLARE_EVENT_CLASS(clk_state_dump,

	TP_PROTO(const char *name, unsigned int prepare_count,
	unsigned int enable_count, unsigned long rate, unsigned int vdd_level),

	TP_ARGS(name, prepare_count, enable_count, rate, vdd_level),

	TP_STRUCT__entry(
		__string(name,			name)
		__field(unsigned int,		prepare_count)
		__field(unsigned int,		enable_count)
		__field(unsigned long,		rate)
		__field(unsigned int,		vdd_level)
	),

	TP_fast_assign(
		__assign_str(name, name);
		__entry->prepare_count = prepare_count;
		__entry->enable_count = enable_count;
		__entry->rate = rate;
		__entry->vdd_level = vdd_level;
	),

	TP_printk("%s\tprepare:enable cnt [%u:%u]\trate: vdd_level [%lu:%u]",
		__get_str(name), __entry->prepare_count, __entry->enable_count,
		__entry->rate, __entry->vdd_level)
);

DEFINE_EVENT(clk_state_dump, clk_state,

	TP_PROTO(const char *name, unsigned int prepare_count,
	unsigned int enable_count, unsigned long rate, unsigned int vdd_level),

	TP_ARGS(name, prepare_count, enable_count, rate, vdd_level)
);

#endif /* _TRACE_CLK_H */

/* This part must be outside protection */