1570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen/*
2570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  JZ4740 SoC clock support debugfs entries
4570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *
5570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  This program is free software; you can redistribute it and/or modify it
6570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  under  the terms of the GNU General  Public License as published by the
7570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  Free Software Foundation;  either version 2 of the License, or (at your
8570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  option) any later version.
9570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *
10570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  You should have received a copy of the GNU General Public License along
11570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  with this program; if not, write to the Free Software Foundation, Inc.,
12570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *  675 Mass Ave, Cambridge, MA 02139, USA.
13570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen *
14570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen */
15570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
16570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen#include <linux/kernel.h>
17570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen#include <linux/module.h>
18570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen#include <linux/clk.h>
19570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen#include <linux/err.h>
20570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
21570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen#include <linux/debugfs.h>
22570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen#include <linux/uaccess.h>
23570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
24570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen#include <asm/mach-jz4740/clock.h>
25570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen#include "clock.h"
26570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
27570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausenstatic struct dentry *jz4740_clock_debugfs;
28570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
29570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausenstatic int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
30570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen{
31570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	struct clk *clk = data;
32570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	*value = clk_is_enabled(clk);
33570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
34570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	return 0;
35570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen}
36570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
37570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausenstatic int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
38570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen{
39570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	struct clk *clk = data;
40570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
41570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	if (value)
42570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		return clk_enable(clk);
43570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	else
44570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		clk_disable(clk);
45570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
46570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	return 0;
47570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen}
48570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
49570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter ClausenDEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
50570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	jz4740_clock_debugfs_show_enabled,
51570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	jz4740_clock_debugfs_set_enabled,
52570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	"%llu\n");
53570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
54570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausenstatic int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
55570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen{
56570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	struct clk *clk = data;
57570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	*value = clk_get_rate(clk);
58570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
59570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	return 0;
60570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen}
61570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
62570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter ClausenDEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
63570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	jz4740_clock_debugfs_show_rate,
64570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	NULL,
65570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	"%llu\n");
66570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
67570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausenvoid jz4740_clock_debugfs_add_clk(struct clk *clk)
68570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen{
69570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	if (!jz4740_clock_debugfs)
70570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		return;
71570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
72570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
73570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
74570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen				&jz4740_clock_debugfs_ops_rate);
75570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
76570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen				&jz4740_clock_debugfs_ops_enabled);
77570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
78570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	if (clk->parent) {
79570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		char parent_path[100];
80570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		snprintf(parent_path, 100, "../%s", clk->parent->name);
81570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
82570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen						clk->debugfs_entry,
83570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen						parent_path);
84570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	}
85570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen}
86570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
87570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen/* TODO: Locking */
88570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausenvoid jz4740_clock_debugfs_update_parent(struct clk *clk)
89570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen{
90570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	if (clk->debugfs_parent_entry)
91570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		debugfs_remove(clk->debugfs_parent_entry);
92570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
93570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	if (clk->parent) {
94570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		char parent_path[100];
95570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		snprintf(parent_path, 100, "../%s", clk->parent->name);
96570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
97570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen						clk->debugfs_entry,
98570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen						parent_path);
99570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	} else {
100570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		clk->debugfs_parent_entry = NULL;
101570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	}
102570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen}
103570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen
104570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausenvoid jz4740_clock_debugfs_init(void)
105570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen{
106570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
107570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen	if (IS_ERR(jz4740_clock_debugfs))
108570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen		jz4740_clock_debugfs = NULL;
109570a0bb82f0b5c2c6324153010e72c3f0c26a7a3Lars-Peter Clausen}
110