diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2018-01-03 12:06:16 +0100 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2018-01-10 22:13:22 +0100 |
commit | a6059ab98130fb561157682d320c51c5ccd4b647 (patch) | |
tree | e990364caee2d7c1eac84fe200a490201c04cb3c /drivers/clk | |
parent | clk: Improve flags doc for of_clk_detect_critical() (diff) | |
download | linux-a6059ab98130fb561157682d320c51c5ccd4b647.tar.xz linux-a6059ab98130fb561157682d320c51c5ccd4b647.zip |
clk: Show symbolic clock flags in debugfs
Currently the virtual "clk_flags" file in debugfs shows the numeric
value of the top-level framework flags for the specified clock.
Hence the user must manually interpret these values.
Moreover, on big-endian 64-bit systems, the wrong half of the value is
shown, due to the cast from "unsigned long *" to "u32 *".
Fix both issues by showing the symbolic flag names instead.
Any non-standard flags are shown as a hex number.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/clk.c | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index fe2d43e34216..479a3ee9cfe2 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -24,6 +24,7 @@ #include <linux/pm_runtime.h> #include <linux/sched.h> #include <linux/clkdev.h> +#include <linux/stringify.h> #include "clk.h" @@ -2554,6 +2555,58 @@ static const struct file_operations clk_dump_fops = { .release = single_release, }; +static const struct { + unsigned long flag; + const char *name; +} clk_flags[] = { +#define ENTRY(f) { f, __stringify(f) } + ENTRY(CLK_SET_RATE_GATE), + ENTRY(CLK_SET_PARENT_GATE), + ENTRY(CLK_SET_RATE_PARENT), + ENTRY(CLK_IGNORE_UNUSED), + ENTRY(CLK_IS_BASIC), + 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), +#undef ENTRY +}; + +static int clk_flags_dump(struct seq_file *s, void *data) +{ + struct clk_core *core = s->private; + unsigned long flags = core->flags; + 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; +} + +static int clk_flags_open(struct inode *inode, struct file *file) +{ + return single_open(file, clk_flags_dump, inode->i_private); +} + +static const struct file_operations clk_flags_fops = { + .open = clk_flags_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static int possible_parents_dump(struct seq_file *s, void *data) { struct clk_core *core = s->private; @@ -2610,8 +2663,8 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) if (!d) goto err_out; - d = debugfs_create_x32("clk_flags", S_IRUGO, core->dentry, - (u32 *)&core->flags); + d = debugfs_create_file("clk_flags", 0444, core->dentry, core, + &clk_flags_fops); if (!d) goto err_out; |