.. | .. |
---|
19 | 19 | #include <linux/clk-provider.h> |
---|
20 | 20 | #include <linux/clkdev.h> |
---|
21 | 21 | #include <linux/clk/ti.h> |
---|
| 22 | +#include <linux/io.h> |
---|
22 | 23 | #include <linux/of.h> |
---|
23 | 24 | #include <linux/of_address.h> |
---|
24 | 25 | #include <linux/list.h> |
---|
25 | 26 | #include <linux/regmap.h> |
---|
26 | | -#include <linux/bootmem.h> |
---|
| 27 | +#include <linux/memblock.h> |
---|
27 | 28 | #include <linux/device.h> |
---|
28 | 29 | |
---|
29 | 30 | #include "clock.h" |
---|
.. | .. |
---|
31 | 32 | #undef pr_fmt |
---|
32 | 33 | #define pr_fmt(fmt) "%s: " fmt, __func__ |
---|
33 | 34 | |
---|
| 35 | +static LIST_HEAD(clk_hw_omap_clocks); |
---|
34 | 36 | struct ti_clk_ll_ops *ti_clk_ll_ops; |
---|
35 | 37 | static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS]; |
---|
36 | 38 | |
---|
37 | | -static struct ti_clk_features ti_clk_features; |
---|
| 39 | +struct ti_clk_features ti_clk_features; |
---|
38 | 40 | |
---|
39 | 41 | struct clk_iomap { |
---|
40 | 42 | struct regmap *regmap; |
---|
.. | .. |
---|
129 | 131 | void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) |
---|
130 | 132 | { |
---|
131 | 133 | struct ti_dt_clk *c; |
---|
132 | | - struct device_node *node, *parent; |
---|
| 134 | + struct device_node *node, *parent, *child; |
---|
133 | 135 | struct clk *clk; |
---|
134 | 136 | struct of_phandle_args clkspec; |
---|
135 | 137 | char buf[64]; |
---|
.. | .. |
---|
140 | 142 | int ret; |
---|
141 | 143 | static bool clkctrl_nodes_missing; |
---|
142 | 144 | static bool has_clkctrl_data; |
---|
| 145 | + static bool compat_mode; |
---|
| 146 | + |
---|
| 147 | + compat_mode = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT; |
---|
143 | 148 | |
---|
144 | 149 | for (c = oclks; c->node_name != NULL; c++) { |
---|
145 | 150 | strcpy(buf, c->node_name); |
---|
.. | .. |
---|
164 | 169 | continue; |
---|
165 | 170 | |
---|
166 | 171 | node = of_find_node_by_name(NULL, buf); |
---|
167 | | - if (num_args) { |
---|
| 172 | + if (num_args && compat_mode) { |
---|
168 | 173 | parent = node; |
---|
169 | | - node = of_get_child_by_name(parent, "clk"); |
---|
170 | | - of_node_put(parent); |
---|
| 174 | + child = of_get_child_by_name(parent, "clock"); |
---|
| 175 | + if (!child) |
---|
| 176 | + child = of_get_child_by_name(parent, "clk"); |
---|
| 177 | + if (child) { |
---|
| 178 | + of_node_put(parent); |
---|
| 179 | + node = child; |
---|
| 180 | + } |
---|
171 | 181 | } |
---|
172 | 182 | |
---|
173 | 183 | clkspec.np = node; |
---|
.. | .. |
---|
232 | 242 | { |
---|
233 | 243 | struct clk_init_item *retry; |
---|
234 | 244 | |
---|
235 | | - pr_debug("%s: adding to retry list...\n", node->name); |
---|
| 245 | + pr_debug("%pOFn: adding to retry list...\n", node); |
---|
236 | 246 | retry = kzalloc(sizeof(*retry), GFP_KERNEL); |
---|
237 | 247 | if (!retry) |
---|
238 | 248 | return -ENOMEM; |
---|
.. | .. |
---|
267 | 277 | } |
---|
268 | 278 | |
---|
269 | 279 | if (i == CLK_MAX_MEMMAPS) { |
---|
270 | | - pr_err("clk-provider not found for %s!\n", node->name); |
---|
| 280 | + pr_err("clk-provider not found for %pOFn!\n", node); |
---|
271 | 281 | return -ENOENT; |
---|
272 | 282 | } |
---|
273 | 283 | |
---|
274 | 284 | reg->index = i; |
---|
275 | 285 | |
---|
276 | 286 | if (of_property_read_u32_index(node, "reg", index, &val)) { |
---|
277 | | - pr_err("%s must have reg[%d]!\n", node->name, index); |
---|
| 287 | + pr_err("%pOFn must have reg[%d]!\n", node, index); |
---|
278 | 288 | return -EINVAL; |
---|
279 | 289 | } |
---|
280 | 290 | |
---|
.. | .. |
---|
321 | 331 | /* get clocks for this parent */ |
---|
322 | 332 | clocks = of_get_child_by_name(parent, "clocks"); |
---|
323 | 333 | if (!clocks) { |
---|
324 | | - pr_err("%s missing 'clocks' child node.\n", parent->name); |
---|
| 334 | + pr_err("%pOFn missing 'clocks' child node.\n", parent); |
---|
325 | 335 | return -EINVAL; |
---|
326 | 336 | } |
---|
327 | 337 | |
---|
.. | .. |
---|
351 | 361 | { |
---|
352 | 362 | struct clk_iomap *io; |
---|
353 | 363 | |
---|
354 | | - io = memblock_virt_alloc(sizeof(*io), 0); |
---|
| 364 | + io = memblock_alloc(sizeof(*io), SMP_CACHE_BYTES); |
---|
| 365 | + if (!io) |
---|
| 366 | + panic("%s: Failed to allocate %zu bytes\n", __func__, |
---|
| 367 | + sizeof(*io)); |
---|
355 | 368 | |
---|
356 | 369 | io->mem = mem; |
---|
357 | 370 | |
---|
.. | .. |
---|
374 | 387 | |
---|
375 | 388 | while (!list_empty(&retry_list) && retries) { |
---|
376 | 389 | list_for_each_entry_safe(retry, tmp, &retry_list, link) { |
---|
377 | | - pr_debug("retry-init: %s\n", retry->node->name); |
---|
| 390 | + pr_debug("retry-init: %pOFn\n", retry->node); |
---|
378 | 391 | retry->func(retry->user, retry->node); |
---|
379 | 392 | list_del(&retry->link); |
---|
380 | 393 | kfree(retry); |
---|
.. | .. |
---|
518 | 531 | |
---|
519 | 532 | return clk; |
---|
520 | 533 | } |
---|
| 534 | + |
---|
| 535 | +/** |
---|
| 536 | + * ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework |
---|
| 537 | + * @dev: device for this clock |
---|
| 538 | + * @hw: hardware clock handle |
---|
| 539 | + * @con: connection ID for this clock |
---|
| 540 | + * |
---|
| 541 | + * Registers a clk_hw_omap clock to the clock framewor, adds a clock alias |
---|
| 542 | + * for it, and adds the list to the available clk_hw_omap type clocks. |
---|
| 543 | + * Returns a handle to the registered clock if successful, ERR_PTR value |
---|
| 544 | + * in failure. |
---|
| 545 | + */ |
---|
| 546 | +struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw, |
---|
| 547 | + const char *con) |
---|
| 548 | +{ |
---|
| 549 | + struct clk *clk; |
---|
| 550 | + struct clk_hw_omap *oclk; |
---|
| 551 | + |
---|
| 552 | + clk = ti_clk_register(dev, hw, con); |
---|
| 553 | + if (IS_ERR(clk)) |
---|
| 554 | + return clk; |
---|
| 555 | + |
---|
| 556 | + oclk = to_clk_hw_omap(hw); |
---|
| 557 | + |
---|
| 558 | + list_add(&oclk->node, &clk_hw_omap_clocks); |
---|
| 559 | + |
---|
| 560 | + return clk; |
---|
| 561 | +} |
---|
| 562 | + |
---|
| 563 | +/** |
---|
| 564 | + * omap2_clk_for_each - call function for each registered clk_hw_omap |
---|
| 565 | + * @fn: pointer to a callback function |
---|
| 566 | + * |
---|
| 567 | + * Call @fn for each registered clk_hw_omap, passing @hw to each |
---|
| 568 | + * function. @fn must return 0 for success or any other value for |
---|
| 569 | + * failure. If @fn returns non-zero, the iteration across clocks |
---|
| 570 | + * will stop and the non-zero return value will be passed to the |
---|
| 571 | + * caller of omap2_clk_for_each(). |
---|
| 572 | + */ |
---|
| 573 | +int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw)) |
---|
| 574 | +{ |
---|
| 575 | + int ret; |
---|
| 576 | + struct clk_hw_omap *hw; |
---|
| 577 | + |
---|
| 578 | + list_for_each_entry(hw, &clk_hw_omap_clocks, node) { |
---|
| 579 | + ret = (*fn)(hw); |
---|
| 580 | + if (ret) |
---|
| 581 | + break; |
---|
| 582 | + } |
---|
| 583 | + |
---|
| 584 | + return ret; |
---|
| 585 | +} |
---|
| 586 | + |
---|
| 587 | +/** |
---|
| 588 | + * omap2_clk_is_hw_omap - check if the provided clk_hw is OMAP clock |
---|
| 589 | + * @hw: clk_hw to check if it is an omap clock or not |
---|
| 590 | + * |
---|
| 591 | + * Checks if the provided clk_hw is OMAP clock or not. Returns true if |
---|
| 592 | + * it is, false otherwise. |
---|
| 593 | + */ |
---|
| 594 | +bool omap2_clk_is_hw_omap(struct clk_hw *hw) |
---|
| 595 | +{ |
---|
| 596 | + struct clk_hw_omap *oclk; |
---|
| 597 | + |
---|
| 598 | + list_for_each_entry(oclk, &clk_hw_omap_clocks, node) { |
---|
| 599 | + if (&oclk->hw == hw) |
---|
| 600 | + return true; |
---|
| 601 | + } |
---|
| 602 | + |
---|
| 603 | + return false; |
---|
| 604 | +} |
---|