xref: /openbmc/linux/drivers/clk/clkdev.c (revision 8f8d5745bb520c76b81abef4a2cb3023d0313bfd)
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);
450