linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] clk: Move debugfs to a loadable kernel module
@ 2025-01-08  0:58 Stephen Boyd
  2025-01-08  0:58 ` [PATCH 1/4] clk: Prepare clk_debug_create_one() to be split off Stephen Boyd
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Stephen Boyd @ 2025-01-08  0:58 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-kernel, linux-clk, patches

This series moves as much of the debugfs code as possible from the core
clk framework file clk.c into a loadable kernel module. The goal is to
move the debugfs code out of the primary vmlinux and allow users to
decide if they want to load the debugging logic at all. To get there, we
make the debugfs code use struct clk_hw and then add a bunch of helpers
to interrogate the clk_hw enough to satisfy the use-cases we have in
debugfs today. Finally we move the code from clk.c to clk-debug.c almost
wholesale, except for some tree walking logic and functions to
interrogate a struct clk_hw or install a function pointer to call when a
clk is registered.

I'll probably wait to merge this until after we're able to limit the
exporting of kernel symbols to particular modules, because I'm not super
excited with exporting internal clk details to any module. For now, I've
put the symbols that are newly introduced for debugfs into the
"clk-debug" namespace.

Stephen Boyd (4):
  clk: Prepare clk_debug_create_one() to be split off
  clk: Use struct clk_hw instead of struct clk_core for debugfs
  clk: Iterate instead of recurse for debugfs printing
  clk: Make debugfs code into a loadable kernel module

 drivers/clk/Kconfig     |   8 +
 drivers/clk/Makefile    |   1 +
 drivers/clk/clk-debug.c | 529 ++++++++++++++++++++++++++++++++
 drivers/clk/clk-debug.h |  33 ++
 drivers/clk/clk.c       | 646 ++++++++++++----------------------------
 5 files changed, 763 insertions(+), 454 deletions(-)
 create mode 100644 drivers/clk/clk-debug.c
 create mode 100644 drivers/clk/clk-debug.h


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] clk: Prepare clk_debug_create_one() to be split off
  2025-01-08  0:58 [PATCH 0/4] clk: Move debugfs to a loadable kernel module Stephen Boyd
@ 2025-01-08  0:58 ` Stephen Boyd
  2025-01-08  0:58 ` [PATCH 2/4] clk: Use struct clk_hw instead of struct clk_core for debugfs Stephen Boyd
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Stephen Boyd @ 2025-01-08  0:58 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-kernel, linux-clk, patches

In a later patch we're going to move clk_debug_create_one() to a
loadable kernel module. Prepare for that step by returning the dentry
created in there from the function and wrap that all up in a new
function, clk_core_debug_create_one(), that we can call in both places
the dentry is created. Similarly, don't pass the 'pdentry' argument to
clk_debug_create_one() because it's always the global 'rootdir', so just
use that where it is used instead of passing it. We can remove the NULL
checks too because we know the pointers are always valid.

Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/clk.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index bdc6e5b90da5..1a94a27194c9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3705,14 +3705,11 @@ static int clk_max_rate_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(clk_max_rate);
 
-static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
+static struct dentry *clk_debug_create_one(struct clk_core *core)
 {
 	struct dentry *root;
 
-	if (!core || !pdentry)
-		return;
-
-	root = debugfs_create_dir(core->name, pdentry);
+	root = debugfs_create_dir(core->name, rootdir);
 	core->dentry = root;
 
 	debugfs_create_file("clk_rate", clk_rate_mode, root, core,
@@ -3746,8 +3743,19 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
 		debugfs_create_file("clk_possible_parents", 0444, root, core,
 				    &possible_parents_fops);
 
+	return root;
+}
+
+static void clk_core_debug_create_one(struct clk_core *core)
+{
+	struct clk_hw *hw = core->hw;
+
+	if (!inited)
+		return;
+
+	core->dentry = clk_debug_create_one(core);
 	if (core->ops->debug_init)
-		core->ops->debug_init(core->hw, core->dentry);
+		core->ops->debug_init(hw, core->dentry);
 }
 
 /**
@@ -3762,8 +3770,7 @@ static void clk_debug_register(struct clk_core *core)
 {
 	mutex_lock(&clk_debug_lock);
 	hlist_add_head(&core->debug_node, &clk_debug_list);
-	if (inited)
-		clk_debug_create_one(core, rootdir);
+	clk_core_debug_create_one(core);
 	mutex_unlock(&clk_debug_lock);
 }
 
@@ -3827,10 +3834,9 @@ static int __init clk_debug_init(void)
 			    &clk_dump_fops);
 
 	mutex_lock(&clk_debug_lock);
-	hlist_for_each_entry(core, &clk_debug_list, debug_node)
-		clk_debug_create_one(core, rootdir);
-
 	inited = 1;
+	hlist_for_each_entry(core, &clk_debug_list, debug_node)
+		clk_core_debug_create_one(core);
 	mutex_unlock(&clk_debug_lock);
 
 	return 0;
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/4] clk: Use struct clk_hw instead of struct clk_core for debugfs
  2025-01-08  0:58 [PATCH 0/4] clk: Move debugfs to a loadable kernel module Stephen Boyd
  2025-01-08  0:58 ` [PATCH 1/4] clk: Prepare clk_debug_create_one() to be split off Stephen Boyd
@ 2025-01-08  0:58 ` Stephen Boyd
  2025-01-08  0:58 ` [PATCH 3/4] clk: Iterate instead of recurse for debugfs printing Stephen Boyd
  2025-01-08  0:58 ` [PATCH 4/4] clk: Make debugfs code into a loadable kernel module Stephen Boyd
  3 siblings, 0 replies; 8+ messages in thread
From: Stephen Boyd @ 2025-01-08  0:58 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-kernel, linux-clk, patches

The clk debugfs code uses struct clk_core because it is part of the core
framework file where the struct isn't opaque. Introduce helpers that use
struct clk_hw and use them in the clk debugfs code so that a later patch
can split out the clk debugfs code to a loadable kernel module while
keeping struct clk_core opaque.

Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/clk.c | 412 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 294 insertions(+), 118 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 1a94a27194c9..e2f8fcbc1d4f 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -818,6 +818,14 @@ void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
 }
 EXPORT_SYMBOL_GPL(clk_hw_get_rate_range);
 
+static void clk_debug_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
+				     unsigned long *max_rate)
+{
+	clk_prepare_lock();
+	clk_hw_get_rate_range(hw, min_rate, max_rate);
+	clk_prepare_unlock();
+}
+
 static bool clk_core_check_boundaries(struct clk_core *core,
 				      unsigned long min_rate,
 				      unsigned long max_rate)
@@ -1897,6 +1905,11 @@ static long clk_core_get_accuracy_recalc(struct clk_core *core)
 	return clk_core_get_accuracy_no_lock(core);
 }
 
+static long clk_hw_get_accuracy_recalc(struct clk_hw *hw)
+{
+	return clk_core_get_accuracy_recalc(hw->core);
+}
+
 /**
  * clk_get_accuracy - return the accuracy of clk
  * @clk: the clk whose accuracy is being returned
@@ -1983,6 +1996,11 @@ static unsigned long clk_core_get_rate_recalc(struct clk_core *core)
 	return clk_core_get_rate_nolock(core);
 }
 
+static unsigned long clk_hw_get_rate_recalc(struct clk_hw *hw)
+{
+	return clk_core_get_rate_recalc(hw->core);
+}
+
 /**
  * clk_get_rate - return the rate of clk
  * @clk: the clk whose rate is being returned
@@ -3059,6 +3077,11 @@ static int clk_core_get_phase(struct clk_core *core)
 	return ret;
 }
 
+static int clk_hw_get_phase(struct clk_hw *hw)
+{
+	return clk_core_get_phase(hw->core);
+}
+
 /**
  * clk_get_phase - return the phase shift of a clock signal
  * @clk: clock signal source
@@ -3219,17 +3242,19 @@ static int clk_core_get_scaled_duty_cycle(struct clk_core *core,
 	struct clk_duty *duty = &core->duty;
 	int ret;
 
-	clk_prepare_lock();
-
 	ret = clk_core_update_duty_cycle_nolock(core);
 	if (!ret)
 		ret = mult_frac(scale, duty->num, duty->den);
 
-	clk_prepare_unlock();
-
 	return ret;
 }
 
+static int clk_hw_get_scaled_duty_cycle(struct clk_hw *hw,
+					unsigned int scale)
+{
+	return clk_core_get_scaled_duty_cycle(hw->core, scale);
+}
+
 /**
  * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal
  * @clk: clock signal source
@@ -3240,10 +3265,16 @@ static int clk_core_get_scaled_duty_cycle(struct clk_core *core,
  */
 int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale)
 {
+	int ret;
+
 	if (!clk)
 		return 0;
 
-	return clk_core_get_scaled_duty_cycle(clk->core, scale);
+	clk_prepare_lock();
+	ret = clk_core_get_scaled_duty_cycle(clk->core, scale);
+	clk_prepare_unlock();
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(clk_get_scaled_duty_cycle);
 
@@ -3288,45 +3319,95 @@ static struct hlist_head *orphan_list[] = {
 	NULL,
 };
 
-static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
+/*
+ * 1: Enabled in hardware
+ * 0: Disabled in hardware
+ * -1: Unknown enable state
+ */
+static int clk_hw_enable_state(struct clk_hw *hw)
+{
+	struct clk_core *core = hw->core;
+
+	if (core->ops->is_enabled)
+		return clk_hw_is_enabled(hw) ? 1 : 0;
+	if (!core->ops->enable)
+		return 1;
+
+	return -1;
+}
+
+static unsigned int clk_hw_enable_count(struct clk_hw *hw)
+{
+	return hw->core->enable_count;
+}
+
+static unsigned int clk_hw_prepare_count(struct clk_hw *hw)
+{
+	return hw->core->prepare_count;
+}
+
+static unsigned int clk_hw_protect_count(struct clk_hw *hw)
+{
+	return hw->core->protect_count;
+}
+
+static const char *clk_con_id(struct clk *clk)
+{
+	return clk->con_id;
+}
+
+static const char *clk_dev_id(struct clk *clk)
+{
+	return clk->dev_id;
+}
+
+static struct clk *clk_hw_next_consumer(struct clk_hw *hw, struct clk *prev)
+{
+	if (prev)
+		return hlist_entry_safe(prev->clks_node.next, struct clk, clks_node);
+
+	return hlist_entry_safe(hw->core->clks.first, struct clk, clks_node);
+}
+
+static void clk_summary_show_one(struct seq_file *s, struct clk_hw *hw,
 				 int level)
 {
+	int enable;
 	int phase;
-	struct clk *clk_user;
+	struct clk *clk_user = NULL;
 	int multi_node = 0;
 
 	seq_printf(s, "%*s%-*s %-7d %-8d %-8d %-11lu %-10lu ",
 		   level * 3 + 1, "",
-		   35 - level * 3, c->name,
-		   c->enable_count, c->prepare_count, c->protect_count,
-		   clk_core_get_rate_recalc(c),
-		   clk_core_get_accuracy_recalc(c));
+		   35 - level * 3, clk_hw_get_name(hw),
+		   clk_hw_enable_count(hw), clk_hw_prepare_count(hw),
+		   clk_hw_protect_count(hw),
+		   clk_hw_get_rate_recalc(hw),
+		   clk_hw_get_accuracy_recalc(hw));
 
-	phase = clk_core_get_phase(c);
+	phase = clk_hw_get_phase(hw);
 	if (phase >= 0)
 		seq_printf(s, "%-5d", phase);
 	else
 		seq_puts(s, "-----");
 
-	seq_printf(s, " %-6d", clk_core_get_scaled_duty_cycle(c, 100000));
+	seq_printf(s, " %-6d", clk_hw_get_scaled_duty_cycle(hw, 100000));
 
-	if (c->ops->is_enabled)
-		seq_printf(s, " %5c ", clk_core_is_enabled(c) ? 'Y' : 'N');
-	else if (!c->ops->enable)
-		seq_printf(s, " %5c ", 'Y');
+	enable = clk_hw_enable_state(hw);
+	if (enable >= 0)
+		seq_printf(s, " %5c ", enable ? 'Y' : 'N');
 	else
 		seq_printf(s, " %5c ", '?');
 
-	hlist_for_each_entry(clk_user, &c->clks, clks_node) {
+	while ((clk_user = clk_hw_next_consumer(hw, clk_user))) {
 		seq_printf(s, "%*s%-*s  %-25s\n",
 			   level * 3 + 2 + 105 * multi_node, "",
 			   30,
-			   clk_user->dev_id ? clk_user->dev_id : "deviceless",
-			   clk_user->con_id ? clk_user->con_id : "no_connection_id");
+			   clk_dev_id(clk_user) ? : "deviceless",
+			   clk_con_id(clk_user) ? : "no_connection_id");
 
 		multi_node = 1;
 	}
-
 }
 
 static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
@@ -3334,7 +3415,7 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
 {
 	struct clk_core *child;
 
-	clk_summary_show_one(s, c, level);
+	clk_summary_show_one(s, c->hw, level);
 
 	hlist_for_each_entry(child, &c->children, child_node)
 		clk_summary_show_subtree(s, child, level + 1);
@@ -3367,34 +3448,34 @@ static int clk_summary_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(clk_summary);
 
-static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
+static void clk_dump_one(struct seq_file *s, struct clk_hw *hw, int level)
 {
 	int phase;
 	unsigned long min_rate, max_rate;
 
-	clk_core_get_boundaries(c, &min_rate, &max_rate);
+	clk_hw_get_rate_range(hw, &min_rate, &max_rate);
 
 	/* This should be JSON format, i.e. elements separated with a comma */
-	seq_printf(s, "\"%s\": { ", c->name);
-	seq_printf(s, "\"enable_count\": %d,", c->enable_count);
-	seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
-	seq_printf(s, "\"protect_count\": %d,", c->protect_count);
-	seq_printf(s, "\"rate\": %lu,", clk_core_get_rate_recalc(c));
+	seq_printf(s, "\"%s\": { ", clk_hw_get_name(hw));
+	seq_printf(s, "\"enable_count\": %d,", clk_hw_enable_count(hw));
+	seq_printf(s, "\"prepare_count\": %d,", clk_hw_prepare_count(hw));
+	seq_printf(s, "\"protect_count\": %d,", clk_hw_protect_count(hw));
+	seq_printf(s, "\"rate\": %lu,", clk_hw_get_rate_recalc(hw));
 	seq_printf(s, "\"min_rate\": %lu,", min_rate);
 	seq_printf(s, "\"max_rate\": %lu,", max_rate);
-	seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy_recalc(c));
-	phase = clk_core_get_phase(c);
+	seq_printf(s, "\"accuracy\": %lu,", clk_hw_get_accuracy_recalc(hw));
+	phase = clk_hw_get_phase(hw);
 	if (phase >= 0)
 		seq_printf(s, "\"phase\": %d,", phase);
 	seq_printf(s, "\"duty_cycle\": %u",
-		   clk_core_get_scaled_duty_cycle(c, 100000));
+		   clk_hw_get_scaled_duty_cycle(hw, 100000));
 }
 
 static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
 {
 	struct clk_core *child;
 
-	clk_dump_one(s, c, level);
+	clk_dump_one(s, c->hw, level);
 
 	hlist_for_each_entry(child, &c->children, child_node) {
 		seq_putc(s, ',');
@@ -3436,21 +3517,24 @@ static int clk_dump_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(clk_dump);
 
-#undef CLOCK_ALLOW_WRITE_DEBUGFS
-#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
 /*
  * This can be dangerous, therefore don't provide any real compile time
  * configuration option for this feature.
  * People who want to use this will need to modify the source code directly.
  */
+#undef CLOCK_ALLOW_WRITE_DEBUGFS
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
 static int clk_rate_set(void *data, u64 val)
 {
-	struct clk_core *core = data;
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_rate_set");
 	int ret;
 
-	clk_prepare_lock();
-	ret = clk_core_set_rate_nolock(core, val);
-	clk_prepare_unlock();
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = clk_set_rate(clk, val);
+	clk_put(clk);
 
 	return ret;
 }
@@ -3459,13 +3543,16 @@ static int clk_rate_set(void *data, u64 val)
 
 static int clk_phase_set(void *data, u64 val)
 {
-	struct clk_core *core = data;
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_phase_set");
 	int degrees = do_div(val, 360);
 	int ret;
 
-	clk_prepare_lock();
-	ret = clk_core_set_phase_nolock(core, degrees);
-	clk_prepare_unlock();
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = clk_set_phase(clk, degrees);
+	clk_put(clk);
 
 	return ret;
 }
@@ -3474,22 +3561,27 @@ static int clk_phase_set(void *data, u64 val)
 
 static int clk_prepare_enable_set(void *data, u64 val)
 {
-	struct clk_core *core = data;
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_prepare_enable_set");
 	int ret = 0;
 
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
 	if (val)
-		ret = clk_prepare_enable(core->hw->clk);
+		ret = clk_prepare_enable(clk);
 	else
-		clk_disable_unprepare(core->hw->clk);
+		clk_disable_unprepare(clk);
+	clk_put(clk);
 
 	return ret;
 }
 
 static int clk_prepare_enable_get(void *data, u64 *val)
 {
-	struct clk_core *core = data;
+	struct clk_hw *hw = data;
 
-	*val = core->enable_count && core->prepare_count;
+	*val = clk_hw_is_prepared(hw) && clk_hw_is_enabled(hw);
 	return 0;
 }
 
@@ -3506,11 +3598,14 @@ DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get,
 
 static int clk_rate_get(void *data, u64 *val)
 {
-	struct clk_core *core = data;
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_rate_get");
 
-	clk_prepare_lock();
-	*val = clk_core_get_rate_recalc(core);
-	clk_prepare_unlock();
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	*val = clk_get_rate(clk);
+	clk_put(clk);
 
 	return 0;
 }
@@ -3519,9 +3614,15 @@ DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n");
 
 static int clk_phase_get(void *data, u64 *val)
 {
-	struct clk_core *core = data;
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_phase_get");
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	*val = clk_get_phase(clk);
+	clk_put(clk);
 
-	*val = core->phase;
 	return 0;
 }
 
@@ -3549,8 +3650,8 @@ static const struct {
 
 static int clk_flags_show(struct seq_file *s, void *data)
 {
-	struct clk_core *core = s->private;
-	unsigned long flags = core->flags;
+	struct clk_hw *hw = s->private;
+	unsigned long flags = clk_hw_get_flags(hw);
 	unsigned int i;
 
 	for (i = 0; flags && i < ARRAY_SIZE(clk_flags); i++) {
@@ -3568,10 +3669,11 @@ static int clk_flags_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(clk_flags);
 
-static void possible_parent_show(struct seq_file *s, struct clk_core *core,
-				 unsigned int i, char terminator)
+static void clk_hw_show_parent_by_index(struct seq_file *s, struct clk_hw *hw,
+					unsigned int i, char terminator)
 {
-	struct clk_core *parent;
+	struct clk_hw *parent;
+	struct clk_core *core = hw->core;
 	const char *name = NULL;
 
 	/*
@@ -3586,9 +3688,9 @@ static void possible_parent_show(struct seq_file *s, struct clk_core *core,
 	 * specified directly via a struct clk_hw pointer, but it isn't
 	 * registered (yet).
 	 */
-	parent = clk_core_get_parent_by_index(core, i);
+	parent = clk_hw_get_parent_by_index(hw, i);
 	if (parent) {
-		seq_puts(s, parent->name);
+		seq_puts(s, clk_hw_get_name(parent));
 	} else if (core->parents[i].name) {
 		seq_puts(s, core->parents[i].name);
 	} else if (core->parents[i].fw_name) {
@@ -3607,13 +3709,13 @@ static void possible_parent_show(struct seq_file *s, struct clk_core *core,
 
 static int possible_parents_show(struct seq_file *s, void *data)
 {
-	struct clk_core *core = s->private;
+	struct clk_hw *hw = s->private;
 	int i;
 
-	for (i = 0; i < core->num_parents - 1; i++)
-		possible_parent_show(s, core, i, ' ');
+	for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++)
+		clk_hw_show_parent_by_index(s, hw, i, ' ');
 
-	possible_parent_show(s, core, i, '\n');
+	clk_hw_show_parent_by_index(s, hw, i, '\n');
 
 	return 0;
 }
@@ -3621,10 +3723,11 @@ DEFINE_SHOW_ATTRIBUTE(possible_parents);
 
 static int current_parent_show(struct seq_file *s, void *data)
 {
-	struct clk_core *core = s->private;
+	struct clk_hw *hw = s->private;
+	struct clk_hw *parent = clk_hw_get_parent(hw);
 
-	if (core->parent)
-		seq_printf(s, "%s\n", core->parent->name);
+	if (parent)
+		seq_printf(s, "%s\n", clk_hw_get_name(parent));
 
 	return 0;
 }
@@ -3635,26 +3738,38 @@ static ssize_t current_parent_write(struct file *file, const char __user *ubuf,
 				    size_t count, loff_t *ppos)
 {
 	struct seq_file *s = file->private_data;
-	struct clk_core *core = s->private;
-	struct clk_core *parent;
+	struct clk *clk, *parent;
+	struct clk_hw *hw = s->private;
+	struct clk_hw *parent_hw;
 	u8 idx;
-	int err;
+	int ret;
 
-	err = kstrtou8_from_user(ubuf, count, 0, &idx);
-	if (err < 0)
-		return err;
+	ret = kstrtou8_from_user(ubuf, count, 0, &idx);
+	if (ret < 0)
+		return ret;
 
-	parent = clk_core_get_parent_by_index(core, idx);
-	if (!parent)
+	parent_hw = clk_hw_get_parent_by_index(hw, idx);
+	if (!parent_hw)
 		return -ENOENT;
 
-	clk_prepare_lock();
-	err = clk_core_set_parent_nolock(core, parent);
-	clk_prepare_unlock();
-	if (err)
-		return err;
+	clk = clk_hw_get_clk(hw, "debugfs_write");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
 
-	return count;
+	parent = clk_hw_get_clk(parent_hw, "debugfs_write");
+	if (IS_ERR(parent)) {
+		ret = PTR_ERR(parent);
+		goto err;
+	}
+
+	ret = clk_set_parent(clk, parent);
+	if (!ret)
+		ret = count;
+
+	clk_put(parent);
+err:
+	clk_put(clk);
+	return ret;
 }
 
 static const struct file_operations current_parent_rw_fops = {
@@ -3666,12 +3781,19 @@ static const struct file_operations current_parent_rw_fops = {
 };
 #endif
 
+static void clk_hw_get_duty(struct clk_hw *hw, struct clk_duty *duty)
+{
+	memcpy(duty, &hw->core->duty, sizeof(*duty));
+}
+
 static int clk_duty_cycle_show(struct seq_file *s, void *data)
 {
-	struct clk_core *core = s->private;
-	struct clk_duty *duty = &core->duty;
+	struct clk_hw *hw = s->private;
+	struct clk_duty duty = { };
 
-	seq_printf(s, "%u/%u\n", duty->num, duty->den);
+	clk_hw_get_duty(hw, &duty);
+
+	seq_printf(s, "%u/%u\n", duty.num, duty.den);
 
 	return 0;
 }
@@ -3679,12 +3801,10 @@ DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle);
 
 static int clk_min_rate_show(struct seq_file *s, void *data)
 {
-	struct clk_core *core = s->private;
+	struct clk_hw *hw = s->private;
 	unsigned long min_rate, max_rate;
 
-	clk_prepare_lock();
-	clk_core_get_boundaries(core, &min_rate, &max_rate);
-	clk_prepare_unlock();
+	clk_debug_get_rate_range(hw, &min_rate, &max_rate);
 	seq_printf(s, "%lu\n", min_rate);
 
 	return 0;
@@ -3693,54 +3813,110 @@ DEFINE_SHOW_ATTRIBUTE(clk_min_rate);
 
 static int clk_max_rate_show(struct seq_file *s, void *data)
 {
-	struct clk_core *core = s->private;
+	struct clk_hw *hw = s->private;
 	unsigned long min_rate, max_rate;
 
-	clk_prepare_lock();
-	clk_core_get_boundaries(core, &min_rate, &max_rate);
-	clk_prepare_unlock();
+	clk_debug_get_rate_range(hw, &min_rate, &max_rate);
 	seq_printf(s, "%lu\n", max_rate);
 
 	return 0;
 }
 DEFINE_SHOW_ATTRIBUTE(clk_max_rate);
 
-static struct dentry *clk_debug_create_one(struct clk_core *core)
+static int clk_accuracy_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_accuracy");
+	unsigned long accuracy;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	accuracy = clk_get_accuracy(clk);
+	seq_printf(s, "%lu\n", accuracy);
+	clk_put(clk);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_accuracy);
+
+static int clk_prepare_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+
+	seq_printf(s, "%u\n", clk_hw_prepare_count(hw));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_prepare);
+
+static int clk_enable_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+
+	seq_printf(s, "%u\n", clk_hw_enable_count(hw));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_enable);
+
+static int clk_protect_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+
+	seq_printf(s, "%u\n", clk_hw_protect_count(hw));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_protect);
+
+static unsigned int clk_hw_notifier_count(struct clk_hw *hw)
+{
+	return hw->core->notifier_count;
+}
+
+static int clk_notifier_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+
+	seq_printf(s, "%u\n", clk_hw_notifier_count(hw));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_notifier);
+
+static struct dentry *clk_hw_debug_create_one(struct clk_hw *hw)
 {
 	struct dentry *root;
 
-	root = debugfs_create_dir(core->name, rootdir);
-	core->dentry = root;
+	root = debugfs_create_dir(clk_hw_get_name(hw), rootdir);
 
-	debugfs_create_file("clk_rate", clk_rate_mode, root, core,
-			    &clk_rate_fops);
-	debugfs_create_file("clk_min_rate", 0444, root, core, &clk_min_rate_fops);
-	debugfs_create_file("clk_max_rate", 0444, root, core, &clk_max_rate_fops);
-	debugfs_create_ulong("clk_accuracy", 0444, root, &core->accuracy);
-	debugfs_create_file("clk_phase", clk_phase_mode, root, core,
-			    &clk_phase_fops);
-	debugfs_create_file("clk_flags", 0444, root, core, &clk_flags_fops);
-	debugfs_create_u32("clk_prepare_count", 0444, root, &core->prepare_count);
-	debugfs_create_u32("clk_enable_count", 0444, root, &core->enable_count);
-	debugfs_create_u32("clk_protect_count", 0444, root, &core->protect_count);
-	debugfs_create_u32("clk_notifier_count", 0444, root, &core->notifier_count);
-	debugfs_create_file("clk_duty_cycle", 0444, root, core,
-			    &clk_duty_cycle_fops);
+	debugfs_create_file("clk_rate", clk_rate_mode, root, hw, &clk_rate_fops);
+	debugfs_create_file("clk_min_rate", 0444, root, hw, &clk_min_rate_fops);
+	debugfs_create_file("clk_max_rate", 0444, root, hw, &clk_max_rate_fops);
+	debugfs_create_file("clk_accuracy", 0444, root, hw, &clk_accuracy_fops);
+	debugfs_create_file("clk_phase", clk_phase_mode, root, hw, &clk_phase_fops);
+	debugfs_create_file("clk_flags", 0444, root, hw, &clk_flags_fops);
+	debugfs_create_file("clk_prepare_count", 0444, root, hw, &clk_prepare_fops);
+	debugfs_create_file("clk_enable_count", 0444, root, hw, &clk_enable_fops);
+	debugfs_create_file("clk_protect_count", 0444, root, hw, &clk_protect_fops);
+	debugfs_create_file("clk_notifier_count", 0444, root, hw, &clk_notifier_fops);
+	debugfs_create_file("clk_duty_cycle", 0444, root, hw, &clk_duty_cycle_fops);
 #ifdef CLOCK_ALLOW_WRITE_DEBUGFS
-	debugfs_create_file("clk_prepare_enable", 0644, root, core,
+	debugfs_create_file("clk_prepare_enable", 0644, root, hw,
 			    &clk_prepare_enable_fops);
 
-	if (core->num_parents > 1)
-		debugfs_create_file("clk_parent", 0644, root, core,
+	if (clk_hw_get_num_parents(hw) > 1)
+		debugfs_create_file("clk_parent", 0644, root, hw,
 				    &current_parent_rw_fops);
 	else
 #endif
-	if (core->num_parents > 0)
-		debugfs_create_file("clk_parent", 0444, root, core,
+	if (clk_hw_get_num_parents(hw) > 0)
+		debugfs_create_file("clk_parent", 0444, root, hw,
 				    &current_parent_fops);
 
-	if (core->num_parents > 1)
-		debugfs_create_file("clk_possible_parents", 0444, root, core,
+	if (clk_hw_get_num_parents(hw) > 1)
+		debugfs_create_file("clk_possible_parents", 0444, root, hw,
 				    &possible_parents_fops);
 
 	return root;
@@ -3753,7 +3929,7 @@ static void clk_core_debug_create_one(struct clk_core *core)
 	if (!inited)
 		return;
 
-	core->dentry = clk_debug_create_one(core);
+	core->dentry = clk_hw_debug_create_one(hw);
 	if (core->ops->debug_init)
 		core->ops->debug_init(hw, core->dentry);
 }
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] clk: Iterate instead of recurse for debugfs printing
  2025-01-08  0:58 [PATCH 0/4] clk: Move debugfs to a loadable kernel module Stephen Boyd
  2025-01-08  0:58 ` [PATCH 1/4] clk: Prepare clk_debug_create_one() to be split off Stephen Boyd
  2025-01-08  0:58 ` [PATCH 2/4] clk: Use struct clk_hw instead of struct clk_core for debugfs Stephen Boyd
@ 2025-01-08  0:58 ` Stephen Boyd
  2025-01-08  0:58 ` [PATCH 4/4] clk: Make debugfs code into a loadable kernel module Stephen Boyd
  3 siblings, 0 replies; 8+ messages in thread
From: Stephen Boyd @ 2025-01-08  0:58 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-kernel, linux-clk, patches

The implementation for clk debugfs files like clk_summary and clk_dump
are recursive and entangled with the tree walking logic to the point
that it's not easy to split out the code that walks the clk tree from
the code that prints details of a clk. Harmonize the clk_dump_show() and
clk_summary_show() clk tree walking details by linking all the clks to
be shown onto a linked list in the order that the clks are walked and
then iterate the list calling a "show" function supplied by the caller.

Replacing recursion with iteration avoids exceeding limited kernel
stacks as well as allows us to split the "show" function out to a
loadable kernel module. The downside is the code is more complicated.

Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/clk.c | 171 +++++++++++++++++++++++++---------------------
 1 file changed, 95 insertions(+), 76 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index e2f8fcbc1d4f..37c7963d685f 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -89,6 +89,7 @@ struct clk_core {
 	struct hlist_node	child_node;
 	struct hlist_head	clks;
 	unsigned int		notifier_count;
+	struct hlist_node	iterate_node;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry		*dentry;
 	struct hlist_node	debug_node;
@@ -3314,11 +3315,6 @@ static int inited = 0;
 static DEFINE_MUTEX(clk_debug_lock);
 static HLIST_HEAD(clk_debug_list);
 
-static struct hlist_head *orphan_list[] = {
-	&clk_orphan_list,
-	NULL,
-};
-
 /*
  * 1: Enabled in hardware
  * 0: Disabled in hardware
@@ -3369,9 +3365,85 @@ static struct clk *clk_hw_next_consumer(struct clk_hw *hw, struct clk *prev)
 	return hlist_entry_safe(hw->core->clks.first, struct clk, clks_node);
 }
 
-static void clk_summary_show_one(struct seq_file *s, struct clk_hw *hw,
-				 int level)
+static void clk_walk_trees(struct hlist_head *list, bool only_orphans)
 {
+	struct clk_core *root, *core, *child;
+	struct clk_core *last = NULL;
+	const struct hlist_head **lists = all_lists;
+
+	if (only_orphans)
+		lists++;
+
+	for (; *lists; lists++) {
+		hlist_for_each_entry(root, *lists, child_node) {
+			if (last)
+				hlist_add_behind(&root->iterate_node, &last->iterate_node);
+			else
+				hlist_add_head(&root->iterate_node, list);
+
+			core = root;
+			hlist_for_each_entry_from(core, iterate_node) {
+				last = core;
+				hlist_for_each_entry(child, &core->children, child_node) {
+					hlist_add_behind(&child->iterate_node, &last->iterate_node);
+					last = child;
+				}
+			}
+		}
+	}
+}
+
+static int clk_show_tree(void (*show_fn)(struct clk_hw *hw, int level,
+					 int next_level, bool first,
+					 void *data),
+			 void *data, bool orphan_only)
+{
+	struct clk_core *core, *parent;
+	struct hlist_node *tmp;
+	HLIST_HEAD(list);
+	int ret;
+	int level = 0;
+	int next_level;
+	bool first = true;
+
+	ret = clk_pm_runtime_get_all();
+	if (ret)
+		return ret;
+
+	clk_prepare_lock();
+
+	clk_walk_trees(&list, orphan_only);
+	hlist_for_each_entry_safe(core, tmp, &list, iterate_node) {
+		next_level = level;
+		parent = core;
+		/*
+		 * If this is the right most (i.e. last) clk at this level
+		 * figure out how many levels lower the next clk will be by
+		 * finding the next left side of the tree.
+		 */
+		while (!parent->child_node.next && (parent = parent->parent))
+			next_level--;
+		/* If the clk has children the next node is at the next level */
+		if (!hlist_empty(&core->children))
+			next_level = level + 1;
+
+		show_fn(core->hw, level, next_level, first, data);
+		first = false;
+
+		hlist_del_init(&core->iterate_node);
+		level = next_level;
+	}
+
+	clk_prepare_unlock();
+	clk_pm_runtime_put_all();
+
+	return 0;
+}
+
+static void clk_summary_show_one(struct clk_hw *hw, int level, int next_level,
+				 bool first, void *data)
+{
+	struct seq_file *s = data;
 	int enable;
 	int phase;
 	struct clk *clk_user = NULL;
@@ -3410,51 +3482,29 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_hw *hw,
 	}
 }
 
-static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
-				     int level)
-{
-	struct clk_core *child;
-
-	clk_summary_show_one(s, c->hw, level);
-
-	hlist_for_each_entry(child, &c->children, child_node)
-		clk_summary_show_subtree(s, child, level + 1);
-}
-
 static int clk_summary_show(struct seq_file *s, void *data)
 {
-	struct clk_core *c;
-	struct hlist_head **lists = s->private;
-	int ret;
+	bool orphan_only = s->private;
 
 	seq_puts(s, "                                 enable  prepare  protect                                duty  hardware                            connection\n");
 	seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id\n");
 	seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
 
-	ret = clk_pm_runtime_get_all();
-	if (ret)
-		return ret;
-
-	clk_prepare_lock();
-
-	for (; *lists; lists++)
-		hlist_for_each_entry(c, *lists, child_node)
-			clk_summary_show_subtree(s, c, 0);
-
-	clk_prepare_unlock();
-	clk_pm_runtime_put_all();
-
-	return 0;
+	return clk_show_tree(clk_summary_show_one, s, orphan_only);
 }
 DEFINE_SHOW_ATTRIBUTE(clk_summary);
 
-static void clk_dump_one(struct seq_file *s, struct clk_hw *hw, int level)
+static void clk_dump_one(struct clk_hw *hw, int level, int next_level, bool first, void *data)
 {
+	struct seq_file *s = data;
 	int phase;
 	unsigned long min_rate, max_rate;
 
 	clk_hw_get_rate_range(hw, &min_rate, &max_rate);
 
+	if (!first)
+		seq_putc(s, ',');
+
 	/* This should be JSON format, i.e. elements separated with a comma */
 	seq_printf(s, "\"%s\": { ", clk_hw_get_name(hw));
 	seq_printf(s, "\"enable_count\": %d,", clk_hw_enable_count(hw));
@@ -3469,50 +3519,19 @@ static void clk_dump_one(struct seq_file *s, struct clk_hw *hw, int level)
 		seq_printf(s, "\"phase\": %d,", phase);
 	seq_printf(s, "\"duty_cycle\": %u",
 		   clk_hw_get_scaled_duty_cycle(hw, 100000));
-}
 
-static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
-{
-	struct clk_core *child;
-
-	clk_dump_one(s, c->hw, level);
-
-	hlist_for_each_entry(child, &c->children, child_node) {
-		seq_putc(s, ',');
-		clk_dump_subtree(s, child, level + 1);
-	}
-
-	seq_putc(s, '}');
+	while (level-- >= next_level)
+		seq_putc(s, '}');
 }
 
 static int clk_dump_show(struct seq_file *s, void *data)
 {
-	struct clk_core *c;
-	bool first_node = true;
-	struct hlist_head **lists = s->private;
-	int ret;
-
-	ret = clk_pm_runtime_get_all();
-	if (ret)
-		return ret;
+	bool orphan_only = s->private;
 
 	seq_putc(s, '{');
-
-	clk_prepare_lock();
-
-	for (; *lists; lists++) {
-		hlist_for_each_entry(c, *lists, child_node) {
-			if (!first_node)
-				seq_putc(s, ',');
-			first_node = false;
-			clk_dump_subtree(s, c, 0);
-		}
-	}
-
-	clk_prepare_unlock();
-	clk_pm_runtime_put_all();
-
+	clk_show_tree(clk_dump_one, s, orphan_only);
 	seq_puts(s, "}\n");
+
 	return 0;
 }
 DEFINE_SHOW_ATTRIBUTE(clk_dump);
@@ -4000,13 +4019,13 @@ static int __init clk_debug_init(void)
 
 	rootdir = debugfs_create_dir("clk", NULL);
 
-	debugfs_create_file("clk_summary", 0444, rootdir, &all_lists,
+	debugfs_create_file("clk_summary", 0444, rootdir, (void *)0UL,
 			    &clk_summary_fops);
-	debugfs_create_file("clk_dump", 0444, rootdir, &all_lists,
+	debugfs_create_file("clk_dump", 0444, rootdir, (void *)0UL,
 			    &clk_dump_fops);
-	debugfs_create_file("clk_orphan_summary", 0444, rootdir, &orphan_list,
+	debugfs_create_file("clk_orphan_summary", 0444, rootdir, (void *)1UL,
 			    &clk_summary_fops);
-	debugfs_create_file("clk_orphan_dump", 0444, rootdir, &orphan_list,
+	debugfs_create_file("clk_orphan_dump", 0444, rootdir, (void *)1UL,
 			    &clk_dump_fops);
 
 	mutex_lock(&clk_debug_lock);
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/4] clk: Make debugfs code into a loadable kernel module
  2025-01-08  0:58 [PATCH 0/4] clk: Move debugfs to a loadable kernel module Stephen Boyd
                   ` (2 preceding siblings ...)
  2025-01-08  0:58 ` [PATCH 3/4] clk: Iterate instead of recurse for debugfs printing Stephen Boyd
@ 2025-01-08  0:58 ` Stephen Boyd
  2025-01-10  6:45   ` kernel test robot
                     ` (2 more replies)
  3 siblings, 3 replies; 8+ messages in thread
From: Stephen Boyd @ 2025-01-08  0:58 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-kernel, linux-clk, patches

Split the debugfs code for the clk framework into a separate loadable
kernel module. This allows the debugfs code to be loaded later, or not
at all.

Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/Kconfig     |   8 +
 drivers/clk/Makefile    |   1 +
 drivers/clk/clk-debug.c | 529 ++++++++++++++++++++++++++++++++++
 drivers/clk/clk-debug.h |  33 +++
 drivers/clk/clk.c       | 607 +++++-----------------------------------
 5 files changed, 643 insertions(+), 535 deletions(-)
 create mode 100644 drivers/clk/clk-debug.c
 create mode 100644 drivers/clk/clk-debug.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 713573b6c86c..fb84c2698cbd 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -33,6 +33,14 @@ menuconfig COMMON_CLK
 
 if COMMON_CLK
 
+config COMMON_CLK_DEBUG
+	tristate "Common Clock Framework debug support"
+	depends on DEBUG_FS || COMPILE_TEST
+	default COMMON_CLK
+	help
+	  Say yes here to enable debugging support for the common clock
+	  framework.
+
 config COMMON_CLK_WM831X
 	tristate "Clock driver for WM831x/2x PMICs"
 	depends on MFD_WM831X
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index bf4bd45adc3a..10e1dab55cc9 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -2,6 +2,7 @@
 # common clock types
 obj-$(CONFIG_HAVE_CLK)		+= clk-devres.o clk-bulk.o clkdev.o
 obj-$(CONFIG_COMMON_CLK)	+= clk.o
+obj-$(CONFIG_COMMON_CLK_DEBUG)	+= clk-debug.o
 obj-$(CONFIG_CLK_KUNIT_TEST)	+= clk-test.o
 clk-test-y			:= clk_test.o \
 				   kunit_clk_assigned_rates_u64_one.dtbo.o \
diff --git a/drivers/clk/clk-debug.c b/drivers/clk/clk-debug.c
new file mode 100644
index 000000000000..47af5f25c4e3
--- /dev/null
+++ b/drivers/clk/clk-debug.c
@@ -0,0 +1,529 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
+ *
+ * Debugfs functionality for the common clock framework.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/debugfs.h>
+#include <linux/kstrtox.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/seq_file.h>
+
+#include "clk-debug.h"
+
+MODULE_IMPORT_NS("clk-debug");
+
+static struct dentry *rootdir;
+
+static void clk_summary_show_one(struct clk_hw *hw, int level, int next_level,
+				 bool first, void *data)
+{
+	struct seq_file *s = data;
+	int enable;
+	int phase;
+	struct clk *clk_user = NULL;
+	int multi_node = 0;
+
+	seq_printf(s, "%*s%-*s %-7d %-8d %-8d %-11lu %-10lu ",
+		   level * 3 + 1, "",
+		   35 - level * 3, clk_hw_get_name(hw),
+		   clk_hw_enable_count(hw), clk_hw_prepare_count(hw),
+		   clk_hw_protect_count(hw),
+		   clk_hw_get_rate_recalc(hw),
+		   clk_hw_get_accuracy_recalc(hw));
+
+	phase = clk_hw_get_phase(hw);
+	if (phase >= 0)
+		seq_printf(s, "%-5d", phase);
+	else
+		seq_puts(s, "-----");
+
+	seq_printf(s, " %-6d", clk_hw_get_scaled_duty_cycle(hw, 100000));
+
+	enable = clk_hw_enable_state(hw);
+	if (enable >= 0)
+		seq_printf(s, " %5c ", enable ? 'Y' : 'N');
+	else
+		seq_printf(s, " %5c ", '?');
+
+	while ((clk_user = clk_hw_next_consumer(hw, clk_user))) {
+		seq_printf(s, "%*s%-*s  %-25s\n",
+			   level * 3 + 2 + 105 * multi_node, "",
+			   30,
+			   clk_dev_id(clk_user) ? : "deviceless",
+			   clk_con_id(clk_user) ? : "no_connection_id");
+
+		multi_node = 1;
+	}
+}
+
+static int clk_summary_show(struct seq_file *s, void *data)
+{
+	bool orphan_only = s->private;
+
+	seq_puts(s, "                                 enable  prepare  protect                                duty  hardware                            connection\n");
+	seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id\n");
+	seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
+
+	return clk_show_tree(clk_summary_show_one, s, orphan_only);
+}
+DEFINE_SHOW_ATTRIBUTE(clk_summary);
+
+static void clk_dump_one(struct clk_hw *hw, int level, int next_level, bool first, void *data)
+{
+	struct seq_file *s = data;
+	int phase;
+	unsigned long min_rate, max_rate;
+
+	clk_hw_get_rate_range(hw, &min_rate, &max_rate);
+
+	if (!first)
+		seq_putc(s, ',');
+
+	/* This should be JSON format, i.e. elements separated with a comma */
+	seq_printf(s, "\"%s\": { ", clk_hw_get_name(hw));
+	seq_printf(s, "\"enable_count\": %d,", clk_hw_enable_count(hw));
+	seq_printf(s, "\"prepare_count\": %d,", clk_hw_prepare_count(hw));
+	seq_printf(s, "\"protect_count\": %d,", clk_hw_protect_count(hw));
+	seq_printf(s, "\"rate\": %lu,", clk_hw_get_rate_recalc(hw));
+	seq_printf(s, "\"min_rate\": %lu,", min_rate);
+	seq_printf(s, "\"max_rate\": %lu,", max_rate);
+	seq_printf(s, "\"accuracy\": %lu,", clk_hw_get_accuracy_recalc(hw));
+	phase = clk_hw_get_phase(hw);
+	if (phase >= 0)
+		seq_printf(s, "\"phase\": %d,", phase);
+	seq_printf(s, "\"duty_cycle\": %u",
+		   clk_hw_get_scaled_duty_cycle(hw, 100000));
+
+	while (level-- >= next_level)
+		seq_putc(s, '}');
+}
+
+static int clk_dump_show(struct seq_file *s, void *data)
+{
+	bool orphan_only = s->private;
+
+	seq_putc(s, '{');
+	clk_show_tree(clk_dump_one, s, orphan_only);
+	seq_puts(s, "}\n");
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_dump);
+
+/*
+ * This can be dangerous, therefore don't provide any real compile time
+ * configuration option for this feature.
+ * People who want to use this will need to modify the source code directly.
+ */
+#undef CLOCK_ALLOW_WRITE_DEBUGFS
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+static int clk_rate_set(void *data, u64 val)
+{
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_rate_set");
+	int ret;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = clk_set_rate(clk, val);
+	clk_put(clk);
+
+	return ret;
+}
+
+#define clk_rate_mode	0644
+
+static int clk_phase_set(void *data, u64 val)
+{
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_phase_set");
+	int degrees = do_div(val, 360);
+	int ret;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = clk_set_phase(clk, degrees);
+	clk_put(clk);
+
+	return ret;
+}
+
+#define clk_phase_mode	0644
+
+static int clk_prepare_enable_set(void *data, u64 val)
+{
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_prepare_enable_set");
+	int ret = 0;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	if (val)
+		ret = clk_prepare_enable(clk);
+	else
+		clk_disable_unprepare(clk);
+	clk_put(clk);
+
+	return ret;
+}
+
+static int clk_prepare_enable_get(void *data, u64 *val)
+{
+	struct clk_hw *hw = data;
+
+	*val = clk_hw_is_prepared(hw) && clk_hw_is_enabled(hw);
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get,
+			 clk_prepare_enable_set, "%llu\n");
+
+#else
+#define clk_rate_set	NULL
+#define clk_rate_mode	0444
+
+#define clk_phase_set	NULL
+#define clk_phase_mode	0644
+#endif
+
+static int clk_rate_get(void *data, u64 *val)
+{
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_rate_get");
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	*val = clk_get_rate(clk);
+	clk_put(clk);
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n");
+
+static int clk_phase_get(void *data, u64 *val)
+{
+	struct clk_hw *hw = data;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_phase_get");
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	*val = clk_get_phase(clk);
+	clk_put(clk);
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(clk_phase_fops, clk_phase_get, clk_phase_set, "%llu\n");
+
+static const struct {
+	unsigned long flag;
+	const char *name;
+} clk_flags[] = {
+#define ENTRY(f) { f, #f }
+	ENTRY(CLK_SET_RATE_GATE),
+	ENTRY(CLK_SET_PARENT_GATE),
+	ENTRY(CLK_SET_RATE_PARENT),
+	ENTRY(CLK_IGNORE_UNUSED),
+	ENTRY(CLK_GET_RATE_NOCACHE),
+	ENTRY(CLK_SET_RATE_NO_REPARENT),
+	ENTRY(CLK_GET_ACCURACY_NOCACHE),
+	ENTRY(CLK_RECALC_NEW_RATES),
+	ENTRY(CLK_SET_RATE_UNGATE),
+	ENTRY(CLK_IS_CRITICAL),
+	ENTRY(CLK_OPS_PARENT_ENABLE),
+	ENTRY(CLK_DUTY_CYCLE_PARENT),
+#undef ENTRY
+};
+
+static int clk_flags_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+	unsigned long flags = clk_hw_get_flags(hw);
+	unsigned int i;
+
+	for (i = 0; flags && i < ARRAY_SIZE(clk_flags); i++) {
+		if (flags & clk_flags[i].flag) {
+			seq_printf(s, "%s\n", clk_flags[i].name);
+			flags &= ~clk_flags[i].flag;
+		}
+	}
+	if (flags) {
+		/* Unknown flags */
+		seq_printf(s, "0x%lx\n", flags);
+	}
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_flags);
+
+static int possible_parents_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+	int i;
+
+	for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++)
+		clk_hw_show_parent_by_index(s, hw, i, ' ');
+
+	clk_hw_show_parent_by_index(s, hw, i, '\n');
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(possible_parents);
+
+static int current_parent_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+
+	if (parent)
+		seq_printf(s, "%s\n", clk_hw_get_name(parent));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(current_parent);
+
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+static ssize_t current_parent_write(struct file *file, const char __user *ubuf,
+				    size_t count, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct clk *clk, *parent;
+	struct clk_hw *hw = s->private;
+	struct clk_hw *parent_hw;
+	u8 idx;
+	int ret;
+
+	ret = kstrtou8_from_user(ubuf, count, 0, &idx);
+	if (ret < 0)
+		return ret;
+
+	parent_hw = clk_hw_get_parent_by_index(hw, idx);
+	if (!parent_hw)
+		return -ENOENT;
+
+	clk = clk_hw_get_clk(hw, "debugfs_write");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	parent = clk_hw_get_clk(parent_hw, "debugfs_write");
+	if (IS_ERR(parent)) {
+		ret = PTR_ERR(parent);
+		goto err;
+	}
+
+	ret = clk_set_parent(clk, parent);
+	if (!ret)
+		ret = count;
+
+	clk_put(parent);
+err:
+	clk_put(clk);
+	return ret;
+}
+
+static const struct file_operations current_parent_rw_fops = {
+	.open		= current_parent_open,
+	.write		= current_parent_write,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+#endif
+
+static int clk_duty_cycle_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+	struct clk_duty duty = { };
+
+	clk_hw_get_duty(hw, &duty);
+
+	seq_printf(s, "%u/%u\n", duty.num, duty.den);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle);
+
+static int clk_min_rate_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+	unsigned long min_rate, max_rate;
+
+	clk_debug_get_rate_range(hw, &min_rate, &max_rate);
+	seq_printf(s, "%lu\n", min_rate);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_min_rate);
+
+static int clk_max_rate_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+	unsigned long min_rate, max_rate;
+
+	clk_debug_get_rate_range(hw, &min_rate, &max_rate);
+	seq_printf(s, "%lu\n", max_rate);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_max_rate);
+
+static int clk_accuracy_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+	struct clk *clk = clk_hw_get_clk(hw, "debugfs_accuracy");
+	unsigned long accuracy;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	accuracy = clk_get_accuracy(clk);
+	seq_printf(s, "%lu\n", accuracy);
+	clk_put(clk);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_accuracy);
+
+static int clk_prepare_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+
+	seq_printf(s, "%u\n", clk_hw_prepare_count(hw));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_prepare);
+
+static int clk_enable_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+
+	seq_printf(s, "%u\n", clk_hw_enable_count(hw));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_enable);
+
+static int clk_protect_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+
+	seq_printf(s, "%u\n", clk_hw_protect_count(hw));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_protect);
+
+static int clk_notifier_show(struct seq_file *s, void *data)
+{
+	struct clk_hw *hw = s->private;
+
+	seq_printf(s, "%u\n", clk_hw_notifier_count(hw));
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_notifier);
+
+static struct dentry *clk_hw_debug_create_one(struct clk_hw *hw)
+{
+	struct dentry *root;
+
+	root = debugfs_create_dir(clk_hw_get_name(hw), rootdir);
+
+	debugfs_create_file("clk_rate", clk_rate_mode, root, hw, &clk_rate_fops);
+	debugfs_create_file("clk_min_rate", 0444, root, hw, &clk_min_rate_fops);
+	debugfs_create_file("clk_max_rate", 0444, root, hw, &clk_max_rate_fops);
+	debugfs_create_file("clk_accuracy", 0444, root, hw, &clk_accuracy_fops);
+	debugfs_create_file("clk_phase", clk_phase_mode, root, hw, &clk_phase_fops);
+	debugfs_create_file("clk_flags", 0444, root, hw, &clk_flags_fops);
+	debugfs_create_file("clk_prepare_count", 0444, root, hw, &clk_prepare_fops);
+	debugfs_create_file("clk_enable_count", 0444, root, hw, &clk_enable_fops);
+	debugfs_create_file("clk_protect_count", 0444, root, hw, &clk_protect_fops);
+	debugfs_create_file("clk_notifier_count", 0444, root, hw, &clk_notifier_fops);
+	debugfs_create_file("clk_duty_cycle", 0444, root, hw, &clk_duty_cycle_fops);
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+	debugfs_create_file("clk_prepare_enable", 0644, root, hw,
+			    &clk_prepare_enable_fops);
+
+	if (clk_hw_get_num_parents(hw) > 1)
+		debugfs_create_file("clk_parent", 0644, root, hw,
+				    &current_parent_rw_fops);
+	else
+#endif
+	if (clk_hw_get_num_parents(hw) > 0)
+		debugfs_create_file("clk_parent", 0444, root, hw,
+				    &current_parent_fops);
+
+	if (clk_hw_get_num_parents(hw) > 1)
+		debugfs_create_file("clk_possible_parents", 0444, root, hw,
+				    &possible_parents_fops);
+
+	return root;
+}
+
+/**
+ * clk_debug_init - lazily populate the debugfs clk directory
+ *
+ * clks are often initialized very early during boot before memory can be
+ * dynamically allocated and well before debugfs is setup. This function
+ * populates the debugfs clk directory once at boot-time when we know that
+ * debugfs is setup. It should only be called once at boot-time, all other clks
+ * added dynamically will be done so with clk_debug_register.
+ */
+static int __init clk_debug_init(void)
+{
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+	pr_warn("\n");
+	pr_warn("********************************************************************\n");
+	pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
+	pr_warn("**                                                                **\n");
+	pr_warn("**  WRITEABLE clk DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n");
+	pr_warn("**                                                                **\n");
+	pr_warn("** This means that this kernel is built to expose clk operations  **\n");
+	pr_warn("** such as parent or rate setting, enabling, disabling, etc.      **\n");
+	pr_warn("** to userspace, which may compromise security on your system.    **\n");
+	pr_warn("**                                                                **\n");
+	pr_warn("** If you see this message and you are not debugging the          **\n");
+	pr_warn("** kernel, report this immediately to your vendor!                **\n");
+	pr_warn("**                                                                **\n");
+	pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
+	pr_warn("********************************************************************\n");
+#endif
+
+	rootdir = debugfs_create_dir("clk", NULL);
+
+	debugfs_create_file("clk_summary", 0444, rootdir, (void *)0UL,
+			    &clk_summary_fops);
+	debugfs_create_file("clk_dump", 0444, rootdir, (void *)0UL,
+			    &clk_dump_fops);
+	debugfs_create_file("clk_orphan_summary", 0444, rootdir, (void *)1UL,
+			    &clk_summary_fops);
+	debugfs_create_file("clk_orphan_dump", 0444, rootdir, (void *)1UL,
+			    &clk_dump_fops);
+
+	clk_hw_debug_for_each_init(clk_hw_debug_create_one);
+
+	return 0;
+}
+late_initcall(clk_debug_init);
+
+static void __exit clk_debug_exit(void)
+{
+	clk_hw_debug_exit();
+	debugfs_remove_recursive(rootdir);
+}
+module_exit(clk_debug_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-debug.h b/drivers/clk/clk-debug.h
new file mode 100644
index 000000000000..007fa32237c0
--- /dev/null
+++ b/drivers/clk/clk-debug.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+struct clk;
+struct clk_duty;
+struct clk_hw;
+struct seq_file;
+
+extern int clk_hw_enable_state(struct clk_hw *hw);
+extern unsigned int clk_hw_enable_count(struct clk_hw *hw);
+extern unsigned int clk_hw_prepare_count(struct clk_hw *hw);
+extern unsigned int clk_hw_protect_count(struct clk_hw *hw);
+extern int clk_hw_get_phase(struct clk_hw *hw);
+extern int clk_hw_get_scaled_duty_cycle(struct clk_hw *hw, unsigned int scale);
+extern void clk_hw_get_duty(struct clk_hw *hw, struct clk_duty *duty);
+extern unsigned long clk_hw_get_rate_recalc(struct clk_hw *hw);
+extern long clk_hw_get_accuracy_recalc(struct clk_hw *hw);
+extern void clk_debug_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
+				     unsigned long *max_rate);
+extern unsigned int clk_hw_notifier_count(struct clk_hw *hw);
+
+extern const char *clk_con_id(struct clk *clk);
+extern const char *clk_dev_id(struct clk *clk);
+extern struct clk *clk_hw_next_consumer(struct clk_hw *hw, struct clk *prev);
+extern void clk_hw_show_parent_by_index(struct seq_file *s, struct clk_hw *hw,
+					unsigned int i, char terminator);
+
+extern int clk_show_tree(void (*show_fn)(struct clk_hw *hw, int level,
+					 int next_level, bool first,
+					 void *data),
+			 void *data, bool orphan_only);
+
+extern void clk_hw_debug_for_each_init(struct dentry *(*fn)(struct clk_hw *hw));
+extern void clk_hw_debug_exit(void);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 37c7963d685f..a3529595e71b 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -23,6 +23,7 @@
 #include <linux/clkdev.h>
 
 #include "clk.h"
+#include "clk-debug.h"
 
 static DEFINE_SPINLOCK(enable_lock);
 static DEFINE_MUTEX(prepare_lock);
@@ -819,13 +820,14 @@ void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
 }
 EXPORT_SYMBOL_GPL(clk_hw_get_rate_range);
 
-static void clk_debug_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
-				     unsigned long *max_rate)
+void clk_debug_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
+			      unsigned long *max_rate)
 {
 	clk_prepare_lock();
 	clk_hw_get_rate_range(hw, min_rate, max_rate);
 	clk_prepare_unlock();
 }
+EXPORT_SYMBOL_NS_GPL(clk_debug_get_rate_range, "clk-debug");
 
 static bool clk_core_check_boundaries(struct clk_core *core,
 				      unsigned long min_rate,
@@ -1906,10 +1908,11 @@ static long clk_core_get_accuracy_recalc(struct clk_core *core)
 	return clk_core_get_accuracy_no_lock(core);
 }
 
-static long clk_hw_get_accuracy_recalc(struct clk_hw *hw)
+long clk_hw_get_accuracy_recalc(struct clk_hw *hw)
 {
 	return clk_core_get_accuracy_recalc(hw->core);
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_get_accuracy_recalc, "clk-debug");
 
 /**
  * clk_get_accuracy - return the accuracy of clk
@@ -1997,10 +2000,11 @@ static unsigned long clk_core_get_rate_recalc(struct clk_core *core)
 	return clk_core_get_rate_nolock(core);
 }
 
-static unsigned long clk_hw_get_rate_recalc(struct clk_hw *hw)
+unsigned long clk_hw_get_rate_recalc(struct clk_hw *hw)
 {
 	return clk_core_get_rate_recalc(hw->core);
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_get_rate_recalc, "clk-debug");
 
 /**
  * clk_get_rate - return the rate of clk
@@ -3078,10 +3082,11 @@ static int clk_core_get_phase(struct clk_core *core)
 	return ret;
 }
 
-static int clk_hw_get_phase(struct clk_hw *hw)
+int clk_hw_get_phase(struct clk_hw *hw)
 {
 	return clk_core_get_phase(hw->core);
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_get_phase, "clk-debug");
 
 /**
  * clk_get_phase - return the phase shift of a clock signal
@@ -3250,11 +3255,11 @@ static int clk_core_get_scaled_duty_cycle(struct clk_core *core,
 	return ret;
 }
 
-static int clk_hw_get_scaled_duty_cycle(struct clk_hw *hw,
-					unsigned int scale)
+int clk_hw_get_scaled_duty_cycle(struct clk_hw *hw, unsigned int scale)
 {
 	return clk_core_get_scaled_duty_cycle(hw->core, scale);
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_get_scaled_duty_cycle, "clk-debug");
 
 /**
  * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal
@@ -3307,11 +3312,9 @@ EXPORT_SYMBOL_GPL(clk_is_match);
 
 /***        debugfs support        ***/
 
-#ifdef CONFIG_DEBUG_FS
+#if IS_ENABLED(CONFIG_COMMON_CLK_DEBUG)
 #include <linux/debugfs.h>
 
-static struct dentry *rootdir;
-static int inited = 0;
 static DEFINE_MUTEX(clk_debug_lock);
 static HLIST_HEAD(clk_debug_list);
 
@@ -3320,7 +3323,7 @@ static HLIST_HEAD(clk_debug_list);
  * 0: Disabled in hardware
  * -1: Unknown enable state
  */
-static int clk_hw_enable_state(struct clk_hw *hw)
+int clk_hw_enable_state(struct clk_hw *hw)
 {
 	struct clk_core *core = hw->core;
 
@@ -3331,39 +3334,58 @@ static int clk_hw_enable_state(struct clk_hw *hw)
 
 	return -1;
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_enable_state, "clk-debug");
 
-static unsigned int clk_hw_enable_count(struct clk_hw *hw)
+unsigned int clk_hw_enable_count(struct clk_hw *hw)
 {
 	return hw->core->enable_count;
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_enable_count, "clk-debug");
 
-static unsigned int clk_hw_prepare_count(struct clk_hw *hw)
+unsigned int clk_hw_prepare_count(struct clk_hw *hw)
 {
 	return hw->core->prepare_count;
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_prepare_count, "clk-debug");
 
-static unsigned int clk_hw_protect_count(struct clk_hw *hw)
+unsigned int clk_hw_protect_count(struct clk_hw *hw)
 {
 	return hw->core->protect_count;
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_protect_count, "clk-debug");
 
-static const char *clk_con_id(struct clk *clk)
+const char *clk_con_id(struct clk *clk)
 {
 	return clk->con_id;
 }
+EXPORT_SYMBOL_NS_GPL(clk_con_id, "clk-debug");
 
-static const char *clk_dev_id(struct clk *clk)
+const char *clk_dev_id(struct clk *clk)
 {
 	return clk->dev_id;
 }
+EXPORT_SYMBOL_NS_GPL(clk_dev_id, "clk-debug");
 
-static struct clk *clk_hw_next_consumer(struct clk_hw *hw, struct clk *prev)
+struct clk *clk_hw_next_consumer(struct clk_hw *hw, struct clk *prev)
 {
 	if (prev)
 		return hlist_entry_safe(prev->clks_node.next, struct clk, clks_node);
 
 	return hlist_entry_safe(hw->core->clks.first, struct clk, clks_node);
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_next_consumer, "clk-debug");
+
+void clk_hw_get_duty(struct clk_hw *hw, struct clk_duty *duty)
+{
+	memcpy(duty, &hw->core->duty, sizeof(*duty));
+}
+EXPORT_SYMBOL_NS_GPL(clk_hw_get_duty, "clk-debug");
+
+unsigned int clk_hw_notifier_count(struct clk_hw *hw)
+{
+	return hw->core->notifier_count;
+}
+EXPORT_SYMBOL_NS_GPL(clk_hw_notifier_count, "clk-debug");
 
 static void clk_walk_trees(struct hlist_head *list, bool only_orphans)
 {
@@ -3393,10 +3415,9 @@ static void clk_walk_trees(struct hlist_head *list, bool only_orphans)
 	}
 }
 
-static int clk_show_tree(void (*show_fn)(struct clk_hw *hw, int level,
-					 int next_level, bool first,
-					 void *data),
-			 void *data, bool orphan_only)
+int clk_show_tree(void (*show_fn)(struct clk_hw *hw, int level, int next_level,
+				  bool first, void *data),
+		  void *data, bool orphan_only)
 {
 	struct clk_core *core, *parent;
 	struct hlist_node *tmp;
@@ -3439,257 +3460,10 @@ static int clk_show_tree(void (*show_fn)(struct clk_hw *hw, int level,
 
 	return 0;
 }
+EXPORT_SYMBOL_NS_GPL(clk_show_tree, "clk-debug");
 
-static void clk_summary_show_one(struct clk_hw *hw, int level, int next_level,
-				 bool first, void *data)
-{
-	struct seq_file *s = data;
-	int enable;
-	int phase;
-	struct clk *clk_user = NULL;
-	int multi_node = 0;
-
-	seq_printf(s, "%*s%-*s %-7d %-8d %-8d %-11lu %-10lu ",
-		   level * 3 + 1, "",
-		   35 - level * 3, clk_hw_get_name(hw),
-		   clk_hw_enable_count(hw), clk_hw_prepare_count(hw),
-		   clk_hw_protect_count(hw),
-		   clk_hw_get_rate_recalc(hw),
-		   clk_hw_get_accuracy_recalc(hw));
-
-	phase = clk_hw_get_phase(hw);
-	if (phase >= 0)
-		seq_printf(s, "%-5d", phase);
-	else
-		seq_puts(s, "-----");
-
-	seq_printf(s, " %-6d", clk_hw_get_scaled_duty_cycle(hw, 100000));
-
-	enable = clk_hw_enable_state(hw);
-	if (enable >= 0)
-		seq_printf(s, " %5c ", enable ? 'Y' : 'N');
-	else
-		seq_printf(s, " %5c ", '?');
-
-	while ((clk_user = clk_hw_next_consumer(hw, clk_user))) {
-		seq_printf(s, "%*s%-*s  %-25s\n",
-			   level * 3 + 2 + 105 * multi_node, "",
-			   30,
-			   clk_dev_id(clk_user) ? : "deviceless",
-			   clk_con_id(clk_user) ? : "no_connection_id");
-
-		multi_node = 1;
-	}
-}
-
-static int clk_summary_show(struct seq_file *s, void *data)
-{
-	bool orphan_only = s->private;
-
-	seq_puts(s, "                                 enable  prepare  protect                                duty  hardware                            connection\n");
-	seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id\n");
-	seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
-
-	return clk_show_tree(clk_summary_show_one, s, orphan_only);
-}
-DEFINE_SHOW_ATTRIBUTE(clk_summary);
-
-static void clk_dump_one(struct clk_hw *hw, int level, int next_level, bool first, void *data)
-{
-	struct seq_file *s = data;
-	int phase;
-	unsigned long min_rate, max_rate;
-
-	clk_hw_get_rate_range(hw, &min_rate, &max_rate);
-
-	if (!first)
-		seq_putc(s, ',');
-
-	/* This should be JSON format, i.e. elements separated with a comma */
-	seq_printf(s, "\"%s\": { ", clk_hw_get_name(hw));
-	seq_printf(s, "\"enable_count\": %d,", clk_hw_enable_count(hw));
-	seq_printf(s, "\"prepare_count\": %d,", clk_hw_prepare_count(hw));
-	seq_printf(s, "\"protect_count\": %d,", clk_hw_protect_count(hw));
-	seq_printf(s, "\"rate\": %lu,", clk_hw_get_rate_recalc(hw));
-	seq_printf(s, "\"min_rate\": %lu,", min_rate);
-	seq_printf(s, "\"max_rate\": %lu,", max_rate);
-	seq_printf(s, "\"accuracy\": %lu,", clk_hw_get_accuracy_recalc(hw));
-	phase = clk_hw_get_phase(hw);
-	if (phase >= 0)
-		seq_printf(s, "\"phase\": %d,", phase);
-	seq_printf(s, "\"duty_cycle\": %u",
-		   clk_hw_get_scaled_duty_cycle(hw, 100000));
-
-	while (level-- >= next_level)
-		seq_putc(s, '}');
-}
-
-static int clk_dump_show(struct seq_file *s, void *data)
-{
-	bool orphan_only = s->private;
-
-	seq_putc(s, '{');
-	clk_show_tree(clk_dump_one, s, orphan_only);
-	seq_puts(s, "}\n");
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_dump);
-
-/*
- * This can be dangerous, therefore don't provide any real compile time
- * configuration option for this feature.
- * People who want to use this will need to modify the source code directly.
- */
-#undef CLOCK_ALLOW_WRITE_DEBUGFS
-#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
-static int clk_rate_set(void *data, u64 val)
-{
-	struct clk_hw *hw = data;
-	struct clk *clk = clk_hw_get_clk(hw, "debugfs_rate_set");
-	int ret;
-
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
-
-	ret = clk_set_rate(clk, val);
-	clk_put(clk);
-
-	return ret;
-}
-
-#define clk_rate_mode	0644
-
-static int clk_phase_set(void *data, u64 val)
-{
-	struct clk_hw *hw = data;
-	struct clk *clk = clk_hw_get_clk(hw, "debugfs_phase_set");
-	int degrees = do_div(val, 360);
-	int ret;
-
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
-
-	ret = clk_set_phase(clk, degrees);
-	clk_put(clk);
-
-	return ret;
-}
-
-#define clk_phase_mode	0644
-
-static int clk_prepare_enable_set(void *data, u64 val)
-{
-	struct clk_hw *hw = data;
-	struct clk *clk = clk_hw_get_clk(hw, "debugfs_prepare_enable_set");
-	int ret = 0;
-
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
-
-	if (val)
-		ret = clk_prepare_enable(clk);
-	else
-		clk_disable_unprepare(clk);
-	clk_put(clk);
-
-	return ret;
-}
-
-static int clk_prepare_enable_get(void *data, u64 *val)
-{
-	struct clk_hw *hw = data;
-
-	*val = clk_hw_is_prepared(hw) && clk_hw_is_enabled(hw);
-	return 0;
-}
-
-DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get,
-			 clk_prepare_enable_set, "%llu\n");
-
-#else
-#define clk_rate_set	NULL
-#define clk_rate_mode	0444
-
-#define clk_phase_set	NULL
-#define clk_phase_mode	0644
-#endif
-
-static int clk_rate_get(void *data, u64 *val)
-{
-	struct clk_hw *hw = data;
-	struct clk *clk = clk_hw_get_clk(hw, "debugfs_rate_get");
-
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
-
-	*val = clk_get_rate(clk);
-	clk_put(clk);
-
-	return 0;
-}
-
-DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n");
-
-static int clk_phase_get(void *data, u64 *val)
-{
-	struct clk_hw *hw = data;
-	struct clk *clk = clk_hw_get_clk(hw, "debugfs_phase_get");
-
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
-
-	*val = clk_get_phase(clk);
-	clk_put(clk);
-
-	return 0;
-}
-
-DEFINE_DEBUGFS_ATTRIBUTE(clk_phase_fops, clk_phase_get, clk_phase_set, "%llu\n");
-
-static const struct {
-	unsigned long flag;
-	const char *name;
-} clk_flags[] = {
-#define ENTRY(f) { f, #f }
-	ENTRY(CLK_SET_RATE_GATE),
-	ENTRY(CLK_SET_PARENT_GATE),
-	ENTRY(CLK_SET_RATE_PARENT),
-	ENTRY(CLK_IGNORE_UNUSED),
-	ENTRY(CLK_GET_RATE_NOCACHE),
-	ENTRY(CLK_SET_RATE_NO_REPARENT),
-	ENTRY(CLK_GET_ACCURACY_NOCACHE),
-	ENTRY(CLK_RECALC_NEW_RATES),
-	ENTRY(CLK_SET_RATE_UNGATE),
-	ENTRY(CLK_IS_CRITICAL),
-	ENTRY(CLK_OPS_PARENT_ENABLE),
-	ENTRY(CLK_DUTY_CYCLE_PARENT),
-#undef ENTRY
-};
-
-static int clk_flags_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-	unsigned long flags = clk_hw_get_flags(hw);
-	unsigned int i;
-
-	for (i = 0; flags && i < ARRAY_SIZE(clk_flags); i++) {
-		if (flags & clk_flags[i].flag) {
-			seq_printf(s, "%s\n", clk_flags[i].name);
-			flags &= ~clk_flags[i].flag;
-		}
-	}
-	if (flags) {
-		/* Unknown flags */
-		seq_printf(s, "0x%lx\n", flags);
-	}
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_flags);
-
-static void clk_hw_show_parent_by_index(struct seq_file *s, struct clk_hw *hw,
-					unsigned int i, char terminator)
+void clk_hw_show_parent_by_index(struct seq_file *s, struct clk_hw *hw,
+				 unsigned int i, char terminator)
 {
 	struct clk_hw *parent;
 	struct clk_core *core = hw->core;
@@ -3725,227 +3499,15 @@ static void clk_hw_show_parent_by_index(struct seq_file *s, struct clk_hw *hw,
 
 	seq_putc(s, terminator);
 }
+EXPORT_SYMBOL_NS_GPL(clk_hw_show_parent_by_index, "clk-debug");
 
-static int possible_parents_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-	int i;
-
-	for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++)
-		clk_hw_show_parent_by_index(s, hw, i, ' ');
-
-	clk_hw_show_parent_by_index(s, hw, i, '\n');
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(possible_parents);
-
-static int current_parent_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-	struct clk_hw *parent = clk_hw_get_parent(hw);
-
-	if (parent)
-		seq_printf(s, "%s\n", clk_hw_get_name(parent));
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(current_parent);
-
-#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
-static ssize_t current_parent_write(struct file *file, const char __user *ubuf,
-				    size_t count, loff_t *ppos)
-{
-	struct seq_file *s = file->private_data;
-	struct clk *clk, *parent;
-	struct clk_hw *hw = s->private;
-	struct clk_hw *parent_hw;
-	u8 idx;
-	int ret;
-
-	ret = kstrtou8_from_user(ubuf, count, 0, &idx);
-	if (ret < 0)
-		return ret;
-
-	parent_hw = clk_hw_get_parent_by_index(hw, idx);
-	if (!parent_hw)
-		return -ENOENT;
-
-	clk = clk_hw_get_clk(hw, "debugfs_write");
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
-
-	parent = clk_hw_get_clk(parent_hw, "debugfs_write");
-	if (IS_ERR(parent)) {
-		ret = PTR_ERR(parent);
-		goto err;
-	}
-
-	ret = clk_set_parent(clk, parent);
-	if (!ret)
-		ret = count;
-
-	clk_put(parent);
-err:
-	clk_put(clk);
-	return ret;
-}
-
-static const struct file_operations current_parent_rw_fops = {
-	.open		= current_parent_open,
-	.write		= current_parent_write,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-#endif
-
-static void clk_hw_get_duty(struct clk_hw *hw, struct clk_duty *duty)
-{
-	memcpy(duty, &hw->core->duty, sizeof(*duty));
-}
-
-static int clk_duty_cycle_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-	struct clk_duty duty = { };
-
-	clk_hw_get_duty(hw, &duty);
-
-	seq_printf(s, "%u/%u\n", duty.num, duty.den);
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle);
-
-static int clk_min_rate_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-	unsigned long min_rate, max_rate;
-
-	clk_debug_get_rate_range(hw, &min_rate, &max_rate);
-	seq_printf(s, "%lu\n", min_rate);
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_min_rate);
-
-static int clk_max_rate_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-	unsigned long min_rate, max_rate;
-
-	clk_debug_get_rate_range(hw, &min_rate, &max_rate);
-	seq_printf(s, "%lu\n", max_rate);
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_max_rate);
-
-static int clk_accuracy_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-	struct clk *clk = clk_hw_get_clk(hw, "debugfs_accuracy");
-	unsigned long accuracy;
-
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
-
-	accuracy = clk_get_accuracy(clk);
-	seq_printf(s, "%lu\n", accuracy);
-	clk_put(clk);
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_accuracy);
-
-static int clk_prepare_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-
-	seq_printf(s, "%u\n", clk_hw_prepare_count(hw));
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_prepare);
-
-static int clk_enable_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-
-	seq_printf(s, "%u\n", clk_hw_enable_count(hw));
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_enable);
-
-static int clk_protect_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-
-	seq_printf(s, "%u\n", clk_hw_protect_count(hw));
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_protect);
-
-static unsigned int clk_hw_notifier_count(struct clk_hw *hw)
-{
-	return hw->core->notifier_count;
-}
-
-static int clk_notifier_show(struct seq_file *s, void *data)
-{
-	struct clk_hw *hw = s->private;
-
-	seq_printf(s, "%u\n", clk_hw_notifier_count(hw));
-
-	return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(clk_notifier);
-
-static struct dentry *clk_hw_debug_create_one(struct clk_hw *hw)
-{
-	struct dentry *root;
-
-	root = debugfs_create_dir(clk_hw_get_name(hw), rootdir);
-
-	debugfs_create_file("clk_rate", clk_rate_mode, root, hw, &clk_rate_fops);
-	debugfs_create_file("clk_min_rate", 0444, root, hw, &clk_min_rate_fops);
-	debugfs_create_file("clk_max_rate", 0444, root, hw, &clk_max_rate_fops);
-	debugfs_create_file("clk_accuracy", 0444, root, hw, &clk_accuracy_fops);
-	debugfs_create_file("clk_phase", clk_phase_mode, root, hw, &clk_phase_fops);
-	debugfs_create_file("clk_flags", 0444, root, hw, &clk_flags_fops);
-	debugfs_create_file("clk_prepare_count", 0444, root, hw, &clk_prepare_fops);
-	debugfs_create_file("clk_enable_count", 0444, root, hw, &clk_enable_fops);
-	debugfs_create_file("clk_protect_count", 0444, root, hw, &clk_protect_fops);
-	debugfs_create_file("clk_notifier_count", 0444, root, hw, &clk_notifier_fops);
-	debugfs_create_file("clk_duty_cycle", 0444, root, hw, &clk_duty_cycle_fops);
-#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
-	debugfs_create_file("clk_prepare_enable", 0644, root, hw,
-			    &clk_prepare_enable_fops);
-
-	if (clk_hw_get_num_parents(hw) > 1)
-		debugfs_create_file("clk_parent", 0644, root, hw,
-				    &current_parent_rw_fops);
-	else
-#endif
-	if (clk_hw_get_num_parents(hw) > 0)
-		debugfs_create_file("clk_parent", 0444, root, hw,
-				    &current_parent_fops);
-
-	if (clk_hw_get_num_parents(hw) > 1)
-		debugfs_create_file("clk_possible_parents", 0444, root, hw,
-				    &possible_parents_fops);
-
-	return root;
-}
+static struct dentry *(*clk_hw_debug_create_one)(struct clk_hw *hw);
 
 static void clk_core_debug_create_one(struct clk_core *core)
 {
 	struct clk_hw *hw = core->hw;
 
-	if (!inited)
+	if (!clk_hw_debug_create_one)
 		return;
 
 	core->dentry = clk_hw_debug_create_one(hw);
@@ -3969,6 +3531,13 @@ static void clk_debug_register(struct clk_core *core)
 	mutex_unlock(&clk_debug_lock);
 }
 
+static void clk_core_debug_remove_one(struct clk_core *core)
+{
+	hlist_del_init(&core->debug_node);
+	debugfs_remove_recursive(core->dentry);
+	core->dentry = NULL;
+}
+
  /**
  * clk_debug_unregister - remove a clk node from the debugfs clk directory
  * @core: the clk being removed from the debugfs clk directory
@@ -3980,68 +3549,36 @@ static void clk_debug_register(struct clk_core *core)
 static void clk_debug_unregister(struct clk_core *core)
 {
 	mutex_lock(&clk_debug_lock);
-	hlist_del_init(&core->debug_node);
-	debugfs_remove_recursive(core->dentry);
-	core->dentry = NULL;
+	clk_core_debug_remove_one(core);
 	mutex_unlock(&clk_debug_lock);
 }
 
-/**
- * clk_debug_init - lazily populate the debugfs clk directory
- *
- * clks are often initialized very early during boot before memory can be
- * dynamically allocated and well before debugfs is setup. This function
- * populates the debugfs clk directory once at boot-time when we know that
- * debugfs is setup. It should only be called once at boot-time, all other clks
- * added dynamically will be done so with clk_debug_register.
- */
-static int __init clk_debug_init(void)
+void clk_hw_debug_for_each_init(struct dentry *(*fn)(struct clk_hw *hw))
 {
 	struct clk_core *core;
 
-#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
-	pr_warn("\n");
-	pr_warn("********************************************************************\n");
-	pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
-	pr_warn("**                                                                **\n");
-	pr_warn("**  WRITEABLE clk DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n");
-	pr_warn("**                                                                **\n");
-	pr_warn("** This means that this kernel is built to expose clk operations  **\n");
-	pr_warn("** such as parent or rate setting, enabling, disabling, etc.      **\n");
-	pr_warn("** to userspace, which may compromise security on your system.    **\n");
-	pr_warn("**                                                                **\n");
-	pr_warn("** If you see this message and you are not debugging the          **\n");
-	pr_warn("** kernel, report this immediately to your vendor!                **\n");
-	pr_warn("**                                                                **\n");
-	pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
-	pr_warn("********************************************************************\n");
-#endif
-
-	rootdir = debugfs_create_dir("clk", NULL);
-
-	debugfs_create_file("clk_summary", 0444, rootdir, (void *)0UL,
-			    &clk_summary_fops);
-	debugfs_create_file("clk_dump", 0444, rootdir, (void *)0UL,
-			    &clk_dump_fops);
-	debugfs_create_file("clk_orphan_summary", 0444, rootdir, (void *)1UL,
-			    &clk_summary_fops);
-	debugfs_create_file("clk_orphan_dump", 0444, rootdir, (void *)1UL,
-			    &clk_dump_fops);
-
 	mutex_lock(&clk_debug_lock);
-	inited = 1;
+	clk_hw_debug_create_one = fn;
 	hlist_for_each_entry(core, &clk_debug_list, debug_node)
 		clk_core_debug_create_one(core);
 	mutex_unlock(&clk_debug_lock);
-
-	return 0;
 }
-late_initcall(clk_debug_init);
+EXPORT_SYMBOL_NS_GPL(clk_hw_debug_for_each_init, "clk-debug");
+
+void clk_hw_debug_exit(void)
+{
+	struct clk_core *core;
+
+	mutex_lock(&clk_debug_lock);
+	clk_hw_debug_create_one = NULL;
+	hlist_for_each_entry(core, &clk_debug_list, debug_node)
+		clk_core_debug_remove_one(core);
+	mutex_unlock(&clk_debug_lock);
+}
+EXPORT_SYMBOL_NS_GPL(clk_hw_debug_exit, "clk-debug");
 #else
 static inline void clk_debug_register(struct clk_core *core) { }
-static inline void clk_debug_unregister(struct clk_core *core)
-{
-}
+static inline void clk_debug_unregister(struct clk_core *core) { }
 #endif
 
 static void clk_core_reparent_orphans_nolock(void)
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] clk: Make debugfs code into a loadable kernel module
  2025-01-08  0:58 ` [PATCH 4/4] clk: Make debugfs code into a loadable kernel module Stephen Boyd
@ 2025-01-10  6:45   ` kernel test robot
  2025-01-11 11:51   ` kernel test robot
  2025-01-22 23:29   ` Jeff Johnson
  2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-01-10  6:45 UTC (permalink / raw)
  To: Stephen Boyd, Michael Turquette
  Cc: oe-kbuild-all, linux-kernel, linux-clk, patches

Hi Stephen,

kernel test robot noticed the following build errors:

[auto build test ERROR on fac04efc5c793dccbd07e2d59af9f90b7fc0dca4]

url:    https://github.com/intel-lab-lkp/linux/commits/Stephen-Boyd/clk-Prepare-clk_debug_create_one-to-be-split-off/20250108-085933
base:   fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
patch link:    https://lore.kernel.org/r/20250108005854.2973184-5-sboyd%40kernel.org
patch subject: [PATCH 4/4] clk: Make debugfs code into a loadable kernel module
config: parisc-randconfig-001-20250110 (https://download.01.org/0day-ci/archive/20250110/202501101445.zIwSpQgC-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250110/202501101445.zIwSpQgC-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501101445.zIwSpQgC-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/clk/clk.c: In function 'clk_core_debug_create_one':
>> drivers/clk/clk.c:3513:13: error: 'struct clk_core' has no member named 'dentry'
    3513 |         core->dentry = clk_hw_debug_create_one(hw);
         |             ^~
   drivers/clk/clk.c:3515:47: error: 'struct clk_core' has no member named 'dentry'
    3515 |                 core->ops->debug_init(hw, core->dentry);
         |                                               ^~
   drivers/clk/clk.c: In function 'clk_debug_register':
>> drivers/clk/clk.c:3529:29: error: 'struct clk_core' has no member named 'debug_node'
    3529 |         hlist_add_head(&core->debug_node, &clk_debug_list);
         |                             ^~
   drivers/clk/clk.c: In function 'clk_core_debug_remove_one':
   drivers/clk/clk.c:3536:29: error: 'struct clk_core' has no member named 'debug_node'
    3536 |         hlist_del_init(&core->debug_node);
         |                             ^~
   drivers/clk/clk.c:3537:38: error: 'struct clk_core' has no member named 'dentry'
    3537 |         debugfs_remove_recursive(core->dentry);
         |                                      ^~
   drivers/clk/clk.c:3538:13: error: 'struct clk_core' has no member named 'dentry'
    3538 |         core->dentry = NULL;
         |             ^~
   In file included from include/linux/container_of.h:5,
                    from include/linux/kernel.h:22,
                    from include/linux/clk.h:13,
                    from drivers/clk/clk.c:9:
   drivers/clk/clk.c: In function 'clk_hw_debug_for_each_init':
>> include/linux/container_of.h:20:54: error: 'struct clk_core' has no member named 'debug_node'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                                      ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/compiler_types.h:483:27: error: expression in static assertion is not an integer
     483 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   In file included from include/uapi/linux/posix_types.h:5,
                    from include/uapi/linux/types.h:14,
                    from include/linux/types.h:6,
                    from include/linux/kasan-checks.h:5,
                    from include/asm-generic/rwonce.h:26,
                    from ./arch/parisc/include/generated/asm/rwonce.h:1,
                    from include/linux/compiler.h:324,
                    from include/linux/err.h:5,
                    from include/linux/clk.h:12:
>> include/linux/stddef.h:16:33: error: 'struct clk_core' has no member named 'debug_node'
      16 | #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
         |                                 ^~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:23:28: note: in expansion of macro 'offsetof'
      23 |         ((type *)(__mptr - offsetof(type, member))); })
         |                            ^~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/mutex.h:15,
                    from include/linux/notifier.h:14,
                    from include/linux/clk.h:14:
>> include/linux/list.h:1157:42: error: 'struct clk_core' has no member named 'debug_node'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                                          ^~
   include/linux/list.h:1144:19: note: in definition of macro 'hlist_entry_safe'
    1144 |         ({ typeof(ptr) ____ptr = (ptr); \
         |                   ^~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/list.h:1157:42: error: 'struct clk_core' has no member named 'debug_node'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                                          ^~
   include/linux/list.h:1144:35: note: in definition of macro 'hlist_entry_safe'
    1144 |         ({ typeof(ptr) ____ptr = (ptr); \
         |                                   ^~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:20:35: error: invalid type argument of unary '*' (have 'int')
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                   ^~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/container_of.h:20:54: error: 'struct clk_core' has no member named 'debug_node'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                                      ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:21:35: error: invalid type argument of unary '*' (have 'int')
      21 |                       __same_type(*(ptr), void),                        \
         |                                   ^~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |                       __same_type(*(ptr), void),                        \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/compiler_types.h:483:27: error: expression in static assertion is not an integer
     483 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/stddef.h:16:33: error: 'struct clk_core' has no member named 'debug_node'
      16 | #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
         |                                 ^~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:23:28: note: in expansion of macro 'offsetof'
      23 |         ((type *)(__mptr - offsetof(type, member))); })
         |                            ^~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   drivers/clk/clk.c: In function 'clk_hw_debug_exit':
>> include/linux/container_of.h:20:54: error: 'struct clk_core' has no member named 'debug_node'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                                      ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/compiler_types.h:483:27: error: expression in static assertion is not an integer
     483 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/stddef.h:16:33: error: 'struct clk_core' has no member named 'debug_node'
      16 | #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
         |                                 ^~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:23:28: note: in expansion of macro 'offsetof'
      23 |         ((type *)(__mptr - offsetof(type, member))); })
         |                            ^~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/list.h:1157:42: error: 'struct clk_core' has no member named 'debug_node'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                                          ^~
   include/linux/list.h:1144:19: note: in definition of macro 'hlist_entry_safe'
    1144 |         ({ typeof(ptr) ____ptr = (ptr); \
         |                   ^~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/list.h:1157:42: error: 'struct clk_core' has no member named 'debug_node'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                                          ^~
   include/linux/list.h:1144:35: note: in definition of macro 'hlist_entry_safe'
    1144 |         ({ typeof(ptr) ____ptr = (ptr); \
         |                                   ^~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:20:35: error: invalid type argument of unary '*' (have 'int')
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                   ^~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/container_of.h:20:54: error: 'struct clk_core' has no member named 'debug_node'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                                      ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:21:35: error: invalid type argument of unary '*' (have 'int')
      21 |                       __same_type(*(ptr), void),                        \
         |                                   ^~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |                       __same_type(*(ptr), void),                        \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/compiler_types.h:483:27: error: expression in static assertion is not an integer
     483 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/stddef.h:16:33: error: 'struct clk_core' has no member named 'debug_node'
      16 | #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
         |                                 ^~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:23:28: note: in expansion of macro 'offsetof'
      23 |         ((type *)(__mptr - offsetof(type, member))); })
         |                            ^~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~


vim +3513 drivers/clk/clk.c

06c1e876918854 Stephen Boyd       2025-01-07  3505  
06c1e876918854 Stephen Boyd       2025-01-07  3506  static void clk_core_debug_create_one(struct clk_core *core)
06c1e876918854 Stephen Boyd       2025-01-07  3507  {
06c1e876918854 Stephen Boyd       2025-01-07  3508  	struct clk_hw *hw = core->hw;
06c1e876918854 Stephen Boyd       2025-01-07  3509  
22ece94fca2e92 Stephen Boyd       2025-01-07  3510  	if (!clk_hw_debug_create_one)
06c1e876918854 Stephen Boyd       2025-01-07  3511  		return;
06c1e876918854 Stephen Boyd       2025-01-07  3512  
94dffe79bcc703 Stephen Boyd       2025-01-07 @3513  	core->dentry = clk_hw_debug_create_one(hw);
8a26bbbb932021 Greg Kroah-Hartman 2018-05-29  3514  	if (core->ops->debug_init)
06c1e876918854 Stephen Boyd       2025-01-07  3515  		core->ops->debug_init(hw, core->dentry);
4dff95dc9477a3 Stephen Boyd       2015-04-30  3516  }
b2476490ef1113 Mike Turquette     2012-03-15  3517  
4dff95dc9477a3 Stephen Boyd       2015-04-30  3518  /**
6e5ab41b1064ee Stephen Boyd       2015-04-30  3519   * clk_debug_register - add a clk node to the debugfs clk directory
6e5ab41b1064ee Stephen Boyd       2015-04-30  3520   * @core: the clk being added to the debugfs clk directory
4dff95dc9477a3 Stephen Boyd       2015-04-30  3521   *
6e5ab41b1064ee Stephen Boyd       2015-04-30  3522   * Dynamically adds a clk to the debugfs clk directory if debugfs has been
6e5ab41b1064ee Stephen Boyd       2015-04-30  3523   * initialized.  Otherwise it bails out early since the debugfs clk directory
4dff95dc9477a3 Stephen Boyd       2015-04-30  3524   * will be created lazily by clk_debug_init as part of a late_initcall.
4dff95dc9477a3 Stephen Boyd       2015-04-30  3525   */
8a26bbbb932021 Greg Kroah-Hartman 2018-05-29  3526  static void clk_debug_register(struct clk_core *core)
4dff95dc9477a3 Stephen Boyd       2015-04-30  3527  {
4dff95dc9477a3 Stephen Boyd       2015-04-30  3528  	mutex_lock(&clk_debug_lock);
4dff95dc9477a3 Stephen Boyd       2015-04-30 @3529  	hlist_add_head(&core->debug_node, &clk_debug_list);
06c1e876918854 Stephen Boyd       2025-01-07  3530  	clk_core_debug_create_one(core);
4dff95dc9477a3 Stephen Boyd       2015-04-30  3531  	mutex_unlock(&clk_debug_lock);
b2476490ef1113 Mike Turquette     2012-03-15  3532  }
035a61c314eb3d Tomeu Vizoso       2015-01-23  3533  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] clk: Make debugfs code into a loadable kernel module
  2025-01-08  0:58 ` [PATCH 4/4] clk: Make debugfs code into a loadable kernel module Stephen Boyd
  2025-01-10  6:45   ` kernel test robot
@ 2025-01-11 11:51   ` kernel test robot
  2025-01-22 23:29   ` Jeff Johnson
  2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-01-11 11:51 UTC (permalink / raw)
  To: Stephen Boyd, Michael Turquette
  Cc: oe-kbuild-all, linux-kernel, linux-clk, patches

Hi Stephen,

kernel test robot noticed the following build warnings:

[auto build test WARNING on fac04efc5c793dccbd07e2d59af9f90b7fc0dca4]

url:    https://github.com/intel-lab-lkp/linux/commits/Stephen-Boyd/clk-Prepare-clk_debug_create_one-to-be-split-off/20250108-085933
base:   fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
patch link:    https://lore.kernel.org/r/20250108005854.2973184-5-sboyd%40kernel.org
patch subject: [PATCH 4/4] clk: Make debugfs code into a loadable kernel module
config: loongarch-randconfig-r054-20250111 (https://download.01.org/0day-ci/archive/20250111/202501111916.yahwykQO-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250111/202501111916.yahwykQO-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501111916.yahwykQO-lkp@intel.com/

All warnings (new ones prefixed by >>):

                    from include/linux/kernel.h:22,
                    from include/linux/clk.h:13,
                    from drivers/clk/clk.c:9:
   drivers/clk/clk.c: In function 'clk_hw_debug_for_each_init':
   include/linux/container_of.h:20:54: error: 'struct clk_core' has no member named 'debug_node'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                                      ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:483:27: error: expression in static assertion is not an integer
     483 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   In file included from include/uapi/linux/posix_types.h:5,
                    from include/uapi/linux/types.h:14,
                    from include/linux/types.h:6,
                    from include/linux/kasan-checks.h:5,
                    from include/asm-generic/rwonce.h:26,
                    from ./arch/loongarch/include/generated/asm/rwonce.h:1,
                    from include/linux/compiler.h:324,
                    from include/linux/err.h:5,
                    from include/linux/clk.h:12:
   include/linux/stddef.h:16:33: error: 'struct clk_core' has no member named 'debug_node'
      16 | #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
         |                                 ^~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:23:28: note: in expansion of macro 'offsetof'
      23 |         ((type *)(__mptr - offsetof(type, member))); })
         |                            ^~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/mutex.h:15,
                    from include/linux/notifier.h:14,
                    from include/linux/clk.h:14:
   include/linux/list.h:1157:42: error: 'struct clk_core' has no member named 'debug_node'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                                          ^~
   include/linux/list.h:1144:19: note: in definition of macro 'hlist_entry_safe'
    1144 |         ({ typeof(ptr) ____ptr = (ptr); \
         |                   ^~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/list.h:1157:42: error: 'struct clk_core' has no member named 'debug_node'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                                          ^~
   include/linux/list.h:1144:35: note: in definition of macro 'hlist_entry_safe'
    1144 |         ({ typeof(ptr) ____ptr = (ptr); \
         |                                   ^~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/container_of.h:19:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
      19 |         void *__mptr = (void *)(ptr);                                   \
         |                        ^
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:20:35: error: invalid type argument of unary '*' (have 'int')
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                   ^~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:20:54: error: 'struct clk_core' has no member named 'debug_node'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                                      ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:21:35: error: invalid type argument of unary '*' (have 'int')
      21 |                       __same_type(*(ptr), void),                        \
         |                                   ^~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |                       __same_type(*(ptr), void),                        \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:483:27: error: expression in static assertion is not an integer
     483 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
--
   include/linux/container_of.h:23:28: note: in expansion of macro 'offsetof'
      23 |         ((type *)(__mptr - offsetof(type, member))); })
         |                            ^~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3562:9: note: in expansion of macro 'hlist_for_each_entry'
    3562 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   drivers/clk/clk.c: In function 'clk_hw_debug_exit':
   include/linux/container_of.h:20:54: error: 'struct clk_core' has no member named 'debug_node'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                                      ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:483:27: error: expression in static assertion is not an integer
     483 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/stddef.h:16:33: error: 'struct clk_core' has no member named 'debug_node'
      16 | #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
         |                                 ^~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:23:28: note: in expansion of macro 'offsetof'
      23 |         ((type *)(__mptr - offsetof(type, member))); })
         |                            ^~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1155:20: note: in expansion of macro 'hlist_entry_safe'
    1155 |         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/list.h:1157:42: error: 'struct clk_core' has no member named 'debug_node'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                                          ^~
   include/linux/list.h:1144:19: note: in definition of macro 'hlist_entry_safe'
    1144 |         ({ typeof(ptr) ____ptr = (ptr); \
         |                   ^~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/list.h:1157:42: error: 'struct clk_core' has no member named 'debug_node'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                                          ^~
   include/linux/list.h:1144:35: note: in definition of macro 'hlist_entry_safe'
    1144 |         ({ typeof(ptr) ____ptr = (ptr); \
         |                                   ^~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/container_of.h:19:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
      19 |         void *__mptr = (void *)(ptr);                                   \
         |                        ^
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:20:35: error: invalid type argument of unary '*' (have 'int')
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                   ^~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:20:54: error: 'struct clk_core' has no member named 'debug_node'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                                      ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/container_of.h:21:35: error: invalid type argument of unary '*' (have 'int')
      21 |                       __same_type(*(ptr), void),                        \
         |                                   ^~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |                       __same_type(*(ptr), void),                        \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
         |                                        ^~~~~~~~~~~~
   include/linux/list.h:1145:22: note: in expansion of macro 'hlist_entry'
    1145 |            ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
         |                      ^~~~~~~~~~~
   include/linux/list.h:1157:20: note: in expansion of macro 'hlist_entry_safe'
    1157 |              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
         |                    ^~~~~~~~~~~~~~~~
   drivers/clk/clk.c:3574:9: note: in expansion of macro 'hlist_for_each_entry'
    3574 |         hlist_for_each_entry(core, &clk_debug_list, debug_node)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:483:27: error: expression in static assertion is not an integer
     483 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:1134:40: note: in expansion of macro 'container_of'
    1134 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member)


vim +19 include/linux/container_of.h

d2a8ebbf8192b8 Andy Shevchenko  2021-11-08   9  
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  10  /**
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  11   * container_of - cast a member of a structure out to the containing structure
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  12   * @ptr:	the pointer to the member.
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  13   * @type:	the type of the container struct this is embedded in.
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  14   * @member:	the name of the member within the struct.
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  15   *
7376e561fd2e01 Sakari Ailus     2022-10-24  16   * WARNING: any const qualifier of @ptr is lost.
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  17   */
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  18  #define container_of(ptr, type, member) ({				\
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08 @19  	void *__mptr = (void *)(ptr);					\
e1edc277e6f6df Rasmus Villemoes 2021-11-08  20  	static_assert(__same_type(*(ptr), ((type *)0)->member) ||	\
e1edc277e6f6df Rasmus Villemoes 2021-11-08  21  		      __same_type(*(ptr), void),			\
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  22  		      "pointer type mismatch in container_of()");	\
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  23  	((type *)(__mptr - offsetof(type, member))); })
d2a8ebbf8192b8 Andy Shevchenko  2021-11-08  24  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] clk: Make debugfs code into a loadable kernel module
  2025-01-08  0:58 ` [PATCH 4/4] clk: Make debugfs code into a loadable kernel module Stephen Boyd
  2025-01-10  6:45   ` kernel test robot
  2025-01-11 11:51   ` kernel test robot
@ 2025-01-22 23:29   ` Jeff Johnson
  2 siblings, 0 replies; 8+ messages in thread
From: Jeff Johnson @ 2025-01-22 23:29 UTC (permalink / raw)
  To: Stephen Boyd, Michael Turquette; +Cc: linux-kernel, linux-clk, patches

On 1/7/25 16:58, Stephen Boyd wrote:
> Split the debugfs code for the clk framework into a separate loadable
> kernel module. This allows the debugfs code to be loaded later, or not
> at all.
> 
> Signed-off-by: Stephen Boyd <sboyd@kernel.org>

...

> +MODULE_LICENSE("GPL");

Since commit 1fffe7a34c89 ("script: modpost: emit a warning when the
description is missing"), a module without a MODULE_DESCRIPTION() will
result in a warning with make W=1. Please add a MODULE_DESCRIPTION()
to avoid this warning.


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-01-22 23:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-08  0:58 [PATCH 0/4] clk: Move debugfs to a loadable kernel module Stephen Boyd
2025-01-08  0:58 ` [PATCH 1/4] clk: Prepare clk_debug_create_one() to be split off Stephen Boyd
2025-01-08  0:58 ` [PATCH 2/4] clk: Use struct clk_hw instead of struct clk_core for debugfs Stephen Boyd
2025-01-08  0:58 ` [PATCH 3/4] clk: Iterate instead of recurse for debugfs printing Stephen Boyd
2025-01-08  0:58 ` [PATCH 4/4] clk: Make debugfs code into a loadable kernel module Stephen Boyd
2025-01-10  6:45   ` kernel test robot
2025-01-11 11:51   ` kernel test robot
2025-01-22 23:29   ` Jeff Johnson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).