Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / arch / arm / plat-omap / clock.c
1 /*
2  *  linux/arch/arm/plat-omap/clock.c
3  *
4  *  Copyright (C) 2004 - 2005 Nokia corporation
5  *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6  *
7  *  Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 #include <linux/version.h>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/list.h>
18 #include <linux/errno.h>
19 #include <linux/err.h>
20 #include <linux/string.h>
21 #include <linux/clk.h>
22 #include <linux/mutex.h>
23 #include <linux/platform_device.h>
24
25 #include <asm/io.h>
26 #include <asm/semaphore.h>
27
28 #include <asm/arch/clock.h>
29
30 static LIST_HEAD(clocks);
31 static DEFINE_MUTEX(clocks_mutex);
32 static DEFINE_SPINLOCK(clockfw_lock);
33
34 static struct clk_functions *arch_clock;
35
36 /*-------------------------------------------------------------------------
37  * Standard clock functions defined in include/linux/clk.h
38  *-------------------------------------------------------------------------*/
39
40 /*
41  * Returns a clock. Note that we first try to use device id on the bus
42  * and clock name. If this fails, we try to use clock name only.
43  */
44 struct clk * clk_get(struct device *dev, const char *id)
45 {
46         struct clk *p, *clk = ERR_PTR(-ENOENT);
47         int idno;
48
49         if (dev == NULL || dev->bus != &platform_bus_type)
50                 idno = -1;
51         else
52                 idno = to_platform_device(dev)->id;
53
54         mutex_lock(&clocks_mutex);
55
56         list_for_each_entry(p, &clocks, node) {
57                 if (p->id == idno &&
58                     strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
59                         clk = p;
60                         goto found;
61                 }
62         }
63
64         list_for_each_entry(p, &clocks, node) {
65                 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
66                         clk = p;
67                         break;
68                 }
69         }
70
71 found:
72         mutex_unlock(&clocks_mutex);
73
74         return clk;
75 }
76 EXPORT_SYMBOL(clk_get);
77
78 int clk_enable(struct clk *clk)
79 {
80         unsigned long flags;
81         int ret = 0;
82
83         if (clk == NULL || IS_ERR(clk))
84                 return -EINVAL;
85
86         spin_lock_irqsave(&clockfw_lock, flags);
87         if (arch_clock->clk_enable)
88                 ret = arch_clock->clk_enable(clk);
89         spin_unlock_irqrestore(&clockfw_lock, flags);
90
91         return ret;
92 }
93 EXPORT_SYMBOL(clk_enable);
94
95 void clk_disable(struct clk *clk)
96 {
97         unsigned long flags;
98
99         if (clk == NULL || IS_ERR(clk))
100                 return;
101
102         spin_lock_irqsave(&clockfw_lock, flags);
103         BUG_ON(clk->usecount == 0);
104         if (arch_clock->clk_disable)
105                 arch_clock->clk_disable(clk);
106         spin_unlock_irqrestore(&clockfw_lock, flags);
107 }
108 EXPORT_SYMBOL(clk_disable);
109
110 int clk_get_usecount(struct clk *clk)
111 {
112         unsigned long flags;
113         int ret = 0;
114
115         if (clk == NULL || IS_ERR(clk))
116                 return 0;
117
118         spin_lock_irqsave(&clockfw_lock, flags);
119         ret = clk->usecount;
120         spin_unlock_irqrestore(&clockfw_lock, flags);
121
122         return ret;
123 }
124 EXPORT_SYMBOL(clk_get_usecount);
125
126 unsigned long clk_get_rate(struct clk *clk)
127 {
128         unsigned long flags;
129         unsigned long ret = 0;
130
131         if (clk == NULL || IS_ERR(clk))
132                 return 0;
133
134         spin_lock_irqsave(&clockfw_lock, flags);
135         ret = clk->rate;
136         spin_unlock_irqrestore(&clockfw_lock, flags);
137
138         return ret;
139 }
140 EXPORT_SYMBOL(clk_get_rate);
141
142 void clk_put(struct clk *clk)
143 {
144         if (clk && !IS_ERR(clk))
145                 module_put(clk->owner);
146 }
147 EXPORT_SYMBOL(clk_put);
148
149 /*-------------------------------------------------------------------------
150  * Optional clock functions defined in include/linux/clk.h
151  *-------------------------------------------------------------------------*/
152
153 long clk_round_rate(struct clk *clk, unsigned long rate)
154 {
155         unsigned long flags;
156         long ret = 0;
157
158         if (clk == NULL || IS_ERR(clk))
159                 return ret;
160
161         spin_lock_irqsave(&clockfw_lock, flags);
162         if (arch_clock->clk_round_rate)
163                 ret = arch_clock->clk_round_rate(clk, rate);
164         spin_unlock_irqrestore(&clockfw_lock, flags);
165
166         return ret;
167 }
168 EXPORT_SYMBOL(clk_round_rate);
169
170 int clk_set_rate(struct clk *clk, unsigned long rate)
171 {
172         unsigned long flags;
173         int ret = -EINVAL;
174
175         if (clk == NULL || IS_ERR(clk))
176                 return ret;
177
178         spin_lock_irqsave(&clockfw_lock, flags);
179         if (arch_clock->clk_set_rate)
180                 ret = arch_clock->clk_set_rate(clk, rate);
181         spin_unlock_irqrestore(&clockfw_lock, flags);
182
183         return ret;
184 }
185 EXPORT_SYMBOL(clk_set_rate);
186
187 int clk_set_parent(struct clk *clk, struct clk *parent)
188 {
189         unsigned long flags;
190         int ret = -EINVAL;
191
192         if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
193                 return ret;
194
195         spin_lock_irqsave(&clockfw_lock, flags);
196         if (arch_clock->clk_set_parent)
197                 ret =  arch_clock->clk_set_parent(clk, parent);
198         spin_unlock_irqrestore(&clockfw_lock, flags);
199
200         return ret;
201 }
202 EXPORT_SYMBOL(clk_set_parent);
203
204 struct clk *clk_get_parent(struct clk *clk)
205 {
206         unsigned long flags;
207         struct clk * ret = NULL;
208
209         if (clk == NULL || IS_ERR(clk))
210                 return ret;
211
212         spin_lock_irqsave(&clockfw_lock, flags);
213         if (arch_clock->clk_get_parent)
214                 ret = arch_clock->clk_get_parent(clk);
215         spin_unlock_irqrestore(&clockfw_lock, flags);
216
217         return ret;
218 }
219 EXPORT_SYMBOL(clk_get_parent);
220
221 /*-------------------------------------------------------------------------
222  * OMAP specific clock functions shared between omap1 and omap2
223  *-------------------------------------------------------------------------*/
224
225 unsigned int __initdata mpurate;
226
227 /*
228  * By default we use the rate set by the bootloader.
229  * You can override this with mpurate= cmdline option.
230  */
231 static int __init omap_clk_setup(char *str)
232 {
233         get_option(&str, &mpurate);
234
235         if (!mpurate)
236                 return 1;
237
238         if (mpurate < 1000)
239                 mpurate *= 1000000;
240
241         return 1;
242 }
243 __setup("mpurate=", omap_clk_setup);
244
245 /* Used for clocks that always have same value as the parent clock */
246 void followparent_recalc(struct clk *clk)
247 {
248         if (clk == NULL || IS_ERR(clk))
249                 return;
250
251         clk->rate = clk->parent->rate;
252 }
253
254 /* Propagate rate to children */
255 void propagate_rate(struct clk * tclk)
256 {
257         struct clk *clkp;
258
259         if (tclk == NULL || IS_ERR(tclk))
260                 return;
261
262         list_for_each_entry(clkp, &clocks, node) {
263                 if (likely(clkp->parent != tclk))
264                         continue;
265                 if (likely((u32)clkp->recalc))
266                         clkp->recalc(clkp);
267         }
268 }
269
270 int clk_register(struct clk *clk)
271 {
272         if (clk == NULL || IS_ERR(clk))
273                 return -EINVAL;
274
275         mutex_lock(&clocks_mutex);
276         list_add(&clk->node, &clocks);
277         if (clk->init)
278                 clk->init(clk);
279         mutex_unlock(&clocks_mutex);
280
281         return 0;
282 }
283 EXPORT_SYMBOL(clk_register);
284
285 void clk_unregister(struct clk *clk)
286 {
287         if (clk == NULL || IS_ERR(clk))
288                 return;
289
290         mutex_lock(&clocks_mutex);
291         list_del(&clk->node);
292         mutex_unlock(&clocks_mutex);
293 }
294 EXPORT_SYMBOL(clk_unregister);
295
296 void clk_deny_idle(struct clk *clk)
297 {
298         unsigned long flags;
299
300         if (clk == NULL || IS_ERR(clk))
301                 return;
302
303         spin_lock_irqsave(&clockfw_lock, flags);
304         if (arch_clock->clk_deny_idle)
305                 arch_clock->clk_deny_idle(clk);
306         spin_unlock_irqrestore(&clockfw_lock, flags);
307 }
308 EXPORT_SYMBOL(clk_deny_idle);
309
310 void clk_allow_idle(struct clk *clk)
311 {
312         unsigned long flags;
313
314         if (clk == NULL || IS_ERR(clk))
315                 return;
316
317         spin_lock_irqsave(&clockfw_lock, flags);
318         if (arch_clock->clk_allow_idle)
319                 arch_clock->clk_allow_idle(clk);
320         spin_unlock_irqrestore(&clockfw_lock, flags);
321 }
322 EXPORT_SYMBOL(clk_allow_idle);
323
324 /*-------------------------------------------------------------------------*/
325
326 #ifdef CONFIG_OMAP_RESET_CLOCKS
327 /*
328  * Disable any unused clocks left on by the bootloader
329  */
330 static int __init clk_disable_unused(void)
331 {
332         struct clk *ck;
333         unsigned long flags;
334
335         list_for_each_entry(ck, &clocks, node) {
336                 if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
337                         ck->enable_reg == 0)
338                         continue;
339
340                 spin_lock_irqsave(&clockfw_lock, flags);
341                 if (arch_clock->clk_disable_unused)
342                         arch_clock->clk_disable_unused(ck);
343                 spin_unlock_irqrestore(&clockfw_lock, flags);
344         }
345
346         return 0;
347 }
348 late_initcall(clk_disable_unused);
349 #endif
350
351 int __init clk_init(struct clk_functions * custom_clocks)
352 {
353         if (!custom_clocks) {
354                 printk(KERN_ERR "No custom clock functions registered\n");
355                 BUG();
356         }
357
358         arch_clock = custom_clocks;
359
360         return 0;
361 }