.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. |
---|
3 | 4 | * Author: Thomas Abraham <thomas.ab@samsung.com> |
---|
4 | 5 | * |
---|
5 | 6 | * Copyright (c) 2015 Samsung Electronics Co., Ltd. |
---|
6 | 7 | * Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License version 2 as |
---|
10 | | - * published by the Free Software Foundation. |
---|
11 | 8 | * |
---|
12 | 9 | * This file contains the utility function to register CPU clock for Samsung |
---|
13 | 10 | * Exynos platforms. A CPU clock is defined as a clock supplied to a CPU or a |
---|
.. | .. |
---|
33 | 30 | */ |
---|
34 | 31 | |
---|
35 | 32 | #include <linux/errno.h> |
---|
| 33 | +#include <linux/io.h> |
---|
36 | 34 | #include <linux/slab.h> |
---|
37 | 35 | #include <linux/clk.h> |
---|
38 | 36 | #include <linux/clk-provider.h> |
---|
.. | .. |
---|
403 | 401 | |
---|
404 | 402 | /* helper function to register a CPU clock */ |
---|
405 | 403 | int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, |
---|
406 | | - unsigned int lookup_id, const char *name, const char *parent, |
---|
407 | | - const char *alt_parent, unsigned long offset, |
---|
408 | | - const struct exynos_cpuclk_cfg_data *cfg, |
---|
| 404 | + unsigned int lookup_id, const char *name, |
---|
| 405 | + const struct clk_hw *parent, const struct clk_hw *alt_parent, |
---|
| 406 | + unsigned long offset, const struct exynos_cpuclk_cfg_data *cfg, |
---|
409 | 407 | unsigned long num_cfgs, unsigned long flags) |
---|
410 | 408 | { |
---|
411 | 409 | struct exynos_cpuclk *cpuclk; |
---|
412 | | - struct clk_init_data init = {}; |
---|
413 | | - struct clk *parent_clk; |
---|
| 410 | + struct clk_init_data init; |
---|
| 411 | + const char *parent_name; |
---|
414 | 412 | int ret = 0; |
---|
| 413 | + |
---|
| 414 | + if (IS_ERR(parent) || IS_ERR(alt_parent)) { |
---|
| 415 | + pr_err("%s: invalid parent clock(s)\n", __func__); |
---|
| 416 | + return -EINVAL; |
---|
| 417 | + } |
---|
415 | 418 | |
---|
416 | 419 | cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); |
---|
417 | 420 | if (!cpuclk) |
---|
418 | 421 | return -ENOMEM; |
---|
419 | 422 | |
---|
| 423 | + parent_name = clk_hw_get_name(parent); |
---|
| 424 | + |
---|
420 | 425 | init.name = name; |
---|
421 | 426 | init.flags = CLK_SET_RATE_PARENT; |
---|
422 | | - init.parent_names = &parent; |
---|
| 427 | + init.parent_names = &parent_name; |
---|
423 | 428 | init.num_parents = 1; |
---|
424 | 429 | init.ops = &exynos_cpuclk_clk_ops; |
---|
425 | 430 | |
---|
| 431 | + cpuclk->alt_parent = alt_parent; |
---|
426 | 432 | cpuclk->hw.init = &init; |
---|
427 | 433 | cpuclk->ctrl_base = ctx->reg_base + offset; |
---|
428 | 434 | cpuclk->lock = &ctx->lock; |
---|
.. | .. |
---|
432 | 438 | else |
---|
433 | 439 | cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb; |
---|
434 | 440 | |
---|
435 | | - cpuclk->alt_parent = __clk_get_hw(__clk_lookup(alt_parent)); |
---|
436 | | - if (!cpuclk->alt_parent) { |
---|
437 | | - pr_err("%s: could not lookup alternate parent %s\n", |
---|
438 | | - __func__, alt_parent); |
---|
439 | | - ret = -EINVAL; |
---|
440 | | - goto free_cpuclk; |
---|
441 | | - } |
---|
442 | 441 | |
---|
443 | | - parent_clk = __clk_lookup(parent); |
---|
444 | | - if (!parent_clk) { |
---|
445 | | - pr_err("%s: could not lookup parent clock %s\n", |
---|
446 | | - __func__, parent); |
---|
447 | | - ret = -EINVAL; |
---|
448 | | - goto free_cpuclk; |
---|
449 | | - } |
---|
450 | | - |
---|
451 | | - ret = clk_notifier_register(parent_clk, &cpuclk->clk_nb); |
---|
| 442 | + ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb); |
---|
452 | 443 | if (ret) { |
---|
453 | 444 | pr_err("%s: failed to register clock notifier for %s\n", |
---|
454 | 445 | __func__, name); |
---|
.. | .. |
---|
473 | 464 | free_cpuclk_data: |
---|
474 | 465 | kfree(cpuclk->cfg); |
---|
475 | 466 | unregister_clk_nb: |
---|
476 | | - clk_notifier_unregister(parent_clk, &cpuclk->clk_nb); |
---|
| 467 | + clk_notifier_unregister(parent->clk, &cpuclk->clk_nb); |
---|
477 | 468 | free_cpuclk: |
---|
478 | 469 | kfree(cpuclk); |
---|
479 | 470 | return ret; |
---|