diff options
author | Shiraz Hashim <shiraz.hashim@st.com> | 2011-02-16 01:40:40 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-03-09 04:49:45 -0500 |
commit | 4b9502e167d8370c2c5ee0cb20ab081bbebfffa8 (patch) | |
tree | c7f53aff2d7be2d5535ed59112a4cc339051bb13 /arch/arm/plat-spear | |
parent | af89fd812b00a52c54a3b9b2290fae4d31c7be9a (diff) |
ARM: 6681/1: SPEAr: add debugfs support to clk API
Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/plat-spear')
-rw-r--r-- | arch/arm/plat-spear/clock.c | 116 | ||||
-rw-r--r-- | arch/arm/plat-spear/include/plat/clock.h | 8 |
2 files changed, 124 insertions, 0 deletions
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c index 7e7ab606dc49..bdbd7ec9cb6b 100644 --- a/arch/arm/plat-spear/clock.c +++ b/arch/arm/plat-spear/clock.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/bug.h> | 14 | #include <linux/bug.h> |
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/debugfs.h> | ||
16 | #include <linux/err.h> | 17 | #include <linux/err.h> |
17 | #include <linux/io.h> | 18 | #include <linux/io.h> |
18 | #include <linux/list.h> | 19 | #include <linux/list.h> |
@@ -22,8 +23,14 @@ | |||
22 | 23 | ||
23 | static DEFINE_SPINLOCK(clocks_lock); | 24 | static DEFINE_SPINLOCK(clocks_lock); |
24 | static LIST_HEAD(root_clks); | 25 | static LIST_HEAD(root_clks); |
26 | #ifdef CONFIG_DEBUG_FS | ||
27 | static LIST_HEAD(clocks); | ||
28 | #endif | ||
25 | 29 | ||
26 | static void propagate_rate(struct clk *, int on_init); | 30 | static void propagate_rate(struct clk *, int on_init); |
31 | #ifdef CONFIG_DEBUG_FS | ||
32 | static int clk_debugfs_reparent(struct clk *); | ||
33 | #endif | ||
27 | 34 | ||
28 | static int generic_clk_enable(struct clk *clk) | 35 | static int generic_clk_enable(struct clk *clk) |
29 | { | 36 | { |
@@ -96,6 +103,10 @@ static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info) | |||
96 | 103 | ||
97 | clk->pclk = pclk_info->pclk; | 104 | clk->pclk = pclk_info->pclk; |
98 | spin_unlock_irqrestore(&clocks_lock, flags); | 105 | spin_unlock_irqrestore(&clocks_lock, flags); |
106 | |||
107 | #ifdef CONFIG_DEBUG_FS | ||
108 | clk_debugfs_reparent(clk); | ||
109 | #endif | ||
99 | } | 110 | } |
100 | 111 | ||
101 | static void do_clk_disable(struct clk *clk) | 112 | static void do_clk_disable(struct clk *clk) |
@@ -336,6 +347,12 @@ void clk_register(struct clk_lookup *cl) | |||
336 | 347 | ||
337 | spin_unlock_irqrestore(&clocks_lock, flags); | 348 | spin_unlock_irqrestore(&clocks_lock, flags); |
338 | 349 | ||
350 | /* debugfs specific */ | ||
351 | #ifdef CONFIG_DEBUG_FS | ||
352 | list_add(&clk->node, &clocks); | ||
353 | clk->cl = cl; | ||
354 | #endif | ||
355 | |||
339 | /* add clock to arm clockdev framework */ | 356 | /* add clock to arm clockdev framework */ |
340 | clkdev_add(cl); | 357 | clkdev_add(cl); |
341 | } | 358 | } |
@@ -885,3 +902,102 @@ void recalc_root_clocks(void) | |||
885 | } | 902 | } |
886 | spin_unlock_irqrestore(&clocks_lock, flags); | 903 | spin_unlock_irqrestore(&clocks_lock, flags); |
887 | } | 904 | } |
905 | |||
906 | #ifdef CONFIG_DEBUG_FS | ||
907 | /* | ||
908 | * debugfs support to trace clock tree hierarchy and attributes | ||
909 | */ | ||
910 | static struct dentry *clk_debugfs_root; | ||
911 | static int clk_debugfs_register_one(struct clk *c) | ||
912 | { | ||
913 | int err; | ||
914 | struct dentry *d, *child; | ||
915 | struct clk *pa = c->pclk; | ||
916 | char s[255]; | ||
917 | char *p = s; | ||
918 | |||
919 | if (c) { | ||
920 | if (c->cl->con_id) | ||
921 | p += sprintf(p, "%s", c->cl->con_id); | ||
922 | if (c->cl->dev_id) | ||
923 | p += sprintf(p, "%s", c->cl->dev_id); | ||
924 | } | ||
925 | d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root); | ||
926 | if (!d) | ||
927 | return -ENOMEM; | ||
928 | c->dent = d; | ||
929 | |||
930 | d = debugfs_create_u32("usage_count", S_IRUGO, c->dent, | ||
931 | (u32 *)&c->usage_count); | ||
932 | if (!d) { | ||
933 | err = -ENOMEM; | ||
934 | goto err_out; | ||
935 | } | ||
936 | d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); | ||
937 | if (!d) { | ||
938 | err = -ENOMEM; | ||
939 | goto err_out; | ||
940 | } | ||
941 | d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags); | ||
942 | if (!d) { | ||
943 | err = -ENOMEM; | ||
944 | goto err_out; | ||
945 | } | ||
946 | return 0; | ||
947 | |||
948 | err_out: | ||
949 | d = c->dent; | ||
950 | list_for_each_entry(child, &d->d_subdirs, d_u.d_child) | ||
951 | debugfs_remove(child); | ||
952 | debugfs_remove(c->dent); | ||
953 | return err; | ||
954 | } | ||
955 | |||
956 | static int clk_debugfs_register(struct clk *c) | ||
957 | { | ||
958 | int err; | ||
959 | struct clk *pa = c->pclk; | ||
960 | |||
961 | if (pa && !pa->dent) { | ||
962 | err = clk_debugfs_register(pa); | ||
963 | if (err) | ||
964 | return err; | ||
965 | } | ||
966 | |||
967 | if (!c->dent) { | ||
968 | err = clk_debugfs_register_one(c); | ||
969 | if (err) | ||
970 | return err; | ||
971 | } | ||
972 | return 0; | ||
973 | } | ||
974 | |||
975 | static int __init clk_debugfs_init(void) | ||
976 | { | ||
977 | struct clk *c; | ||
978 | struct dentry *d; | ||
979 | int err; | ||
980 | |||
981 | d = debugfs_create_dir("clock", NULL); | ||
982 | if (!d) | ||
983 | return -ENOMEM; | ||
984 | clk_debugfs_root = d; | ||
985 | |||
986 | list_for_each_entry(c, &clocks, node) { | ||
987 | err = clk_debugfs_register(c); | ||
988 | if (err) | ||
989 | goto err_out; | ||
990 | } | ||
991 | return 0; | ||
992 | err_out: | ||
993 | debugfs_remove_recursive(clk_debugfs_root); | ||
994 | return err; | ||
995 | } | ||
996 | late_initcall(clk_debugfs_init); | ||
997 | |||
998 | static int clk_debugfs_reparent(struct clk *c) | ||
999 | { | ||
1000 | debugfs_remove(c->dent); | ||
1001 | return clk_debugfs_register_one(c); | ||
1002 | } | ||
1003 | #endif /* CONFIG_DEBUG_FS */ | ||
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h index 5a601d830971..2ae6606930a6 100644 --- a/arch/arm/plat-spear/include/plat/clock.h +++ b/arch/arm/plat-spear/include/plat/clock.h | |||
@@ -88,6 +88,9 @@ struct rate_config { | |||
88 | * @children: list for childrens or this clock | 88 | * @children: list for childrens or this clock |
89 | * @sibling: node for list of clocks having same parents | 89 | * @sibling: node for list of clocks having same parents |
90 | * @private_data: clock specific private data | 90 | * @private_data: clock specific private data |
91 | * @node: list to maintain clocks linearly | ||
92 | * @cl: clocklook up assoicated with this clock | ||
93 | * @dent: object for debugfs | ||
91 | */ | 94 | */ |
92 | struct clk { | 95 | struct clk { |
93 | unsigned int usage_count; | 96 | unsigned int usage_count; |
@@ -109,6 +112,11 @@ struct clk { | |||
109 | struct list_head children; | 112 | struct list_head children; |
110 | struct list_head sibling; | 113 | struct list_head sibling; |
111 | void *private_data; | 114 | void *private_data; |
115 | #ifdef CONFIG_DEBUG_FS | ||
116 | struct list_head node; | ||
117 | struct clk_lookup *cl; | ||
118 | struct dentry *dent; | ||
119 | #endif | ||
112 | }; | 120 | }; |
113 | 121 | ||
114 | /* pll configuration structure */ | 122 | /* pll configuration structure */ |