[PATCH] Common clock: To list active consumers of clocks

From: Vishal Badole
Date: Tue Jun 21 2022 - 00:25:51 EST


This feature lists the name of clocks and their consumer devices.
Using this feature user can easily check which device is using a
perticular clock. Consumers without dev_id are listed as no_dev_id.

Co-developed-by: Chinmoy Ghosh <chinmoyghosh2001@xxxxxxxxx>
Signed-off-by: Chinmoy Ghosh <chinmoyghosh2001@xxxxxxxxx>
Co-developed-by: Mintu Patel <mintupatel89@xxxxxxxxx>
Signed-off-by: Mintu Patel <mintupatel89@xxxxxxxxx>
Acked-by: Vimal Kumar <vimal.kumar32@xxxxxxxxx>
Signed-off-by: Vishal Badole <badolevishal1116@xxxxxxxxx>
---
drivers/clk/clk.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index ed11918..b191009 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3018,6 +3018,63 @@ static int clk_summary_show(struct seq_file *s, void *data)
}
DEFINE_SHOW_ATTRIBUTE(clk_summary);

+static void clk_consumer_show_one(struct seq_file *s, struct clk_core *core, int level)
+{
+ struct clk *clk_user;
+ const char *consumer;
+
+ hlist_for_each_entry(clk_user, &core->clks, clks_node) {
+ if (!clk_user->dev_id)
+ consumer = "no_dev_id";
+ else
+ consumer = clk_user->dev_id;
+
+ seq_printf(s, "%*s%-*s %30s %5d %7d ",
+ level * 3 + 1, "",
+ 30 - level * 3, clk_user->core->name, consumer,
+ clk_user->core->enable_count, clk_user->core->prepare_count);
+
+ if (clk_user->core->ops->is_enabled)
+ seq_printf(s, " %8c\n", clk_core_is_enabled(clk_user->core) ? 'Y' : 'N');
+ else if (!clk_user->core->ops->enable)
+ seq_printf(s, " %8c\n", 'Y');
+ else
+ seq_printf(s, " %8c\n", '?');
+ }
+}
+
+static void clk_consumer_show_subtree(struct seq_file *s, struct clk_core *c, int level)
+{
+ struct clk_core *child;
+
+ clk_consumer_show_one(s, c, level);
+
+ hlist_for_each_entry(child, &c->children, child_node)
+ clk_consumer_show_subtree(s, child, level + 1);
+}
+
+static int clk_consumer_show(struct seq_file *s, void *data)
+{
+ struct clk_core *c;
+ struct hlist_head **lists = (struct hlist_head **)s->private;
+
+ seq_puts(s, " enable prepare hardware\n");
+ seq_puts(s, " clock consumer count count enable\n");
+ seq_puts(s, "-----------------------------------------------------------------------------------------\n");
+ clk_prepare_lock();
+
+ /*Traversing Linked List to print clock consumer*/
+
+ for (; *lists; lists++)
+ hlist_for_each_entry(c, *lists, child_node)
+ clk_consumer_show_subtree(s, c, 0);
+
+ clk_prepare_unlock();
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_consumer);
+
static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
{
int phase;
@@ -3437,6 +3494,8 @@ static int __init clk_debug_init(void)
&clk_summary_fops);
debugfs_create_file("clk_orphan_dump", 0444, rootdir, &orphan_list,
&clk_dump_fops);
+ debugfs_create_file("clk_consumer", 0444, rootdir, &all_lists,
+ &clk_consumer_fops);

mutex_lock(&clk_debug_lock);
hlist_for_each_entry(core, &clk_debug_list, debug_node)
--
2.7.4