summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2018-01-03 12:06:16 +0100
committerStephen Boyd <sboyd@codeaurora.org>2018-01-10 13:13:22 -0800
commita6059ab98130fb561157682d320c51c5ccd4b647 (patch)
treee990364caee2d7c1eac84fe200a490201c04cb3c /drivers/clk/clk.c
parentf7ae75036762618ecc2cc7ae6fb4f6a74af92afb (diff)
downloadlinux-a6059ab98130fb561157682d320c51c5ccd4b647.tar.bz2
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/clk.c')
-rw-r--r--drivers/clk/clk.c57
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;