Merge branch 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[sfrench/cifs-2.6.git] / drivers / clk / clkdev.c
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/clk-provider.h>
23 #include <linux/of.h>
24
25 #include "clk.h"
26
27 static LIST_HEAD(clocks);
28 static DEFINE_MUTEX(clocks_mutex);
29
30 /*
31  * Find the correct struct clk for the device and connection ID.
32  * We do slightly fuzzy matching here:
33  *  An entry with a NULL ID is assumed to be a wildcard.
34  *  If an entry has a device ID, it must match
35  *  If an entry has a connection ID, it must match
36  * Then we take the most specific entry - with the following
37  * order of precedence: dev+con > dev only > con only.
38  */
39 static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
40 {
41         struct clk_lookup *p, *cl = NULL;
42         int match, best_found = 0, best_possible = 0;
43
44         if (dev_id)
45                 best_possible += 2;
46         if (con_id)
47                 best_possible += 1;
48
49         lockdep_assert_held(&clocks_mutex);
50
51         list_for_each_entry(p, &clocks, node) {
52                 match = 0;
53                 if (p->dev_id) {
54                         if (!dev_id || strcmp(p->dev_id, dev_id))
55                                 continue;
56                         match += 2;
57                 }
58                 if (p->con_id) {
59                         if (!con_id || strcmp(p->con_id, con_id))
60                                 continue;
61                         match += 1;
62                 }
63
64                 if (match > best_found) {
65                         cl = p;
66                         if (match != best_possible)
67                                 best_found = match;
68                         else
69                                 break;
70                 }
71         }
72         return cl;
73 }
74
75 static struct clk *__clk_get_sys(struct device *dev, const char *dev_id,
76                                  const char *con_id)
77 {
78         struct clk_lookup *cl;
79         struct clk *clk = NULL;
80
81         mutex_lock(&clocks_mutex);
82
83         cl = clk_find(dev_id, con_id);
84         if (!cl)
85                 goto out;
86
87         clk = clk_hw_create_clk(dev, cl->clk_hw, dev_id, con_id);
88         if (IS_ERR(clk))
89                 cl = NULL;
90 out:
91         mutex_unlock(&clocks_mutex);
92
93         return cl ? clk : ERR_PTR(-ENOENT);
94 }
95
96 struct clk *clk_get_sys(const char *dev_id, const char *con_id)
97 {
98         return __clk_get_sys(NULL, dev_id, con_id);
99 }
100 EXPORT_SYMBOL(clk_get_sys);
101
102 struct clk *clk_get(struct device *dev, const char *con_id)
103 {
104         const char *dev_id = dev ? dev_name(dev) : NULL;
105         struct clk_hw *hw;
106
107         if (dev && dev->of_node) {
108                 hw = of_clk_get_hw(dev->of_node, 0, con_id);
109                 if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER)
110                         return clk_hw_create_clk(dev, hw, dev_id, con_id);
111         }
112
113         return __clk_get_sys(dev, dev_id, con_id);
114 }
115 EXPORT_SYMBOL(clk_get);
116
117 void clk_put(struct clk *clk)
118 {
119         __clk_put(clk);
120 }
121 EXPORT_SYMBOL(clk_put);
122
123 static void __clkdev_add(struct clk_lookup *cl)
124 {
125         mutex_lock(&clocks_mutex);
126         list_add_tail(&cl->node, &clocks);
127         mutex_unlock(&clocks_mutex);
128 }
129
130 void clkdev_add(struct clk_lookup *cl)
131 {
132         if (!cl->clk_hw)
133                 cl->clk_hw = __clk_get_hw(cl->clk);
134         __clkdev_add(cl);
135 }
136 EXPORT_SYMBOL(clkdev_add);
137
138 void clkdev_add_table(struct clk_lookup *cl, size_t num)
139 {
140         mutex_lock(&clocks_mutex);
141         while (num--) {
142                 cl->clk_hw = __clk_get_hw(cl->clk);
143                 list_add_tail(&cl->node, &clocks);
144                 cl++;
145         }
146         mutex_unlock(&clocks_mutex);
147 }
148
149 #define MAX_DEV_ID      20
150 #define MAX_CON_ID      16
151
152 struct clk_lookup_alloc {
153         struct clk_lookup cl;
154         char    dev_id[MAX_DEV_ID];
155         char    con_id[MAX_CON_ID];
156 };
157
158 static struct clk_lookup * __ref
159 vclkdev_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
160         va_list ap)
161 {
162         struct clk_lookup_alloc *cla;
163
164         cla = kzalloc(sizeof(*cla), GFP_KERNEL);
165         if (!cla)
166                 return NULL;
167
168         cla->cl.clk_hw = hw;
169         if (con_id) {
170                 strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
171                 cla->cl.con_id = cla->con_id;
172         }
173
174         if (dev_fmt) {
175                 vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
176                 cla->cl.dev_id = cla->dev_id;
177         }
178
179         return &cla->cl;
180 }
181
182 static struct clk_lookup *
183 vclkdev_create(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
184         va_list ap)
185 {
186         struct clk_lookup *cl;
187
188         cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
189         if (cl)
190                 __clkdev_add(cl);
191
192         return cl;
193 }
194
195 struct clk_lookup * __ref
196 clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
197 {
198         struct clk_lookup *cl;
199         va_list ap;
200
201         va_start(ap, dev_fmt);
202         cl = vclkdev_alloc(__clk_get_hw(clk), con_id, dev_fmt, ap);
203         va_end(ap);
204
205         return cl;
206 }
207 EXPORT_SYMBOL(clkdev_alloc);
208
209 struct clk_lookup *
210 clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...)
211 {
212         struct clk_lookup *cl;
213         va_list ap;
214
215         va_start(ap, dev_fmt);
216         cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
217         va_end(ap);
218
219         return cl;
220 }
221 EXPORT_SYMBOL(clkdev_hw_alloc);
222
223 /**
224  * clkdev_create - allocate and add a clkdev lookup structure
225  * @clk: struct clk to associate with all clk_lookups
226  * @con_id: connection ID string on device
227  * @dev_fmt: format string describing device name
228  *
229  * Returns a clk_lookup structure, which can be later unregistered and
230  * freed.
231  */
232 struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
233         const char *dev_fmt, ...)
234 {
235         struct clk_lookup *cl;
236         va_list ap;
237
238         va_start(ap, dev_fmt);
239         cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap);
240         va_end(ap);
241
242         return cl;
243 }
244 EXPORT_SYMBOL_GPL(clkdev_create);
245
246 /**
247  * clkdev_hw_create - allocate and add a clkdev lookup structure
248  * @hw: struct clk_hw to associate with all clk_lookups
249  * @con_id: connection ID string on device
250  * @dev_fmt: format string describing device name
251  *
252  * Returns a clk_lookup structure, which can be later unregistered and
253  * freed.
254  */
255 struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
256         const char *dev_fmt, ...)
257 {
258         struct clk_lookup *cl;
259         va_list ap;
260
261         va_start(ap, dev_fmt);
262         cl = vclkdev_create(hw, con_id, dev_fmt, ap);
263         va_end(ap);
264
265         return cl;
266 }
267 EXPORT_SYMBOL_GPL(clkdev_hw_create);
268
269 int clk_add_alias(const char *alias, const char *alias_dev_name,
270         const char *con_id, struct device *dev)
271 {
272         struct clk *r = clk_get(dev, con_id);
273         struct clk_lookup *l;
274
275         if (IS_ERR(r))
276                 return PTR_ERR(r);
277
278         l = clkdev_create(r, alias, alias_dev_name ? "%s" : NULL,
279                           alias_dev_name);
280         clk_put(r);
281
282         return l ? 0 : -ENODEV;
283 }
284 EXPORT_SYMBOL(clk_add_alias);
285
286 /*
287  * clkdev_drop - remove a clock dynamically allocated
288  */
289 void clkdev_drop(struct clk_lookup *cl)
290 {
291         mutex_lock(&clocks_mutex);
292         list_del(&cl->node);
293         mutex_unlock(&clocks_mutex);
294         kfree(cl);
295 }
296 EXPORT_SYMBOL(clkdev_drop);
297
298 static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw,
299                                                 const char *con_id,
300                                                 const char *dev_id, ...)
301 {
302         struct clk_lookup *cl;
303         va_list ap;
304
305         va_start(ap, dev_id);
306         cl = vclkdev_create(hw, con_id, dev_id, ap);
307         va_end(ap);
308
309         return cl;
310 }
311
312 static int do_clk_register_clkdev(struct clk_hw *hw,
313         struct clk_lookup **cl, const char *con_id, const char *dev_id)
314 {
315         if (IS_ERR(hw))
316                 return PTR_ERR(hw);
317         /*
318          * Since dev_id can be NULL, and NULL is handled specially, we must
319          * pass it as either a NULL format string, or with "%s".
320          */
321         if (dev_id)
322                 *cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
323         else
324                 *cl = __clk_register_clkdev(hw, con_id, NULL);
325
326         return *cl ? 0 : -ENOMEM;
327 }
328
329 /**
330  * clk_register_clkdev - register one clock lookup for a struct clk
331  * @clk: struct clk to associate with all clk_lookups
332  * @con_id: connection ID string on device
333  * @dev_id: string describing device name
334  *
335  * con_id or dev_id may be NULL as a wildcard, just as in the rest of
336  * clkdev.
337  *
338  * To make things easier for mass registration, we detect error clks
339  * from a previous clk_register() call, and return the error code for
340  * those.  This is to permit this function to be called immediately
341  * after clk_register().
342  */
343 int clk_register_clkdev(struct clk *clk, const char *con_id,
344         const char *dev_id)
345 {
346         struct clk_lookup *cl;
347
348         if (IS_ERR(clk))
349                 return PTR_ERR(clk);
350
351         return do_clk_register_clkdev(__clk_get_hw(clk), &cl, con_id,
352                                               dev_id);
353 }
354 EXPORT_SYMBOL(clk_register_clkdev);
355
356 /**
357  * clk_hw_register_clkdev - register one clock lookup for a struct clk_hw
358  * @hw: struct clk_hw to associate with all clk_lookups
359  * @con_id: connection ID string on device
360  * @dev_id: format string describing device name
361  *
362  * con_id or dev_id may be NULL as a wildcard, just as in the rest of
363  * clkdev.
364  *
365  * To make things easier for mass registration, we detect error clk_hws
366  * from a previous clk_hw_register_*() call, and return the error code for
367  * those.  This is to permit this function to be called immediately
368  * after clk_hw_register_*().
369  */
370 int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
371         const char *dev_id)
372 {
373         struct clk_lookup *cl;
374
375         return do_clk_register_clkdev(hw, &cl, con_id, dev_id);
376 }
377 EXPORT_SYMBOL(clk_hw_register_clkdev);
378
379 static void devm_clkdev_release(struct device *dev, void *res)
380 {
381         clkdev_drop(*(struct clk_lookup **)res);
382 }
383
384 static int devm_clk_match_clkdev(struct device *dev, void *res, void *data)
385 {
386         struct clk_lookup **l = res;
387
388         return *l == data;
389 }
390
391 /**
392  * devm_clk_release_clkdev - Resource managed clkdev lookup release
393  * @dev: device this lookup is bound
394  * @con_id: connection ID string on device
395  * @dev_id: format string describing device name
396  *
397  * Drop the clkdev lookup created with devm_clk_hw_register_clkdev.
398  * Normally this function will not need to be called and the resource
399  * management code will ensure that the resource is freed.
400  */
401 void devm_clk_release_clkdev(struct device *dev, const char *con_id,
402                              const char *dev_id)
403 {
404         struct clk_lookup *cl;
405         int rval;
406
407         mutex_lock(&clocks_mutex);
408         cl = clk_find(dev_id, con_id);
409         mutex_unlock(&clocks_mutex);
410
411         WARN_ON(!cl);
412         rval = devres_release(dev, devm_clkdev_release,
413                               devm_clk_match_clkdev, cl);
414         WARN_ON(rval);
415 }
416 EXPORT_SYMBOL(devm_clk_release_clkdev);
417
418 /**
419  * devm_clk_hw_register_clkdev - managed clk lookup registration for clk_hw
420  * @dev: device this lookup is bound
421  * @hw: struct clk_hw to associate with all clk_lookups
422  * @con_id: connection ID string on device
423  * @dev_id: format string describing device name
424  *
425  * con_id or dev_id may be NULL as a wildcard, just as in the rest of
426  * clkdev.
427  *
428  * To make things easier for mass registration, we detect error clk_hws
429  * from a previous clk_hw_register_*() call, and return the error code for
430  * those.  This is to permit this function to be called immediately
431  * after clk_hw_register_*().
432  */
433 int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
434                                 const char *con_id, const char *dev_id)
435 {
436         int rval = -ENOMEM;
437         struct clk_lookup **cl;
438
439         cl = devres_alloc(devm_clkdev_release, sizeof(*cl), GFP_KERNEL);
440         if (cl) {
441                 rval = do_clk_register_clkdev(hw, cl, con_id, dev_id);
442                 if (!rval)
443                         devres_add(dev, cl);
444                 else
445                         devres_free(cl);
446         }
447         return rval;
448 }
449 EXPORT_SYMBOL(devm_clk_hw_register_clkdev);