Root/
1 | /* |
2 | * drivers/clk/clkdev.c |
3 | * |
4 | * Copyright (C) 2008 Russell King. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. |
9 | * |
10 | * Helper for the clk API to assist looking up a struct clk. |
11 | */ |
12 | #include <linux/module.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/device.h> |
15 | #include <linux/list.h> |
16 | #include <linux/errno.h> |
17 | #include <linux/err.h> |
18 | #include <linux/string.h> |
19 | #include <linux/mutex.h> |
20 | #include <linux/clk.h> |
21 | #include <linux/clkdev.h> |
22 | #include <linux/of.h> |
23 | |
24 | static LIST_HEAD(clocks); |
25 | static DEFINE_MUTEX(clocks_mutex); |
26 | |
27 | #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) |
28 | struct clk *of_clk_get(struct device_node *np, int index) |
29 | { |
30 | struct of_phandle_args clkspec; |
31 | struct clk *clk; |
32 | int rc; |
33 | |
34 | if (index < 0) |
35 | return ERR_PTR(-EINVAL); |
36 | |
37 | rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index, |
38 | &clkspec); |
39 | if (rc) |
40 | return ERR_PTR(rc); |
41 | |
42 | clk = of_clk_get_from_provider(&clkspec); |
43 | of_node_put(clkspec.np); |
44 | return clk; |
45 | } |
46 | EXPORT_SYMBOL(of_clk_get); |
47 | |
48 | /** |
49 | * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node |
50 | * @np: pointer to clock consumer node |
51 | * @name: name of consumer's clock input, or NULL for the first clock reference |
52 | * |
53 | * This function parses the clocks and clock-names properties, |
54 | * and uses them to look up the struct clk from the registered list of clock |
55 | * providers. |
56 | */ |
57 | struct clk *of_clk_get_by_name(struct device_node *np, const char *name) |
58 | { |
59 | struct clk *clk = ERR_PTR(-ENOENT); |
60 | |
61 | /* Walk up the tree of devices looking for a clock that matches */ |
62 | while (np) { |
63 | int index = 0; |
64 | |
65 | /* |
66 | * For named clocks, first look up the name in the |
67 | * "clock-names" property. If it cannot be found, then |
68 | * index will be an error code, and of_clk_get() will fail. |
69 | */ |
70 | if (name) |
71 | index = of_property_match_string(np, "clock-names", name); |
72 | clk = of_clk_get(np, index); |
73 | if (!IS_ERR(clk)) |
74 | break; |
75 | else if (name && index >= 0) { |
76 | pr_err("ERROR: could not get clock %s:%s(%i)\n", |
77 | np->full_name, name ? name : "", index); |
78 | return clk; |
79 | } |
80 | |
81 | /* |
82 | * No matching clock found on this node. If the parent node |
83 | * has a "clock-ranges" property, then we can try one of its |
84 | * clocks. |
85 | */ |
86 | np = np->parent; |
87 | if (np && !of_get_property(np, "clock-ranges", NULL)) |
88 | break; |
89 | } |
90 | |
91 | return clk; |
92 | } |
93 | EXPORT_SYMBOL(of_clk_get_by_name); |
94 | #endif |
95 | |
96 | /* |
97 | * Find the correct struct clk for the device and connection ID. |
98 | * We do slightly fuzzy matching here: |
99 | * An entry with a NULL ID is assumed to be a wildcard. |
100 | * If an entry has a device ID, it must match |
101 | * If an entry has a connection ID, it must match |
102 | * Then we take the most specific entry - with the following |
103 | * order of precedence: dev+con > dev only > con only. |
104 | */ |
105 | static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) |
106 | { |
107 | struct clk_lookup *p, *cl = NULL; |
108 | int match, best_found = 0, best_possible = 0; |
109 | |
110 | if (dev_id) |
111 | best_possible += 2; |
112 | if (con_id) |
113 | best_possible += 1; |
114 | |
115 | list_for_each_entry(p, &clocks, node) { |
116 | match = 0; |
117 | if (p->dev_id) { |
118 | if (!dev_id || strcmp(p->dev_id, dev_id)) |
119 | continue; |
120 | match += 2; |
121 | } |
122 | if (p->con_id) { |
123 | if (!con_id || strcmp(p->con_id, con_id)) |
124 | continue; |
125 | match += 1; |
126 | } |
127 | |
128 | if (match > best_found) { |
129 | cl = p; |
130 | if (match != best_possible) |
131 | best_found = match; |
132 | else |
133 | break; |
134 | } |
135 | } |
136 | return cl; |
137 | } |
138 | |
139 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) |
140 | { |
141 | struct clk_lookup *cl; |
142 | |
143 | mutex_lock(&clocks_mutex); |
144 | cl = clk_find(dev_id, con_id); |
145 | if (cl && !__clk_get(cl->clk)) |
146 | cl = NULL; |
147 | mutex_unlock(&clocks_mutex); |
148 | |
149 | return cl ? cl->clk : ERR_PTR(-ENOENT); |
150 | } |
151 | EXPORT_SYMBOL(clk_get_sys); |
152 | |
153 | struct clk *clk_get(struct device *dev, const char *con_id) |
154 | { |
155 | const char *dev_id = dev ? dev_name(dev) : NULL; |
156 | struct clk *clk; |
157 | |
158 | if (dev) { |
159 | clk = of_clk_get_by_name(dev->of_node, con_id); |
160 | if (!IS_ERR(clk) && __clk_get(clk)) |
161 | return clk; |
162 | } |
163 | |
164 | return clk_get_sys(dev_id, con_id); |
165 | } |
166 | EXPORT_SYMBOL(clk_get); |
167 | |
168 | void clk_put(struct clk *clk) |
169 | { |
170 | __clk_put(clk); |
171 | } |
172 | EXPORT_SYMBOL(clk_put); |
173 | |
174 | void clkdev_add(struct clk_lookup *cl) |
175 | { |
176 | mutex_lock(&clocks_mutex); |
177 | list_add_tail(&cl->node, &clocks); |
178 | mutex_unlock(&clocks_mutex); |
179 | } |
180 | EXPORT_SYMBOL(clkdev_add); |
181 | |
182 | void __init clkdev_add_table(struct clk_lookup *cl, size_t num) |
183 | { |
184 | mutex_lock(&clocks_mutex); |
185 | while (num--) { |
186 | list_add_tail(&cl->node, &clocks); |
187 | cl++; |
188 | } |
189 | mutex_unlock(&clocks_mutex); |
190 | } |
191 | |
192 | #define MAX_DEV_ID 20 |
193 | #define MAX_CON_ID 16 |
194 | |
195 | struct clk_lookup_alloc { |
196 | struct clk_lookup cl; |
197 | char dev_id[MAX_DEV_ID]; |
198 | char con_id[MAX_CON_ID]; |
199 | }; |
200 | |
201 | static struct clk_lookup * __init_refok |
202 | vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, |
203 | va_list ap) |
204 | { |
205 | struct clk_lookup_alloc *cla; |
206 | |
207 | cla = __clkdev_alloc(sizeof(*cla)); |
208 | if (!cla) |
209 | return NULL; |
210 | |
211 | cla->cl.clk = clk; |
212 | if (con_id) { |
213 | strlcpy(cla->con_id, con_id, sizeof(cla->con_id)); |
214 | cla->cl.con_id = cla->con_id; |
215 | } |
216 | |
217 | if (dev_fmt) { |
218 | vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap); |
219 | cla->cl.dev_id = cla->dev_id; |
220 | } |
221 | |
222 | return &cla->cl; |
223 | } |
224 | |
225 | struct clk_lookup * __init_refok |
226 | clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) |
227 | { |
228 | struct clk_lookup *cl; |
229 | va_list ap; |
230 | |
231 | va_start(ap, dev_fmt); |
232 | cl = vclkdev_alloc(clk, con_id, dev_fmt, ap); |
233 | va_end(ap); |
234 | |
235 | return cl; |
236 | } |
237 | EXPORT_SYMBOL(clkdev_alloc); |
238 | |
239 | int clk_add_alias(const char *alias, const char *alias_dev_name, char *id, |
240 | struct device *dev) |
241 | { |
242 | struct clk *r = clk_get(dev, id); |
243 | struct clk_lookup *l; |
244 | |
245 | if (IS_ERR(r)) |
246 | return PTR_ERR(r); |
247 | |
248 | l = clkdev_alloc(r, alias, alias_dev_name); |
249 | clk_put(r); |
250 | if (!l) |
251 | return -ENODEV; |
252 | clkdev_add(l); |
253 | return 0; |
254 | } |
255 | EXPORT_SYMBOL(clk_add_alias); |
256 | |
257 | /* |
258 | * clkdev_drop - remove a clock dynamically allocated |
259 | */ |
260 | void clkdev_drop(struct clk_lookup *cl) |
261 | { |
262 | mutex_lock(&clocks_mutex); |
263 | list_del(&cl->node); |
264 | mutex_unlock(&clocks_mutex); |
265 | kfree(cl); |
266 | } |
267 | EXPORT_SYMBOL(clkdev_drop); |
268 | |
269 | /** |
270 | * clk_register_clkdev - register one clock lookup for a struct clk |
271 | * @clk: struct clk to associate with all clk_lookups |
272 | * @con_id: connection ID string on device |
273 | * @dev_id: format string describing device name |
274 | * |
275 | * con_id or dev_id may be NULL as a wildcard, just as in the rest of |
276 | * clkdev. |
277 | * |
278 | * To make things easier for mass registration, we detect error clks |
279 | * from a previous clk_register() call, and return the error code for |
280 | * those. This is to permit this function to be called immediately |
281 | * after clk_register(). |
282 | */ |
283 | int clk_register_clkdev(struct clk *clk, const char *con_id, |
284 | const char *dev_fmt, ...) |
285 | { |
286 | struct clk_lookup *cl; |
287 | va_list ap; |
288 | |
289 | if (IS_ERR(clk)) |
290 | return PTR_ERR(clk); |
291 | |
292 | va_start(ap, dev_fmt); |
293 | cl = vclkdev_alloc(clk, con_id, dev_fmt, ap); |
294 | va_end(ap); |
295 | |
296 | if (!cl) |
297 | return -ENOMEM; |
298 | |
299 | clkdev_add(cl); |
300 | |
301 | return 0; |
302 | } |
303 | |
304 | /** |
305 | * clk_register_clkdevs - register a set of clk_lookup for a struct clk |
306 | * @clk: struct clk to associate with all clk_lookups |
307 | * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized |
308 | * @num: number of clk_lookup structures to register |
309 | * |
310 | * To make things easier for mass registration, we detect error clks |
311 | * from a previous clk_register() call, and return the error code for |
312 | * those. This is to permit this function to be called immediately |
313 | * after clk_register(). |
314 | */ |
315 | int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num) |
316 | { |
317 | unsigned i; |
318 | |
319 | if (IS_ERR(clk)) |
320 | return PTR_ERR(clk); |
321 | |
322 | for (i = 0; i < num; i++, cl++) { |
323 | cl->clk = clk; |
324 | clkdev_add(cl); |
325 | } |
326 | |
327 | return 0; |
328 | } |
329 | EXPORT_SYMBOL(clk_register_clkdevs); |
330 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9