[PATCH] clk: add clock panic dump in tree-view
Shawn Lin
shawn.lin at rock-chips.com
Thu May 10 01:50:05 PDT 2018
Sometimes it's useful and for debugging to check the whole system clock
configuration in tree-view upon panic.
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---
Documentation/admin-guide/kernel-parameters.txt | 3 ++
drivers/clk/clk.c | 67 +++++++++++++++++++++++++
2 files changed, 70 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 3487be7..7bbdb6f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -519,6 +519,9 @@
debug and development, but should not be needed on a
platform with proper driver support. For more
information, see Documentation/clk.txt.
+ clk_panic_dump
+ [CLK]
+ Dump the whole clock tree-view upon panic.
clock= [BUGS=X86-32, HW] gettimeofday clocksource override.
[Deprecated]
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 9ae92aa..adb5537 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2802,6 +2802,73 @@ static inline void clk_debug_unregister(struct clk_core *core)
}
#endif
+static bool clk_pdump_enable;
+static int __init clk_pdump_setup(char *__unused)
+{
+ clk_pdump_enable = true;
+ return 1;
+}
+__setup("clk_panic_dump", clk_pdump_setup);
+
+static void clk_pdump_show_one(struct clk_core *c, int level)
+{
+ if (!c)
+ return;
+
+ pr_err("%*s%-*s %11d %12d %11lu %10lu %-3d\n",
+ level * 3 + 1, "", 30 - level * 3, c->name,
+ c->enable_count, c->prepare_count, clk_core_get_rate(c),
+ clk_core_get_accuracy(c), clk_core_get_phase(c));
+}
+
+static void clk_pdump_show_subtree(struct clk_core *c, int level)
+{
+ struct clk_core *child;
+
+ if (!c)
+ return;
+
+ clk_pdump_show_one(c, level);
+
+ hlist_for_each_entry(child, &c->children, child_node)
+ clk_pdump_show_subtree(child, level + 1);
+}
+
+static int clk_panic_dump(struct notifier_block *this, unsigned long ev,
+ void *ptr)
+{
+ struct clk_core *c;
+
+ if (!clk_pdump_enable)
+ return 0;
+
+ pr_err("clock panic dump:\n");
+ pr_err(" clock enable_cnt prepare_cnt rate accuracy phase\n");
+ pr_err("----------------------------------------------------------------------------------------\n");
+
+ clk_prepare_lock();
+
+ hlist_for_each_entry(c, &clk_root_list, child_node)
+ clk_pdump_show_subtree(c, 0);
+ hlist_for_each_entry(c, &clk_orphan_list, child_node)
+ clk_pdump_show_subtree(c, 0);
+
+ clk_prepare_unlock();
+
+ return 0;
+}
+
+static struct notifier_block clk_pdump_block = {
+ .notifier_call = clk_panic_dump,
+};
+
+static int clk_register_pdump(void)
+{
+ atomic_notifier_chain_register(&panic_notifier_list, &clk_pdump_block);
+ return 0;
+}
+late_initcall_sync(clk_register_pdump);
+
/**
* __clk_core_init - initialize the data structures in a struct clk_core
* @core: clk_core being initialized
--
1.9.1
More information about the Linux-rockchip
mailing list