diff options
Diffstat (limited to 'arch/arm/mach-bcmring/clock.c')
-rw-r--r-- | arch/arm/mach-bcmring/clock.c | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/arch/arm/mach-bcmring/clock.c b/arch/arm/mach-bcmring/clock.c deleted file mode 100644 index ad237a42d265..000000000000 --- a/arch/arm/mach-bcmring/clock.c +++ /dev/null | |||
@@ -1,223 +0,0 @@ | |||
1 | /***************************************************************************** | ||
2 | * Copyright 2001 - 2009 Broadcom Corporation. All rights reserved. | ||
3 | * | ||
4 | * Unless you and Broadcom execute a separate written software license | ||
5 | * agreement governing use of this software, this software is licensed to you | ||
6 | * under the terms of the GNU General Public License version 2, available at | ||
7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
8 | * | ||
9 | * Notwithstanding the above, under no circumstances may you combine this | ||
10 | * software in any way with any other Broadcom software provided under a | ||
11 | * license other than the GPL, without Broadcom's express prior written | ||
12 | * consent. | ||
13 | *****************************************************************************/ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/list.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/string.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/clkdev.h> | ||
25 | #include <mach/csp/hw_cfg.h> | ||
26 | #include <mach/csp/chipcHw_def.h> | ||
27 | #include <mach/csp/chipcHw_reg.h> | ||
28 | #include <mach/csp/chipcHw_inline.h> | ||
29 | |||
30 | #include "clock.h" | ||
31 | |||
32 | #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) | ||
33 | #define clk_is_pll1(x) ((x)->type & CLK_TYPE_PLL1) | ||
34 | #define clk_is_pll2(x) ((x)->type & CLK_TYPE_PLL2) | ||
35 | #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) | ||
36 | #define clk_is_bypassable(x) ((x)->type & CLK_TYPE_BYPASSABLE) | ||
37 | |||
38 | #define clk_is_using_xtal(x) ((x)->mode & CLK_MODE_XTAL) | ||
39 | |||
40 | static DEFINE_SPINLOCK(clk_lock); | ||
41 | |||
42 | static void __clk_enable(struct clk *clk) | ||
43 | { | ||
44 | if (!clk) | ||
45 | return; | ||
46 | |||
47 | /* enable parent clock first */ | ||
48 | if (clk->parent) | ||
49 | __clk_enable(clk->parent); | ||
50 | |||
51 | if (clk->use_cnt++ == 0) { | ||
52 | if (clk_is_pll1(clk)) { /* PLL1 */ | ||
53 | chipcHw_pll1Enable(clk->rate_hz, 0); | ||
54 | } else if (clk_is_pll2(clk)) { /* PLL2 */ | ||
55 | chipcHw_pll2Enable(clk->rate_hz); | ||
56 | } else if (clk_is_using_xtal(clk)) { /* source is crystal */ | ||
57 | if (!clk_is_primary(clk)) | ||
58 | chipcHw_bypassClockEnable(clk->csp_id); | ||
59 | } else { /* source is PLL */ | ||
60 | chipcHw_setClockEnable(clk->csp_id); | ||
61 | } | ||
62 | } | ||
63 | } | ||
64 | |||
65 | int clk_enable(struct clk *clk) | ||
66 | { | ||
67 | unsigned long flags; | ||
68 | |||
69 | if (!clk) | ||
70 | return -EINVAL; | ||
71 | |||
72 | spin_lock_irqsave(&clk_lock, flags); | ||
73 | __clk_enable(clk); | ||
74 | spin_unlock_irqrestore(&clk_lock, flags); | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | EXPORT_SYMBOL(clk_enable); | ||
79 | |||
80 | static void __clk_disable(struct clk *clk) | ||
81 | { | ||
82 | if (!clk) | ||
83 | return; | ||
84 | |||
85 | BUG_ON(clk->use_cnt == 0); | ||
86 | |||
87 | if (--clk->use_cnt == 0) { | ||
88 | if (clk_is_pll1(clk)) { /* PLL1 */ | ||
89 | chipcHw_pll1Disable(); | ||
90 | } else if (clk_is_pll2(clk)) { /* PLL2 */ | ||
91 | chipcHw_pll2Disable(); | ||
92 | } else if (clk_is_using_xtal(clk)) { /* source is crystal */ | ||
93 | if (!clk_is_primary(clk)) | ||
94 | chipcHw_bypassClockDisable(clk->csp_id); | ||
95 | } else { /* source is PLL */ | ||
96 | chipcHw_setClockDisable(clk->csp_id); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | if (clk->parent) | ||
101 | __clk_disable(clk->parent); | ||
102 | } | ||
103 | |||
104 | void clk_disable(struct clk *clk) | ||
105 | { | ||
106 | unsigned long flags; | ||
107 | |||
108 | if (!clk) | ||
109 | return; | ||
110 | |||
111 | spin_lock_irqsave(&clk_lock, flags); | ||
112 | __clk_disable(clk); | ||
113 | spin_unlock_irqrestore(&clk_lock, flags); | ||
114 | } | ||
115 | EXPORT_SYMBOL(clk_disable); | ||
116 | |||
117 | unsigned long clk_get_rate(struct clk *clk) | ||
118 | { | ||
119 | if (!clk) | ||
120 | return 0; | ||
121 | |||
122 | return clk->rate_hz; | ||
123 | } | ||
124 | EXPORT_SYMBOL(clk_get_rate); | ||
125 | |||
126 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
127 | { | ||
128 | unsigned long flags; | ||
129 | unsigned long actual; | ||
130 | unsigned long rate_hz; | ||
131 | |||
132 | if (!clk) | ||
133 | return -EINVAL; | ||
134 | |||
135 | if (!clk_is_programmable(clk)) | ||
136 | return -EINVAL; | ||
137 | |||
138 | if (clk->use_cnt) | ||
139 | return -EBUSY; | ||
140 | |||
141 | spin_lock_irqsave(&clk_lock, flags); | ||
142 | actual = clk->parent->rate_hz; | ||
143 | rate_hz = min(actual, rate); | ||
144 | spin_unlock_irqrestore(&clk_lock, flags); | ||
145 | |||
146 | return rate_hz; | ||
147 | } | ||
148 | EXPORT_SYMBOL(clk_round_rate); | ||
149 | |||
150 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
151 | { | ||
152 | unsigned long flags; | ||
153 | unsigned long actual; | ||
154 | unsigned long rate_hz; | ||
155 | |||
156 | if (!clk) | ||
157 | return -EINVAL; | ||
158 | |||
159 | if (!clk_is_programmable(clk)) | ||
160 | return -EINVAL; | ||
161 | |||
162 | if (clk->use_cnt) | ||
163 | return -EBUSY; | ||
164 | |||
165 | spin_lock_irqsave(&clk_lock, flags); | ||
166 | actual = clk->parent->rate_hz; | ||
167 | rate_hz = min(actual, rate); | ||
168 | rate_hz = chipcHw_setClockFrequency(clk->csp_id, rate_hz); | ||
169 | clk->rate_hz = rate_hz; | ||
170 | spin_unlock_irqrestore(&clk_lock, flags); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | EXPORT_SYMBOL(clk_set_rate); | ||
175 | |||
176 | struct clk *clk_get_parent(struct clk *clk) | ||
177 | { | ||
178 | if (!clk) | ||
179 | return NULL; | ||
180 | |||
181 | return clk->parent; | ||
182 | } | ||
183 | EXPORT_SYMBOL(clk_get_parent); | ||
184 | |||
185 | int clk_set_parent(struct clk *clk, struct clk *parent) | ||
186 | { | ||
187 | unsigned long flags; | ||
188 | struct clk *old_parent; | ||
189 | |||
190 | if (!clk || !parent) | ||
191 | return -EINVAL; | ||
192 | |||
193 | if (!clk_is_primary(parent) || !clk_is_bypassable(clk)) | ||
194 | return -EINVAL; | ||
195 | |||
196 | /* if more than one user, parent is not allowed */ | ||
197 | if (clk->use_cnt > 1) | ||
198 | return -EBUSY; | ||
199 | |||
200 | if (clk->parent == parent) | ||
201 | return 0; | ||
202 | |||
203 | spin_lock_irqsave(&clk_lock, flags); | ||
204 | old_parent = clk->parent; | ||
205 | clk->parent = parent; | ||
206 | if (clk_is_using_xtal(parent)) | ||
207 | clk->mode |= CLK_MODE_XTAL; | ||
208 | else | ||
209 | clk->mode &= (~CLK_MODE_XTAL); | ||
210 | |||
211 | /* if clock is active */ | ||
212 | if (clk->use_cnt != 0) { | ||
213 | clk->use_cnt--; | ||
214 | /* enable clock with the new parent */ | ||
215 | __clk_enable(clk); | ||
216 | /* disable the old parent */ | ||
217 | __clk_disable(old_parent); | ||
218 | } | ||
219 | spin_unlock_irqrestore(&clk_lock, flags); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | EXPORT_SYMBOL(clk_set_parent); | ||