]> nv-tegra.nvidia Code Review - linux-2.6.git/commitdiff
ARM: tegra: clock: Add debugfs clock set methods
authorAlex Frid <afrid@nvidia.com>
Sat, 8 Jan 2011 03:11:26 +0000 (19:11 -0800)
committerDan Willemsen <dwillemsen@nvidia.com>
Thu, 1 Dec 2011 05:41:56 +0000 (21:41 -0800)
Implemented debugfs clock write mechanism (disabled by default).
Expanded and fixed debugfs clock nodes to properly read clock
parent and rate.

Original-Change-Id: I9f20994d0829634e09f4bccd6fce6c7c8b5bf844
Reviewed-on: http://git-master/r/15315
Tested-by: Amit Kamath <akamath@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Rebase-Id: Ra802d13d77e74c6e8def92a93c08157f8eb888fe

arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/clock.c

index d20ab5b559ffedf2eb47a04d3b1f415a1d3305ff..87b0f8a69fe3c5c13f2ab37e3f59558c5e093242 100644 (file)
@@ -163,4 +163,9 @@ config WIFI_CONTROL_FUNC
        help
          Enables Power/Reset/Carddetect function abstraction
 
+config TEGRA_CLOCK_DEBUG_WRITE
+       bool "Enable debugfs write access to clock tree"
+       depends on DEBUG_FS
+       default n
+
 endif
index 1f68b97a584ce589d8be0ca8bbf0fd1466bc9921..889c032767f416de28fd0b49759994069e4f31f3 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/uaccess.h>
 
 #include <mach/clk.h>
 
@@ -773,6 +774,88 @@ static const struct file_operations possible_parents_fops = {
        .release        = single_release,
 };
 
+static int parent_show(struct seq_file *s, void *data)
+{
+       struct clk *c = s->private;
+       struct clk *p = clk_get_parent(c);
+
+       seq_printf(s, "%s\n", p ? p->name : "clk_root");
+       return 0;
+}
+
+static int parent_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, parent_show, inode->i_private);
+}
+
+static int rate_get(void *data, u64 *val)
+{
+       struct clk *c = (struct clk *)data;
+       *val = (u64)clk_get_rate(c);
+       return 0;
+}
+
+#ifdef CONFIG_TEGRA_CLOCK_DEBUG_WRITE
+
+static const mode_t parent_rate_mode =  S_IRUGO | S_IWUGO;
+
+static ssize_t parent_write(struct file *file,
+       const char __user *userbuf, size_t count, loff_t *ppos)
+{
+       struct seq_file *s = file->private_data;
+       struct clk *c = s->private;
+       struct clk *p = NULL;
+       char buf[32];
+
+       if (sizeof(buf) <= count)
+               return -EINVAL;
+
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       /* terminate buffer and trim - white spaces may be appended
+        *  at the end when invoked from shell command line */
+       buf[count]='\0';
+       strim(buf);
+
+       p = tegra_get_clock_by_name(buf);
+       if (!p)
+               return -EINVAL;
+
+       clk_set_parent(c, p);
+       return count;
+}
+
+static const struct file_operations parent_fops = {
+       .open           = parent_open,
+       .read           = seq_read,
+       .write          = parent_write,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int rate_set(void *data, u64 val)
+{
+       struct clk *c = (struct clk *)data;
+       clk_set_rate(c, (unsigned long)val);
+       return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(rate_fops, rate_get, rate_set, "%llu\n");
+
+#else
+
+static const mode_t parent_rate_mode =  S_IRUGO;
+
+static const struct file_operations parent_fops = {
+       .open           = parent_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+DEFINE_SIMPLE_ATTRIBUTE(rate_fops, rate_get, NULL, "%llu\n");
+#endif
+
 static int clk_debugfs_register_one(struct clk *c)
 {
        struct dentry *d;
@@ -786,11 +869,17 @@ static int clk_debugfs_register_one(struct clk *c)
        if (!d)
                goto err_out;
 
-       d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+       d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
        if (!d)
                goto err_out;
 
-       d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+       d = debugfs_create_file(
+               "parent", parent_rate_mode, c->dent, c, &parent_fops);
+       if (!d)
+               goto err_out;
+
+       d = debugfs_create_file(
+               "rate", parent_rate_mode, c->dent, c, &rate_fops);
        if (!d)
                goto err_out;