hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/clk/clkdev.c
....@@ -1,11 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * drivers/clk/clkdev.c
34 *
45 * 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.
96 *
107 * Helper for the clk API to assist looking up a struct clk.
118 */
....@@ -27,99 +24,6 @@
2724 static LIST_HEAD(clocks);
2825 static DEFINE_MUTEX(clocks_mutex);
2926
30
-#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
31
-static struct clk *__of_clk_get(struct device_node *np, int index,
32
- const char *dev_id, const char *con_id)
33
-{
34
- struct of_phandle_args clkspec;
35
- struct clk *clk;
36
- int rc;
37
-
38
- rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
39
- &clkspec);
40
- if (rc)
41
- return ERR_PTR(rc);
42
-
43
- clk = __of_clk_get_from_provider(&clkspec, dev_id, con_id, true);
44
- of_node_put(clkspec.np);
45
-
46
- return clk;
47
-}
48
-
49
-struct clk *of_clk_get(struct device_node *np, int index)
50
-{
51
- return __of_clk_get(np, index, np->full_name, NULL);
52
-}
53
-EXPORT_SYMBOL(of_clk_get);
54
-
55
-static struct clk *__of_clk_get_by_name(struct device_node *np,
56
- const char *dev_id,
57
- 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, dev_id, name);
73
- if (!IS_ERR(clk)) {
74
- break;
75
- } else if (name && index >= 0) {
76
- if (PTR_ERR(clk) != -EPROBE_DEFER)
77
- pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
78
- np, name ? name : "", index);
79
- return clk;
80
- }
81
-
82
- /*
83
- * No matching clock found on this node. If the parent node
84
- * has a "clock-ranges" property, then we can try one of its
85
- * clocks.
86
- */
87
- np = np->parent;
88
- if (np && !of_get_property(np, "clock-ranges", NULL))
89
- break;
90
- }
91
-
92
- return clk;
93
-}
94
-
95
-/**
96
- * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
97
- * @np: pointer to clock consumer node
98
- * @name: name of consumer's clock input, or NULL for the first clock reference
99
- *
100
- * This function parses the clocks and clock-names properties,
101
- * and uses them to look up the struct clk from the registered list of clock
102
- * providers.
103
- */
104
-struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
105
-{
106
- if (!np)
107
- return ERR_PTR(-ENOENT);
108
-
109
- return __of_clk_get_by_name(np, np->full_name, name);
110
-}
111
-EXPORT_SYMBOL(of_clk_get_by_name);
112
-
113
-#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
114
-
115
-static struct clk *__of_clk_get_by_name(struct device_node *np,
116
- const char *dev_id,
117
- const char *name)
118
-{
119
- return ERR_PTR(-ENOENT);
120
-}
121
-#endif
122
-
12327 /*
12428 * Find the correct struct clk for the device and connection ID.
12529 * We do slightly fuzzy matching here:
....@@ -138,6 +42,8 @@
13842 best_possible += 2;
13943 if (con_id)
14044 best_possible += 1;
45
+
46
+ lockdep_assert_held(&clocks_mutex);
14147
14248 list_for_each_entry(p, &clocks, node) {
14349 match = 0;
....@@ -163,46 +69,46 @@
16369 return cl;
16470 }
16571
166
-struct clk *clk_get_sys(const char *dev_id, const char *con_id)
72
+struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id)
16773 {
16874 struct clk_lookup *cl;
169
- struct clk *clk = NULL;
75
+ struct clk_hw *hw = ERR_PTR(-ENOENT);
17076
17177 mutex_lock(&clocks_mutex);
172
-
17378 cl = clk_find(dev_id, con_id);
174
- if (!cl)
175
- goto out;
176
-
177
- clk = __clk_create_clk(cl->clk_hw, dev_id, con_id, false);
178
- if (IS_ERR(clk))
179
- goto out;
180
-
181
- if (!__clk_get(clk)) {
182
- __clk_free_clk(clk);
183
- cl = NULL;
184
- goto out;
185
- }
186
-
187
-out:
79
+ if (cl)
80
+ hw = cl->clk_hw;
18881 mutex_unlock(&clocks_mutex);
18982
190
- return cl ? clk : ERR_PTR(-ENOENT);
83
+ return hw;
84
+}
85
+
86
+static struct clk *__clk_get_sys(struct device *dev, const char *dev_id,
87
+ const char *con_id)
88
+{
89
+ struct clk_hw *hw = clk_find_hw(dev_id, con_id);
90
+
91
+ return clk_hw_create_clk(dev, hw, dev_id, con_id);
92
+}
93
+
94
+struct clk *clk_get_sys(const char *dev_id, const char *con_id)
95
+{
96
+ return __clk_get_sys(NULL, dev_id, con_id);
19197 }
19298 EXPORT_SYMBOL(clk_get_sys);
19399
194100 struct clk *clk_get(struct device *dev, const char *con_id)
195101 {
196102 const char *dev_id = dev ? dev_name(dev) : NULL;
197
- struct clk *clk;
103
+ struct clk_hw *hw;
198104
199105 if (dev && dev->of_node) {
200
- clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
201
- if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
202
- return clk;
106
+ hw = of_clk_get_hw(dev->of_node, 0, con_id);
107
+ if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER)
108
+ return clk_hw_create_clk(dev, hw, dev_id, con_id);
203109 }
204110
205
- return clk_get_sys(dev_id, con_id);
111
+ return __clk_get_sys(dev, dev_id, con_id);
206112 }
207113 EXPORT_SYMBOL(clk_get);
208114
....@@ -401,6 +307,23 @@
401307 return cl;
402308 }
403309
310
+static int do_clk_register_clkdev(struct clk_hw *hw,
311
+ struct clk_lookup **cl, const char *con_id, const char *dev_id)
312
+{
313
+ if (IS_ERR(hw))
314
+ return PTR_ERR(hw);
315
+ /*
316
+ * Since dev_id can be NULL, and NULL is handled specially, we must
317
+ * pass it as either a NULL format string, or with "%s".
318
+ */
319
+ if (dev_id)
320
+ *cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
321
+ else
322
+ *cl = __clk_register_clkdev(hw, con_id, NULL);
323
+
324
+ return *cl ? 0 : -ENOMEM;
325
+}
326
+
404327 /**
405328 * clk_register_clkdev - register one clock lookup for a struct clk
406329 * @clk: struct clk to associate with all clk_lookups
....@@ -423,17 +346,8 @@
423346 if (IS_ERR(clk))
424347 return PTR_ERR(clk);
425348
426
- /*
427
- * Since dev_id can be NULL, and NULL is handled specially, we must
428
- * pass it as either a NULL format string, or with "%s".
429
- */
430
- if (dev_id)
431
- cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s",
432
- dev_id);
433
- else
434
- cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL);
435
-
436
- return cl ? 0 : -ENOMEM;
349
+ return do_clk_register_clkdev(__clk_get_hw(clk), &cl, con_id,
350
+ dev_id);
437351 }
438352 EXPORT_SYMBOL(clk_register_clkdev);
439353
....@@ -456,18 +370,78 @@
456370 {
457371 struct clk_lookup *cl;
458372
459
- if (IS_ERR(hw))
460
- return PTR_ERR(hw);
461
-
462
- /*
463
- * Since dev_id can be NULL, and NULL is handled specially, we must
464
- * pass it as either a NULL format string, or with "%s".
465
- */
466
- if (dev_id)
467
- cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
468
- else
469
- cl = __clk_register_clkdev(hw, con_id, NULL);
470
-
471
- return cl ? 0 : -ENOMEM;
373
+ return do_clk_register_clkdev(hw, &cl, con_id, dev_id);
472374 }
473375 EXPORT_SYMBOL(clk_hw_register_clkdev);
376
+
377
+static void devm_clkdev_release(struct device *dev, void *res)
378
+{
379
+ clkdev_drop(*(struct clk_lookup **)res);
380
+}
381
+
382
+static int devm_clk_match_clkdev(struct device *dev, void *res, void *data)
383
+{
384
+ struct clk_lookup **l = res;
385
+
386
+ return *l == data;
387
+}
388
+
389
+/**
390
+ * devm_clk_release_clkdev - Resource managed clkdev lookup release
391
+ * @dev: device this lookup is bound
392
+ * @con_id: connection ID string on device
393
+ * @dev_id: format string describing device name
394
+ *
395
+ * Drop the clkdev lookup created with devm_clk_hw_register_clkdev.
396
+ * Normally this function will not need to be called and the resource
397
+ * management code will ensure that the resource is freed.
398
+ */
399
+void devm_clk_release_clkdev(struct device *dev, const char *con_id,
400
+ const char *dev_id)
401
+{
402
+ struct clk_lookup *cl;
403
+ int rval;
404
+
405
+ mutex_lock(&clocks_mutex);
406
+ cl = clk_find(dev_id, con_id);
407
+ mutex_unlock(&clocks_mutex);
408
+
409
+ WARN_ON(!cl);
410
+ rval = devres_release(dev, devm_clkdev_release,
411
+ devm_clk_match_clkdev, cl);
412
+ WARN_ON(rval);
413
+}
414
+EXPORT_SYMBOL(devm_clk_release_clkdev);
415
+
416
+/**
417
+ * devm_clk_hw_register_clkdev - managed clk lookup registration for clk_hw
418
+ * @dev: device this lookup is bound
419
+ * @hw: struct clk_hw to associate with all clk_lookups
420
+ * @con_id: connection ID string on device
421
+ * @dev_id: format string describing device name
422
+ *
423
+ * con_id or dev_id may be NULL as a wildcard, just as in the rest of
424
+ * clkdev.
425
+ *
426
+ * To make things easier for mass registration, we detect error clk_hws
427
+ * from a previous clk_hw_register_*() call, and return the error code for
428
+ * those. This is to permit this function to be called immediately
429
+ * after clk_hw_register_*().
430
+ */
431
+int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
432
+ const char *con_id, const char *dev_id)
433
+{
434
+ int rval = -ENOMEM;
435
+ struct clk_lookup **cl;
436
+
437
+ cl = devres_alloc(devm_clkdev_release, sizeof(*cl), GFP_KERNEL);
438
+ if (cl) {
439
+ rval = do_clk_register_clkdev(hw, cl, con_id, dev_id);
440
+ if (!rval)
441
+ devres_add(dev, cl);
442
+ else
443
+ devres_free(cl);
444
+ }
445
+ return rval;
446
+}
447
+EXPORT_SYMBOL(devm_clk_hw_register_clkdev);