[PATCH] clk: Allow phase adjustment from debugfs

From: John Keeping
Date: Thu Apr 20 2023 - 07:04:37 EST


For testing it may be useful to manually adjust a clock's phase. Add
support for writing to the existing clk_phase debugfs file, with the
written value clamped to [0, 360) to match the behaviour of the
clk_set_phase() function.

This is a dangerous feature, so use the existing define
CLOCK_ALLOW_WRITE_DEBUGFS to allow it only if the source is modified.

Signed-off-by: John Keeping <john@xxxxxxxxxxxx>
---
drivers/clk/clk.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 27c30a533759..2d3b6869f3f6 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3297,6 +3297,21 @@ static int clk_rate_set(void *data, u64 val)

#define clk_rate_mode 0644

+static int clk_phase_set(void *data, u64 val)
+{
+ struct clk_core *core = data;
+ int degrees = do_div(val, 360);
+ int ret;
+
+ clk_prepare_lock();
+ ret = clk_core_set_phase_nolock(core, degrees);
+ clk_prepare_unlock();
+
+ return ret;
+}
+
+#define clk_phase_mode 0644
+
static int clk_prepare_enable_set(void *data, u64 val)
{
struct clk_core *core = data;
@@ -3324,6 +3339,9 @@ DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get,
#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)
@@ -3339,6 +3357,16 @@ static int clk_rate_get(void *data, u64 *val)

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;
+
+ *val = core->phase;
+ 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;
@@ -3529,7 +3557,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
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_u32("clk_phase", 0444, root, &core->phase);
+ 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);
--
2.40.0