diff options
Diffstat (limited to 'drivers')
| -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 |
4 files changed, 322 insertions, 113 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) |
