diff options
author | Stephen Boyd <sboyd@kernel.org> | 2019-05-07 14:46:13 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2019-05-07 14:46:13 -0400 |
commit | c1157f60d72e8b20efc670cef28883832f42406c (patch) | |
tree | e12b4aa8986f184cbf5a92a1816c210c23fdbbc9 | |
parent | 0caf000817353cfc5db22363ecdac63b83d3a3f9 (diff) | |
parent | 1a079560b1450b72ff4e944bb9185e77633d74c4 (diff) |
Merge branch 'clk-parent-rewrite-1' into clk-next
- Rewrite how clk parents can be specified to be DT/clkdev based instead
of just string based
* clk-parent-rewrite-1:
clk: Cache core in clk_fetch_parent_index() without names
clk: fixed-factor: Initialize clk_init_data on stack
clk: fixed-factor: Let clk framework find parent
clk: Allow parents to be specified via clkspec index
clk: Look for parents with clkdev based clk_lookups
clk: Allow parents to be specified without string names
clk: Add of_clk_hw_register() API for early clk drivers
driver core: Let dev_of_node() accept a NULL dev
clk: Prepare for clk registration API that uses DT nodes
clkdev: Move clk creation outside of 'clocks_mutex'
-rw-r--r-- | drivers/clk/clk-fixed-factor.c | 55 | ||||
-rw-r--r-- | drivers/clk/clk.c | 353 | ||||
-rw-r--r-- | drivers/clk/clk.h | 2 | ||||
-rw-r--r-- | drivers/clk/clkdev.c | 25 | ||||
-rw-r--r-- | include/linux/clk-provider.h | 22 | ||||
-rw-r--r-- | include/linux/device.h | 2 |
6 files changed, 345 insertions, 114 deletions
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 8aac2d1b6fea..8b343e59dc61 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c | |||
@@ -64,12 +64,14 @@ const struct clk_ops clk_fixed_factor_ops = { | |||
64 | }; | 64 | }; |
65 | EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); | 65 | EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); |
66 | 66 | ||
67 | struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, | 67 | static struct clk_hw * |
68 | const char *name, const char *parent_name, unsigned long flags, | 68 | __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, |
69 | unsigned int mult, unsigned int div) | 69 | const char *name, const char *parent_name, int index, |
70 | unsigned long flags, unsigned int mult, unsigned int div) | ||
70 | { | 71 | { |
71 | struct clk_fixed_factor *fix; | 72 | struct clk_fixed_factor *fix; |
72 | struct clk_init_data init; | 73 | struct clk_init_data init = { }; |
74 | struct clk_parent_data pdata = { .index = index }; | ||
73 | struct clk_hw *hw; | 75 | struct clk_hw *hw; |
74 | int ret; | 76 | int ret; |
75 | 77 | ||
@@ -85,11 +87,17 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, | |||
85 | init.name = name; | 87 | init.name = name; |
86 | init.ops = &clk_fixed_factor_ops; | 88 | init.ops = &clk_fixed_factor_ops; |
87 | init.flags = flags; | 89 | init.flags = flags; |
88 | init.parent_names = &parent_name; | 90 | if (parent_name) |
91 | init.parent_names = &parent_name; | ||
92 | else | ||
93 | init.parent_data = &pdata; | ||
89 | init.num_parents = 1; | 94 | init.num_parents = 1; |
90 | 95 | ||
91 | hw = &fix->hw; | 96 | hw = &fix->hw; |
92 | ret = clk_hw_register(dev, hw); | 97 | if (dev) |
98 | ret = clk_hw_register(dev, hw); | ||
99 | else | ||
100 | ret = of_clk_hw_register(np, hw); | ||
93 | if (ret) { | 101 | if (ret) { |
94 | kfree(fix); | 102 | kfree(fix); |
95 | hw = ERR_PTR(ret); | 103 | hw = ERR_PTR(ret); |
@@ -97,6 +105,14 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, | |||
97 | 105 | ||
98 | return hw; | 106 | return hw; |
99 | } | 107 | } |
108 | |||
109 | struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, | ||
110 | const char *name, const char *parent_name, unsigned long flags, | ||
111 | unsigned int mult, unsigned int div) | ||
112 | { | ||
113 | return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1, | ||
114 | flags, mult, div); | ||
115 | } | ||
100 | EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); | 116 | EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); |
101 | 117 | ||
102 | struct clk *clk_register_fixed_factor(struct device *dev, const char *name, | 118 | struct clk *clk_register_fixed_factor(struct device *dev, const char *name, |
@@ -143,11 +159,10 @@ static const struct of_device_id set_rate_parent_matches[] = { | |||
143 | { /* Sentinel */ }, | 159 | { /* Sentinel */ }, |
144 | }; | 160 | }; |
145 | 161 | ||
146 | static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) | 162 | static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node) |
147 | { | 163 | { |
148 | struct clk *clk; | 164 | struct clk_hw *hw; |
149 | const char *clk_name = node->name; | 165 | const char *clk_name = node->name; |
150 | const char *parent_name; | ||
151 | unsigned long flags = 0; | 166 | unsigned long flags = 0; |
152 | u32 div, mult; | 167 | u32 div, mult; |
153 | int ret; | 168 | int ret; |
@@ -165,30 +180,28 @@ static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) | |||
165 | } | 180 | } |
166 | 181 | ||
167 | of_property_read_string(node, "clock-output-names", &clk_name); | 182 | of_property_read_string(node, "clock-output-names", &clk_name); |
168 | parent_name = of_clk_get_parent_name(node, 0); | ||
169 | 183 | ||
170 | if (of_match_node(set_rate_parent_matches, node)) | 184 | if (of_match_node(set_rate_parent_matches, node)) |
171 | flags |= CLK_SET_RATE_PARENT; | 185 | flags |= CLK_SET_RATE_PARENT; |
172 | 186 | ||
173 | clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, | 187 | hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0, |
174 | mult, div); | 188 | flags, mult, div); |
175 | if (IS_ERR(clk)) { | 189 | if (IS_ERR(hw)) { |
176 | /* | 190 | /* |
177 | * If parent clock is not registered, registration would fail. | ||
178 | * Clear OF_POPULATED flag so that clock registration can be | 191 | * Clear OF_POPULATED flag so that clock registration can be |
179 | * attempted again from probe function. | 192 | * attempted again from probe function. |
180 | */ | 193 | */ |
181 | of_node_clear_flag(node, OF_POPULATED); | 194 | of_node_clear_flag(node, OF_POPULATED); |
182 | return clk; | 195 | return ERR_CAST(hw); |
183 | } | 196 | } |
184 | 197 | ||
185 | ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); | 198 | ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); |
186 | if (ret) { | 199 | if (ret) { |
187 | clk_unregister(clk); | 200 | clk_hw_unregister_fixed_factor(hw); |
188 | return ERR_PTR(ret); | 201 | return ERR_PTR(ret); |
189 | } | 202 | } |
190 | 203 | ||
191 | return clk; | 204 | return hw; |
192 | } | 205 | } |
193 | 206 | ||
194 | /** | 207 | /** |
@@ -203,17 +216,17 @@ CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock", | |||
203 | 216 | ||
204 | static int of_fixed_factor_clk_remove(struct platform_device *pdev) | 217 | static int of_fixed_factor_clk_remove(struct platform_device *pdev) |
205 | { | 218 | { |
206 | struct clk *clk = platform_get_drvdata(pdev); | 219 | struct clk_hw *clk = platform_get_drvdata(pdev); |
207 | 220 | ||
208 | of_clk_del_provider(pdev->dev.of_node); | 221 | of_clk_del_provider(pdev->dev.of_node); |
209 | clk_unregister_fixed_factor(clk); | 222 | clk_hw_unregister_fixed_factor(clk); |
210 | 223 | ||
211 | return 0; | 224 | return 0; |
212 | } | 225 | } |
213 | 226 | ||
214 | static int of_fixed_factor_clk_probe(struct platform_device *pdev) | 227 | static int of_fixed_factor_clk_probe(struct platform_device *pdev) |
215 | { | 228 | { |
216 | struct clk *clk; | 229 | struct clk_hw *clk; |
217 | 230 | ||
218 | /* | 231 | /* |
219 | * This function is not executed when of_fixed_factor_clk_setup | 232 | * This function is not executed when of_fixed_factor_clk_setup |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 3e1708747cd2..aa51756fd4d6 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -39,15 +39,23 @@ static LIST_HEAD(clk_notifier_list); | |||
39 | 39 | ||
40 | /*** private data structures ***/ | 40 | /*** private data structures ***/ |
41 | 41 | ||
42 | struct clk_parent_map { | ||
43 | const struct clk_hw *hw; | ||
44 | struct clk_core *core; | ||
45 | const char *fw_name; | ||
46 | const char *name; | ||
47 | int index; | ||
48 | }; | ||
49 | |||
42 | struct clk_core { | 50 | struct clk_core { |
43 | const char *name; | 51 | const char *name; |
44 | const struct clk_ops *ops; | 52 | const struct clk_ops *ops; |
45 | struct clk_hw *hw; | 53 | struct clk_hw *hw; |
46 | struct module *owner; | 54 | struct module *owner; |
47 | struct device *dev; | 55 | struct device *dev; |
56 | struct device_node *of_node; | ||
48 | struct clk_core *parent; | 57 | struct clk_core *parent; |
49 | const char **parent_names; | 58 | struct clk_parent_map *parents; |
50 | struct clk_core **parents; | ||
51 | u8 num_parents; | 59 | u8 num_parents; |
52 | u8 new_parent_index; | 60 | u8 new_parent_index; |
53 | unsigned long rate; | 61 | unsigned long rate; |
@@ -316,17 +324,102 @@ static struct clk_core *clk_core_lookup(const char *name) | |||
316 | return NULL; | 324 | return NULL; |
317 | } | 325 | } |
318 | 326 | ||
327 | /** | ||
328 | * clk_core_get - Find the clk_core parent of a clk | ||
329 | * @core: clk to find parent of | ||
330 | * @p_index: parent index to search for | ||
331 | * | ||
332 | * This is the preferred method for clk providers to find the parent of a | ||
333 | * clk when that parent is external to the clk controller. The parent_names | ||
334 | * array is indexed and treated as a local name matching a string in the device | ||
335 | * node's 'clock-names' property or as the 'con_id' matching the device's | ||
336 | * dev_name() in a clk_lookup. This allows clk providers to use their own | ||
337 | * namespace instead of looking for a globally unique parent string. | ||
338 | * | ||
339 | * For example the following DT snippet would allow a clock registered by the | ||
340 | * clock-controller@c001 that has a clk_init_data::parent_data array | ||
341 | * with 'xtal' in the 'name' member to find the clock provided by the | ||
342 | * clock-controller@f00abcd without needing to get the globally unique name of | ||
343 | * the xtal clk. | ||
344 | * | ||
345 | * parent: clock-controller@f00abcd { | ||
346 | * reg = <0xf00abcd 0xabcd>; | ||
347 | * #clock-cells = <0>; | ||
348 | * }; | ||
349 | * | ||
350 | * clock-controller@c001 { | ||
351 | * reg = <0xc001 0xf00d>; | ||
352 | * clocks = <&parent>; | ||
353 | * clock-names = "xtal"; | ||
354 | * #clock-cells = <1>; | ||
355 | * }; | ||
356 | * | ||
357 | * Returns: -ENOENT when the provider can't be found or the clk doesn't | ||
358 | * exist in the provider. -EINVAL when the name can't be found. NULL when the | ||
359 | * provider knows about the clk but it isn't provided on this system. | ||
360 | * A valid clk_core pointer when the clk can be found in the provider. | ||
361 | */ | ||
362 | static struct clk_core *clk_core_get(struct clk_core *core, u8 p_index) | ||
363 | { | ||
364 | const char *name = core->parents[p_index].fw_name; | ||
365 | int index = core->parents[p_index].index; | ||
366 | struct clk_hw *hw = ERR_PTR(-ENOENT); | ||
367 | struct device *dev = core->dev; | ||
368 | const char *dev_id = dev ? dev_name(dev) : NULL; | ||
369 | struct device_node *np = core->of_node; | ||
370 | |||
371 | if (np && index >= 0) | ||
372 | hw = of_clk_get_hw(np, index, name); | ||
373 | |||
374 | /* | ||
375 | * If the DT search above couldn't find the provider or the provider | ||
376 | * didn't know about this clk, fallback to looking up via clkdev based | ||
377 | * clk_lookups | ||
378 | */ | ||
379 | if (PTR_ERR(hw) == -ENOENT && name) | ||
380 | hw = clk_find_hw(dev_id, name); | ||
381 | |||
382 | if (IS_ERR(hw)) | ||
383 | return ERR_CAST(hw); | ||
384 | |||
385 | return hw->core; | ||
386 | } | ||
387 | |||
388 | static void clk_core_fill_parent_index(struct clk_core *core, u8 index) | ||
389 | { | ||
390 | struct clk_parent_map *entry = &core->parents[index]; | ||
391 | struct clk_core *parent = ERR_PTR(-ENOENT); | ||
392 | |||
393 | if (entry->hw) { | ||
394 | parent = entry->hw->core; | ||
395 | /* | ||
396 | * We have a direct reference but it isn't registered yet? | ||
397 | * Orphan it and let clk_reparent() update the orphan status | ||
398 | * when the parent is registered. | ||
399 | */ | ||
400 | if (!parent) | ||
401 | parent = ERR_PTR(-EPROBE_DEFER); | ||
402 | } else { | ||
403 | parent = clk_core_get(core, index); | ||
404 | if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT) | ||
405 | parent = clk_core_lookup(entry->name); | ||
406 | } | ||
407 | |||
408 | /* Only cache it if it's not an error */ | ||
409 | if (!IS_ERR(parent)) | ||
410 | entry->core = parent; | ||
411 | } | ||
412 | |||
319 | static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core, | 413 | static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core, |
320 | u8 index) | 414 | u8 index) |
321 | { | 415 | { |
322 | if (!core || index >= core->num_parents) | 416 | if (!core || index >= core->num_parents || !core->parents) |
323 | return NULL; | 417 | return NULL; |
324 | 418 | ||
325 | if (!core->parents[index]) | 419 | if (!core->parents[index].core) |
326 | core->parents[index] = | 420 | clk_core_fill_parent_index(core, index); |
327 | clk_core_lookup(core->parent_names[index]); | ||
328 | 421 | ||
329 | return core->parents[index]; | 422 | return core->parents[index].core; |
330 | } | 423 | } |
331 | 424 | ||
332 | struct clk_hw * | 425 | struct clk_hw * |
@@ -1520,20 +1613,37 @@ static int clk_fetch_parent_index(struct clk_core *core, | |||
1520 | return -EINVAL; | 1613 | return -EINVAL; |
1521 | 1614 | ||
1522 | for (i = 0; i < core->num_parents; i++) { | 1615 | for (i = 0; i < core->num_parents; i++) { |
1523 | if (core->parents[i] == parent) | 1616 | /* Found it first try! */ |
1617 | if (core->parents[i].core == parent) | ||
1524 | return i; | 1618 | return i; |
1525 | 1619 | ||
1526 | if (core->parents[i]) | 1620 | /* Something else is here, so keep looking */ |
1621 | if (core->parents[i].core) | ||
1527 | continue; | 1622 | continue; |
1528 | 1623 | ||
1529 | /* Fallback to comparing globally unique names */ | 1624 | /* Maybe core hasn't been cached but the hw is all we know? */ |
1530 | if (!strcmp(parent->name, core->parent_names[i])) { | 1625 | if (core->parents[i].hw) { |
1531 | core->parents[i] = parent; | 1626 | if (core->parents[i].hw == parent->hw) |
1532 | return i; | 1627 | break; |
1628 | |||
1629 | /* Didn't match, but we're expecting a clk_hw */ | ||
1630 | continue; | ||
1533 | } | 1631 | } |
1632 | |||
1633 | /* Maybe it hasn't been cached (clk_set_parent() path) */ | ||
1634 | if (parent == clk_core_get(core, i)) | ||
1635 | break; | ||
1636 | |||
1637 | /* Fallback to comparing globally unique names */ | ||
1638 | if (!strcmp(parent->name, core->parents[i].name)) | ||
1639 | break; | ||
1534 | } | 1640 | } |
1535 | 1641 | ||
1536 | return -EINVAL; | 1642 | if (i == core->num_parents) |
1643 | return -EINVAL; | ||
1644 | |||
1645 | core->parents[i].core = parent; | ||
1646 | return i; | ||
1537 | } | 1647 | } |
1538 | 1648 | ||
1539 | /* | 1649 | /* |
@@ -2294,6 +2404,7 @@ void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent) | |||
2294 | bool clk_has_parent(struct clk *clk, struct clk *parent) | 2404 | bool clk_has_parent(struct clk *clk, struct clk *parent) |
2295 | { | 2405 | { |
2296 | struct clk_core *core, *parent_core; | 2406 | struct clk_core *core, *parent_core; |
2407 | int i; | ||
2297 | 2408 | ||
2298 | /* NULL clocks should be nops, so return success if either is NULL. */ | 2409 | /* NULL clocks should be nops, so return success if either is NULL. */ |
2299 | if (!clk || !parent) | 2410 | if (!clk || !parent) |
@@ -2306,8 +2417,11 @@ bool clk_has_parent(struct clk *clk, struct clk *parent) | |||
2306 | if (core->parent == parent_core) | 2417 | if (core->parent == parent_core) |
2307 | return true; | 2418 | return true; |
2308 | 2419 | ||
2309 | return match_string(core->parent_names, core->num_parents, | 2420 | for (i = 0; i < core->num_parents; i++) |
2310 | parent_core->name) >= 0; | 2421 | if (!strcmp(core->parents[i].name, parent_core->name)) |
2422 | return true; | ||
2423 | |||
2424 | return false; | ||
2311 | } | 2425 | } |
2312 | EXPORT_SYMBOL_GPL(clk_has_parent); | 2426 | EXPORT_SYMBOL_GPL(clk_has_parent); |
2313 | 2427 | ||
@@ -2889,9 +3003,9 @@ static int possible_parents_show(struct seq_file *s, void *data) | |||
2889 | int i; | 3003 | int i; |
2890 | 3004 | ||
2891 | for (i = 0; i < core->num_parents - 1; i++) | 3005 | for (i = 0; i < core->num_parents - 1; i++) |
2892 | seq_printf(s, "%s ", core->parent_names[i]); | 3006 | seq_printf(s, "%s ", core->parents[i].name); |
2893 | 3007 | ||
2894 | seq_printf(s, "%s\n", core->parent_names[i]); | 3008 | seq_printf(s, "%s\n", core->parents[i].name); |
2895 | 3009 | ||
2896 | return 0; | 3010 | return 0; |
2897 | } | 3011 | } |
@@ -3025,7 +3139,7 @@ static inline void clk_debug_unregister(struct clk_core *core) | |||
3025 | */ | 3139 | */ |
3026 | static int __clk_core_init(struct clk_core *core) | 3140 | static int __clk_core_init(struct clk_core *core) |
3027 | { | 3141 | { |
3028 | int i, ret; | 3142 | int ret; |
3029 | struct clk_core *orphan; | 3143 | struct clk_core *orphan; |
3030 | struct hlist_node *tmp2; | 3144 | struct hlist_node *tmp2; |
3031 | unsigned long rate; | 3145 | unsigned long rate; |
@@ -3079,12 +3193,6 @@ static int __clk_core_init(struct clk_core *core) | |||
3079 | goto out; | 3193 | goto out; |
3080 | } | 3194 | } |
3081 | 3195 | ||
3082 | /* throw a WARN if any entries in parent_names are NULL */ | ||
3083 | for (i = 0; i < core->num_parents; i++) | ||
3084 | WARN(!core->parent_names[i], | ||
3085 | "%s: invalid NULL in %s's .parent_names\n", | ||
3086 | __func__, core->name); | ||
3087 | |||
3088 | core->parent = __clk_init_parent(core); | 3196 | core->parent = __clk_init_parent(core); |
3089 | 3197 | ||
3090 | /* | 3198 | /* |
@@ -3313,22 +3421,104 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, | |||
3313 | return clk; | 3421 | return clk; |
3314 | } | 3422 | } |
3315 | 3423 | ||
3316 | /** | 3424 | static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist) |
3317 | * clk_register - allocate a new clock, register it and return an opaque cookie | ||
3318 | * @dev: device that is registering this clock | ||
3319 | * @hw: link to hardware-specific clock data | ||
3320 | * | ||
3321 | * clk_register is the *deprecated* interface for populating the clock tree with | ||
3322 | * new clock nodes. Use clk_hw_register() instead. | ||
3323 | * | ||
3324 | * Returns: a pointer to the newly allocated struct clk which | ||
3325 | * cannot be dereferenced by driver code but may be used in conjunction with the | ||
3326 | * rest of the clock API. In the event of an error clk_register will return an | ||
3327 | * error code; drivers must test for an error code after calling clk_register. | ||
3328 | */ | ||
3329 | struct clk *clk_register(struct device *dev, struct clk_hw *hw) | ||
3330 | { | 3425 | { |
3331 | int i, ret; | 3426 | const char *dst; |
3427 | |||
3428 | if (!src) { | ||
3429 | if (must_exist) | ||
3430 | return -EINVAL; | ||
3431 | return 0; | ||
3432 | } | ||
3433 | |||
3434 | *dst_p = dst = kstrdup_const(src, GFP_KERNEL); | ||
3435 | if (!dst) | ||
3436 | return -ENOMEM; | ||
3437 | |||
3438 | return 0; | ||
3439 | } | ||
3440 | |||
3441 | static int clk_core_populate_parent_map(struct clk_core *core) | ||
3442 | { | ||
3443 | const struct clk_init_data *init = core->hw->init; | ||
3444 | u8 num_parents = init->num_parents; | ||
3445 | const char * const *parent_names = init->parent_names; | ||
3446 | const struct clk_hw **parent_hws = init->parent_hws; | ||
3447 | const struct clk_parent_data *parent_data = init->parent_data; | ||
3448 | int i, ret = 0; | ||
3449 | struct clk_parent_map *parents, *parent; | ||
3450 | |||
3451 | if (!num_parents) | ||
3452 | return 0; | ||
3453 | |||
3454 | /* | ||
3455 | * Avoid unnecessary string look-ups of clk_core's possible parents by | ||
3456 | * having a cache of names/clk_hw pointers to clk_core pointers. | ||
3457 | */ | ||
3458 | parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL); | ||
3459 | core->parents = parents; | ||
3460 | if (!parents) | ||
3461 | return -ENOMEM; | ||
3462 | |||
3463 | /* Copy everything over because it might be __initdata */ | ||
3464 | for (i = 0, parent = parents; i < num_parents; i++, parent++) { | ||
3465 | parent->index = -1; | ||
3466 | if (parent_names) { | ||
3467 | /* throw a WARN if any entries are NULL */ | ||
3468 | WARN(!parent_names[i], | ||
3469 | "%s: invalid NULL in %s's .parent_names\n", | ||
3470 | __func__, core->name); | ||
3471 | ret = clk_cpy_name(&parent->name, parent_names[i], | ||
3472 | true); | ||
3473 | } else if (parent_data) { | ||
3474 | parent->hw = parent_data[i].hw; | ||
3475 | parent->index = parent_data[i].index; | ||
3476 | ret = clk_cpy_name(&parent->fw_name, | ||
3477 | parent_data[i].fw_name, false); | ||
3478 | if (!ret) | ||
3479 | ret = clk_cpy_name(&parent->name, | ||
3480 | parent_data[i].name, | ||
3481 | false); | ||
3482 | } else if (parent_hws) { | ||
3483 | parent->hw = parent_hws[i]; | ||
3484 | } else { | ||
3485 | ret = -EINVAL; | ||
3486 | WARN(1, "Must specify parents if num_parents > 0\n"); | ||
3487 | } | ||
3488 | |||
3489 | if (ret) { | ||
3490 | do { | ||
3491 | kfree_const(parents[i].name); | ||
3492 | kfree_const(parents[i].fw_name); | ||
3493 | } while (--i >= 0); | ||
3494 | kfree(parents); | ||
3495 | |||
3496 | return ret; | ||
3497 | } | ||
3498 | } | ||
3499 | |||
3500 | return 0; | ||
3501 | } | ||
3502 | |||
3503 | static void clk_core_free_parent_map(struct clk_core *core) | ||
3504 | { | ||
3505 | int i = core->num_parents; | ||
3506 | |||
3507 | if (!core->num_parents) | ||
3508 | return; | ||
3509 | |||
3510 | while (--i >= 0) { | ||
3511 | kfree_const(core->parents[i].name); | ||
3512 | kfree_const(core->parents[i].fw_name); | ||
3513 | } | ||
3514 | |||
3515 | kfree(core->parents); | ||
3516 | } | ||
3517 | |||
3518 | static struct clk * | ||
3519 | __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) | ||
3520 | { | ||
3521 | int ret; | ||
3332 | struct clk_core *core; | 3522 | struct clk_core *core; |
3333 | 3523 | ||
3334 | core = kzalloc(sizeof(*core), GFP_KERNEL); | 3524 | core = kzalloc(sizeof(*core), GFP_KERNEL); |
@@ -3352,6 +3542,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) | |||
3352 | if (dev && pm_runtime_enabled(dev)) | 3542 | if (dev && pm_runtime_enabled(dev)) |
3353 | core->rpm_enabled = true; | 3543 | core->rpm_enabled = true; |
3354 | core->dev = dev; | 3544 | core->dev = dev; |
3545 | core->of_node = np; | ||
3355 | if (dev && dev->driver) | 3546 | if (dev && dev->driver) |
3356 | core->owner = dev->driver->owner; | 3547 | core->owner = dev->driver->owner; |
3357 | core->hw = hw; | 3548 | core->hw = hw; |
@@ -3361,33 +3552,9 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) | |||
3361 | core->max_rate = ULONG_MAX; | 3552 | core->max_rate = ULONG_MAX; |
3362 | hw->core = core; | 3553 | hw->core = core; |
3363 | 3554 | ||
3364 | /* allocate local copy in case parent_names is __initdata */ | 3555 | ret = clk_core_populate_parent_map(core); |
3365 | core->parent_names = kcalloc(core->num_parents, sizeof(char *), | 3556 | if (ret) |
3366 | GFP_KERNEL); | ||
3367 | |||
3368 | if (!core->parent_names) { | ||
3369 | ret = -ENOMEM; | ||
3370 | goto fail_parent_names; | ||
3371 | } | ||
3372 | |||
3373 | |||
3374 | /* copy each string name in case parent_names is __initdata */ | ||
3375 | for (i = 0; i < core->num_parents; i++) { | ||
3376 | core->parent_names[i] = kstrdup_const(hw->init->parent_names[i], | ||
3377 | GFP_KERNEL); | ||
3378 | if (!core->parent_names[i]) { | ||
3379 | ret = -ENOMEM; | ||
3380 | goto fail_parent_names_copy; | ||
3381 | } | ||
3382 | } | ||
3383 | |||
3384 | /* avoid unnecessary string look-ups of clk_core's possible parents. */ | ||
3385 | core->parents = kcalloc(core->num_parents, sizeof(*core->parents), | ||
3386 | GFP_KERNEL); | ||
3387 | if (!core->parents) { | ||
3388 | ret = -ENOMEM; | ||
3389 | goto fail_parents; | 3557 | goto fail_parents; |
3390 | }; | ||
3391 | 3558 | ||
3392 | INIT_HLIST_HEAD(&core->clks); | 3559 | INIT_HLIST_HEAD(&core->clks); |
3393 | 3560 | ||
@@ -3398,7 +3565,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) | |||
3398 | hw->clk = alloc_clk(core, NULL, NULL); | 3565 | hw->clk = alloc_clk(core, NULL, NULL); |
3399 | if (IS_ERR(hw->clk)) { | 3566 | if (IS_ERR(hw->clk)) { |
3400 | ret = PTR_ERR(hw->clk); | 3567 | ret = PTR_ERR(hw->clk); |
3401 | goto fail_parents; | 3568 | goto fail_create_clk; |
3402 | } | 3569 | } |
3403 | 3570 | ||
3404 | clk_core_link_consumer(hw->core, hw->clk); | 3571 | clk_core_link_consumer(hw->core, hw->clk); |
@@ -3414,13 +3581,9 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) | |||
3414 | free_clk(hw->clk); | 3581 | free_clk(hw->clk); |
3415 | hw->clk = NULL; | 3582 | hw->clk = NULL; |
3416 | 3583 | ||
3584 | fail_create_clk: | ||
3585 | clk_core_free_parent_map(core); | ||
3417 | fail_parents: | 3586 | fail_parents: |
3418 | kfree(core->parents); | ||
3419 | fail_parent_names_copy: | ||
3420 | while (--i >= 0) | ||
3421 | kfree_const(core->parent_names[i]); | ||
3422 | kfree(core->parent_names); | ||
3423 | fail_parent_names: | ||
3424 | fail_ops: | 3587 | fail_ops: |
3425 | kfree_const(core->name); | 3588 | kfree_const(core->name); |
3426 | fail_name: | 3589 | fail_name: |
@@ -3428,6 +3591,24 @@ fail_name: | |||
3428 | fail_out: | 3591 | fail_out: |
3429 | return ERR_PTR(ret); | 3592 | return ERR_PTR(ret); |
3430 | } | 3593 | } |
3594 | |||
3595 | /** | ||
3596 | * clk_register - allocate a new clock, register it and return an opaque cookie | ||
3597 | * @dev: device that is registering this clock | ||
3598 | * @hw: link to hardware-specific clock data | ||
3599 | * | ||
3600 | * clk_register is the *deprecated* interface for populating the clock tree with | ||
3601 | * new clock nodes. Use clk_hw_register() instead. | ||
3602 | * | ||
3603 | * Returns: a pointer to the newly allocated struct clk which | ||
3604 | * cannot be dereferenced by driver code but may be used in conjunction with the | ||
3605 | * rest of the clock API. In the event of an error clk_register will return an | ||
3606 | * error code; drivers must test for an error code after calling clk_register. | ||
3607 | */ | ||
3608 | struct clk *clk_register(struct device *dev, struct clk_hw *hw) | ||
3609 | { | ||
3610 | return __clk_register(dev, dev_of_node(dev), hw); | ||
3611 | } | ||
3431 | EXPORT_SYMBOL_GPL(clk_register); | 3612 | EXPORT_SYMBOL_GPL(clk_register); |
3432 | 3613 | ||
3433 | /** | 3614 | /** |
@@ -3442,23 +3623,35 @@ EXPORT_SYMBOL_GPL(clk_register); | |||
3442 | */ | 3623 | */ |
3443 | int clk_hw_register(struct device *dev, struct clk_hw *hw) | 3624 | int clk_hw_register(struct device *dev, struct clk_hw *hw) |
3444 | { | 3625 | { |
3445 | return PTR_ERR_OR_ZERO(clk_register(dev, hw)); | 3626 | return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw)); |
3446 | } | 3627 | } |
3447 | EXPORT_SYMBOL_GPL(clk_hw_register); | 3628 | EXPORT_SYMBOL_GPL(clk_hw_register); |
3448 | 3629 | ||
3630 | /* | ||
3631 | * of_clk_hw_register - register a clk_hw and return an error code | ||
3632 | * @node: device_node of device that is registering this clock | ||
3633 | * @hw: link to hardware-specific clock data | ||
3634 | * | ||
3635 | * of_clk_hw_register() is the primary interface for populating the clock tree | ||
3636 | * with new clock nodes when a struct device is not available, but a struct | ||
3637 | * device_node is. It returns an integer equal to zero indicating success or | ||
3638 | * less than zero indicating failure. Drivers must test for an error code after | ||
3639 | * calling of_clk_hw_register(). | ||
3640 | */ | ||
3641 | int of_clk_hw_register(struct device_node *node, struct clk_hw *hw) | ||
3642 | { | ||
3643 | return PTR_ERR_OR_ZERO(__clk_register(NULL, node, hw)); | ||
3644 | } | ||
3645 | EXPORT_SYMBOL_GPL(of_clk_hw_register); | ||
3646 | |||
3449 | /* Free memory allocated for a clock. */ | 3647 | /* Free memory allocated for a clock. */ |
3450 | static void __clk_release(struct kref *ref) | 3648 | static void __clk_release(struct kref *ref) |
3451 | { | 3649 | { |
3452 | struct clk_core *core = container_of(ref, struct clk_core, ref); | 3650 | struct clk_core *core = container_of(ref, struct clk_core, ref); |
3453 | int i = core->num_parents; | ||
3454 | 3651 | ||
3455 | lockdep_assert_held(&prepare_lock); | 3652 | lockdep_assert_held(&prepare_lock); |
3456 | 3653 | ||
3457 | kfree(core->parents); | 3654 | clk_core_free_parent_map(core); |
3458 | while (--i >= 0) | ||
3459 | kfree_const(core->parent_names[i]); | ||
3460 | |||
3461 | kfree(core->parent_names); | ||
3462 | kfree_const(core->name); | 3655 | kfree_const(core->name); |
3463 | kfree(core); | 3656 | kfree(core); |
3464 | } | 3657 | } |
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 553f531cc232..d8400d623b34 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h | |||
@@ -19,6 +19,8 @@ static inline struct clk_hw *of_clk_get_hw(struct device_node *np, | |||
19 | } | 19 | } |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id); | ||
23 | |||
22 | #ifdef CONFIG_COMMON_CLK | 24 | #ifdef CONFIG_COMMON_CLK |
23 | struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, | 25 | struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, |
24 | const char *dev_id, const char *con_id); | 26 | const char *dev_id, const char *con_id); |
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 6e787cc9e5b9..2afc8df8acff 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c | |||
@@ -72,25 +72,26 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) | |||
72 | return cl; | 72 | return cl; |
73 | } | 73 | } |
74 | 74 | ||
75 | static struct clk *__clk_get_sys(struct device *dev, const char *dev_id, | 75 | struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id) |
76 | const char *con_id) | ||
77 | { | 76 | { |
78 | struct clk_lookup *cl; | 77 | struct clk_lookup *cl; |
79 | struct clk *clk = NULL; | 78 | struct clk_hw *hw = ERR_PTR(-ENOENT); |
80 | 79 | ||
81 | mutex_lock(&clocks_mutex); | 80 | mutex_lock(&clocks_mutex); |
82 | |||
83 | cl = clk_find(dev_id, con_id); | 81 | cl = clk_find(dev_id, con_id); |
84 | if (!cl) | 82 | if (cl) |
85 | goto out; | 83 | hw = cl->clk_hw; |
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); | 84 | mutex_unlock(&clocks_mutex); |
92 | 85 | ||
93 | return cl ? clk : ERR_PTR(-ENOENT); | 86 | return hw; |
87 | } | ||
88 | |||
89 | static struct clk *__clk_get_sys(struct device *dev, const char *dev_id, | ||
90 | const char *con_id) | ||
91 | { | ||
92 | struct clk_hw *hw = clk_find_hw(dev_id, con_id); | ||
93 | |||
94 | return clk_hw_create_clk(dev, hw, dev_id, con_id); | ||
94 | } | 95 | } |
95 | 96 | ||
96 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) | 97 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 8fa494aaa34d..491d992d045d 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -251,19 +251,40 @@ struct clk_ops { | |||
251 | }; | 251 | }; |
252 | 252 | ||
253 | /** | 253 | /** |
254 | * struct clk_parent_data - clk parent information | ||
255 | * @hw: parent clk_hw pointer (used for clk providers with internal clks) | ||
256 | * @fw_name: parent name local to provider registering clk | ||
257 | * @name: globally unique parent name (used as a fallback) | ||
258 | * @index: parent index local to provider registering clk (if @fw_name absent) | ||
259 | */ | ||
260 | struct clk_parent_data { | ||
261 | const struct clk_hw *hw; | ||
262 | const char *fw_name; | ||
263 | const char *name; | ||
264 | int index; | ||
265 | }; | ||
266 | |||
267 | /** | ||
254 | * struct clk_init_data - holds init data that's common to all clocks and is | 268 | * struct clk_init_data - holds init data that's common to all clocks and is |
255 | * shared between the clock provider and the common clock framework. | 269 | * shared between the clock provider and the common clock framework. |
256 | * | 270 | * |
257 | * @name: clock name | 271 | * @name: clock name |
258 | * @ops: operations this clock supports | 272 | * @ops: operations this clock supports |
259 | * @parent_names: array of string names for all possible parents | 273 | * @parent_names: array of string names for all possible parents |
274 | * @parent_data: array of parent data for all possible parents (when some | ||
275 | * parents are external to the clk controller) | ||
276 | * @parent_hws: array of pointers to all possible parents (when all parents | ||
277 | * are internal to the clk controller) | ||
260 | * @num_parents: number of possible parents | 278 | * @num_parents: number of possible parents |
261 | * @flags: framework-level hints and quirks | 279 | * @flags: framework-level hints and quirks |
262 | */ | 280 | */ |
263 | struct clk_init_data { | 281 | struct clk_init_data { |
264 | const char *name; | 282 | const char *name; |
265 | const struct clk_ops *ops; | 283 | const struct clk_ops *ops; |
284 | /* Only one of the following three should be assigned */ | ||
266 | const char * const *parent_names; | 285 | const char * const *parent_names; |
286 | const struct clk_parent_data *parent_data; | ||
287 | const struct clk_hw **parent_hws; | ||
267 | u8 num_parents; | 288 | u8 num_parents; |
268 | unsigned long flags; | 289 | unsigned long flags; |
269 | }; | 290 | }; |
@@ -776,6 +797,7 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw); | |||
776 | 797 | ||
777 | int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw); | 798 | int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw); |
778 | int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw); | 799 | int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw); |
800 | int __must_check of_clk_hw_register(struct device_node *node, struct clk_hw *hw); | ||
779 | 801 | ||
780 | void clk_unregister(struct clk *clk); | 802 | void clk_unregister(struct clk *clk); |
781 | void devm_clk_unregister(struct device *dev, struct clk *clk); | 803 | void devm_clk_unregister(struct device *dev, struct clk *clk); |
diff --git a/include/linux/device.h b/include/linux/device.h index 4e6987e11f68..ad626df2e12e 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -1229,7 +1229,7 @@ static inline void device_lock_assert(struct device *dev) | |||
1229 | 1229 | ||
1230 | static inline struct device_node *dev_of_node(struct device *dev) | 1230 | static inline struct device_node *dev_of_node(struct device *dev) |
1231 | { | 1231 | { |
1232 | if (!IS_ENABLED(CONFIG_OF)) | 1232 | if (!IS_ENABLED(CONFIG_OF) || !dev) |
1233 | return NULL; | 1233 | return NULL; |
1234 | return dev->of_node; | 1234 | return dev->of_node; |
1235 | } | 1235 | } |