|
@@ -348,3 +348,110 @@ void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
|
|
|
*/
|
|
|
|
|
|
void __init s3c_disable_clocks(struct clk *clkp, int nr_clks)
|
|
|
+{
|
|
|
+ for (; nr_clks > 0; nr_clks--, clkp++)
|
|
|
+ (clkp->enable)(clkp, 0);
|
|
|
+}
|
|
|
+
|
|
|
+/* initialise all the clocks */
|
|
|
+
|
|
|
+int __init s3c24xx_register_baseclocks(unsigned long xtal)
|
|
|
+{
|
|
|
+ printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");
|
|
|
+
|
|
|
+ clk_xtal.rate = xtal;
|
|
|
+
|
|
|
+ /* register our clocks */
|
|
|
+
|
|
|
+ if (s3c24xx_register_clock(&clk_xtal) < 0)
|
|
|
+ printk(KERN_ERR "failed to register master xtal\n");
|
|
|
+
|
|
|
+ if (s3c24xx_register_clock(&clk_mpll) < 0)
|
|
|
+ printk(KERN_ERR "failed to register mpll clock\n");
|
|
|
+
|
|
|
+ if (s3c24xx_register_clock(&clk_upll) < 0)
|
|
|
+ printk(KERN_ERR "failed to register upll clock\n");
|
|
|
+
|
|
|
+ if (s3c24xx_register_clock(&clk_f) < 0)
|
|
|
+ printk(KERN_ERR "failed to register cpu fclk\n");
|
|
|
+
|
|
|
+ if (s3c24xx_register_clock(&clk_h) < 0)
|
|
|
+ printk(KERN_ERR "failed to register cpu hclk\n");
|
|
|
+
|
|
|
+ if (s3c24xx_register_clock(&clk_p) < 0)
|
|
|
+ printk(KERN_ERR "failed to register cpu pclk\n");
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
|
|
+/* debugfs support to trace clock tree hierarchy and attributes */
|
|
|
+
|
|
|
+static struct dentry *clk_debugfs_root;
|
|
|
+
|
|
|
+static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
|
|
|
+{
|
|
|
+ struct clk *child;
|
|
|
+ const char *state;
|
|
|
+ char buf[255] = { 0 };
|
|
|
+ int n = 0;
|
|
|
+
|
|
|
+ if (c->name)
|
|
|
+ n = snprintf(buf, sizeof(buf) - 1, "%s", c->name);
|
|
|
+
|
|
|
+ if (c->devname)
|
|
|
+ n += snprintf(buf + n, sizeof(buf) - 1 - n, ":%s", c->devname);
|
|
|
+
|
|
|
+ state = (c->usage > 0) ? "on" : "off";
|
|
|
+
|
|
|
+ seq_printf(s, "%*s%-*s %-6s %-3d %-10lu\n",
|
|
|
+ level * 3 + 1, "",
|
|
|
+ 50 - level * 3, buf,
|
|
|
+ state, c->usage, clk_get_rate(c));
|
|
|
+
|
|
|
+ list_for_each_entry(child, &clocks, list) {
|
|
|
+ if (child->parent != c)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ clock_tree_show_one(s, child, level + 1);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static int clock_tree_show(struct seq_file *s, void *data)
|
|
|
+{
|
|
|
+ struct clk *c;
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ seq_printf(s, " clock state ref rate\n");
|
|
|
+ seq_printf(s, "----------------------------------------------------\n");
|
|
|
+
|
|
|
+ spin_lock_irqsave(&clocks_lock, flags);
|
|
|
+
|
|
|
+ list_for_each_entry(c, &clocks, list)
|
|
|
+ if (c->parent == NULL)
|
|
|
+ clock_tree_show_one(s, c, 0);
|
|
|
+
|
|
|
+ spin_unlock_irqrestore(&clocks_lock, flags);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int clock_tree_open(struct inode *inode, struct file *file)
|
|
|
+{
|
|
|
+ return single_open(file, clock_tree_show, inode->i_private);
|
|
|
+}
|
|
|
+
|
|
|
+static const struct file_operations clock_tree_fops = {
|
|
|
+ .open = clock_tree_open,
|
|
|
+ .read = seq_read,
|
|
|
+ .llseek = seq_lseek,
|
|
|
+ .release = single_release,
|
|
|
+};
|
|
|
+
|
|
|
+static int clock_rate_show(void *data, u64 *val)
|
|
|
+{
|
|
|
+ struct clk *c = data;
|
|
|
+ *val = clk_get_rate(c);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_rate_show, NULL, "%llu\n");
|
|
|
+
|