aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/clock.c')
-rw-r--r--arch/arm/plat-omap/clock.c67
1 files changed, 65 insertions, 2 deletions
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 3c2bfc0efdaf..06485c193ee3 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -21,6 +21,7 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
26#include <asm/semaphore.h> 27#include <asm/semaphore.h>
@@ -37,17 +38,37 @@ static struct clk_functions *arch_clock;
37 * Standard clock functions defined in include/linux/clk.h 38 * Standard clock functions defined in include/linux/clk.h
38 *-------------------------------------------------------------------------*/ 39 *-------------------------------------------------------------------------*/
39 40
41/*
42 * Returns a clock. Note that we first try to use device id on the bus
43 * and clock name. If this fails, we try to use clock name only.
44 */
40struct clk * clk_get(struct device *dev, const char *id) 45struct clk * clk_get(struct device *dev, const char *id)
41{ 46{
42 struct clk *p, *clk = ERR_PTR(-ENOENT); 47 struct clk *p, *clk = ERR_PTR(-ENOENT);
48 int idno;
49
50 if (dev == NULL || dev->bus != &platform_bus_type)
51 idno = -1;
52 else
53 idno = to_platform_device(dev)->id;
43 54
44 mutex_lock(&clocks_mutex); 55 mutex_lock(&clocks_mutex);
56
57 list_for_each_entry(p, &clocks, node) {
58 if (p->id == idno &&
59 strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
60 clk = p;
61 break;
62 }
63 }
64
45 list_for_each_entry(p, &clocks, node) { 65 list_for_each_entry(p, &clocks, node) {
46 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { 66 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
47 clk = p; 67 clk = p;
48 break; 68 break;
49 } 69 }
50 } 70 }
71
51 mutex_unlock(&clocks_mutex); 72 mutex_unlock(&clocks_mutex);
52 73
53 return clk; 74 return clk;
@@ -59,6 +80,9 @@ int clk_enable(struct clk *clk)
59 unsigned long flags; 80 unsigned long flags;
60 int ret = 0; 81 int ret = 0;
61 82
83 if (clk == NULL || IS_ERR(clk))
84 return -EINVAL;
85
62 spin_lock_irqsave(&clockfw_lock, flags); 86 spin_lock_irqsave(&clockfw_lock, flags);
63 if (arch_clock->clk_enable) 87 if (arch_clock->clk_enable)
64 ret = arch_clock->clk_enable(clk); 88 ret = arch_clock->clk_enable(clk);
@@ -72,6 +96,9 @@ void clk_disable(struct clk *clk)
72{ 96{
73 unsigned long flags; 97 unsigned long flags;
74 98
99 if (clk == NULL || IS_ERR(clk))
100 return;
101
75 spin_lock_irqsave(&clockfw_lock, flags); 102 spin_lock_irqsave(&clockfw_lock, flags);
76 if (arch_clock->clk_disable) 103 if (arch_clock->clk_disable)
77 arch_clock->clk_disable(clk); 104 arch_clock->clk_disable(clk);
@@ -84,6 +111,9 @@ int clk_get_usecount(struct clk *clk)
84 unsigned long flags; 111 unsigned long flags;
85 int ret = 0; 112 int ret = 0;
86 113
114 if (clk == NULL || IS_ERR(clk))
115 return 0;
116
87 spin_lock_irqsave(&clockfw_lock, flags); 117 spin_lock_irqsave(&clockfw_lock, flags);
88 ret = clk->usecount; 118 ret = clk->usecount;
89 spin_unlock_irqrestore(&clockfw_lock, flags); 119 spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -97,6 +127,9 @@ unsigned long clk_get_rate(struct clk *clk)
97 unsigned long flags; 127 unsigned long flags;
98 unsigned long ret = 0; 128 unsigned long ret = 0;
99 129
130 if (clk == NULL || IS_ERR(clk))
131 return 0;
132
100 spin_lock_irqsave(&clockfw_lock, flags); 133 spin_lock_irqsave(&clockfw_lock, flags);
101 ret = clk->rate; 134 ret = clk->rate;
102 spin_unlock_irqrestore(&clockfw_lock, flags); 135 spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -121,6 +154,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
121 unsigned long flags; 154 unsigned long flags;
122 long ret = 0; 155 long ret = 0;
123 156
157 if (clk == NULL || IS_ERR(clk))
158 return ret;
159
124 spin_lock_irqsave(&clockfw_lock, flags); 160 spin_lock_irqsave(&clockfw_lock, flags);
125 if (arch_clock->clk_round_rate) 161 if (arch_clock->clk_round_rate)
126 ret = arch_clock->clk_round_rate(clk, rate); 162 ret = arch_clock->clk_round_rate(clk, rate);
@@ -133,7 +169,10 @@ EXPORT_SYMBOL(clk_round_rate);
133int clk_set_rate(struct clk *clk, unsigned long rate) 169int clk_set_rate(struct clk *clk, unsigned long rate)
134{ 170{
135 unsigned long flags; 171 unsigned long flags;
136 int ret = 0; 172 int ret = -EINVAL;
173
174 if (clk == NULL || IS_ERR(clk))
175 return ret;
137 176
138 spin_lock_irqsave(&clockfw_lock, flags); 177 spin_lock_irqsave(&clockfw_lock, flags);
139 if (arch_clock->clk_set_rate) 178 if (arch_clock->clk_set_rate)
@@ -147,7 +186,10 @@ EXPORT_SYMBOL(clk_set_rate);
147int clk_set_parent(struct clk *clk, struct clk *parent) 186int clk_set_parent(struct clk *clk, struct clk *parent)
148{ 187{
149 unsigned long flags; 188 unsigned long flags;
150 int ret = 0; 189 int ret = -EINVAL;
190
191 if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
192 return ret;
151 193
152 spin_lock_irqsave(&clockfw_lock, flags); 194 spin_lock_irqsave(&clockfw_lock, flags);
153 if (arch_clock->clk_set_parent) 195 if (arch_clock->clk_set_parent)
@@ -163,6 +205,9 @@ struct clk *clk_get_parent(struct clk *clk)
163 unsigned long flags; 205 unsigned long flags;
164 struct clk * ret = NULL; 206 struct clk * ret = NULL;
165 207
208 if (clk == NULL || IS_ERR(clk))
209 return ret;
210
166 spin_lock_irqsave(&clockfw_lock, flags); 211 spin_lock_irqsave(&clockfw_lock, flags);
167 if (arch_clock->clk_get_parent) 212 if (arch_clock->clk_get_parent)
168 ret = arch_clock->clk_get_parent(clk); 213 ret = arch_clock->clk_get_parent(clk);
@@ -199,6 +244,9 @@ __setup("mpurate=", omap_clk_setup);
199/* Used for clocks that always have same value as the parent clock */ 244/* Used for clocks that always have same value as the parent clock */
200void followparent_recalc(struct clk *clk) 245void followparent_recalc(struct clk *clk)
201{ 246{
247 if (clk == NULL || IS_ERR(clk))
248 return;
249
202 clk->rate = clk->parent->rate; 250 clk->rate = clk->parent->rate;
203} 251}
204 252
@@ -207,6 +255,9 @@ void propagate_rate(struct clk * tclk)
207{ 255{
208 struct clk *clkp; 256 struct clk *clkp;
209 257
258 if (tclk == NULL || IS_ERR(tclk))
259 return;
260
210 list_for_each_entry(clkp, &clocks, node) { 261 list_for_each_entry(clkp, &clocks, node) {
211 if (likely(clkp->parent != tclk)) 262 if (likely(clkp->parent != tclk))
212 continue; 263 continue;
@@ -217,6 +268,9 @@ void propagate_rate(struct clk * tclk)
217 268
218int clk_register(struct clk *clk) 269int clk_register(struct clk *clk)
219{ 270{
271 if (clk == NULL || IS_ERR(clk))
272 return -EINVAL;
273
220 mutex_lock(&clocks_mutex); 274 mutex_lock(&clocks_mutex);
221 list_add(&clk->node, &clocks); 275 list_add(&clk->node, &clocks);
222 if (clk->init) 276 if (clk->init)
@@ -229,6 +283,9 @@ EXPORT_SYMBOL(clk_register);
229 283
230void clk_unregister(struct clk *clk) 284void clk_unregister(struct clk *clk)
231{ 285{
286 if (clk == NULL || IS_ERR(clk))
287 return;
288
232 mutex_lock(&clocks_mutex); 289 mutex_lock(&clocks_mutex);
233 list_del(&clk->node); 290 list_del(&clk->node);
234 mutex_unlock(&clocks_mutex); 291 mutex_unlock(&clocks_mutex);
@@ -239,6 +296,9 @@ void clk_deny_idle(struct clk *clk)
239{ 296{
240 unsigned long flags; 297 unsigned long flags;
241 298
299 if (clk == NULL || IS_ERR(clk))
300 return;
301
242 spin_lock_irqsave(&clockfw_lock, flags); 302 spin_lock_irqsave(&clockfw_lock, flags);
243 if (arch_clock->clk_deny_idle) 303 if (arch_clock->clk_deny_idle)
244 arch_clock->clk_deny_idle(clk); 304 arch_clock->clk_deny_idle(clk);
@@ -250,6 +310,9 @@ void clk_allow_idle(struct clk *clk)
250{ 310{
251 unsigned long flags; 311 unsigned long flags;
252 312
313 if (clk == NULL || IS_ERR(clk))
314 return;
315
253 spin_lock_irqsave(&clockfw_lock, flags); 316 spin_lock_irqsave(&clockfw_lock, flags);
254 if (arch_clock->clk_allow_idle) 317 if (arch_clock->clk_allow_idle)
255 arch_clock->clk_allow_idle(clk); 318 arch_clock->clk_allow_idle(clk);