diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-10-16 10:21:42 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2018-10-17 13:43:45 -0400 |
commit | 08979ee55a9f2983265bc46b237576fc7986d56d (patch) | |
tree | 5ce2c172d8b7401355219846e12862b9551be369 | |
parent | 61170a9373ee3cc8e86b033a34d71c16c13473c5 (diff) |
clk: at91: audio-pll: separate registration from DT parsing
Separate registration out of of_sama5d2_clk_audio_pll*_setup to allow other
code to use it.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
[sboyd@kernel.org: Include pmc.h]
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r-- | drivers/clk/at91/clk-audio-pll.c | 149 |
1 files changed, 111 insertions, 38 deletions
diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c index b3eaf654fac9..03b704f0d22f 100644 --- a/drivers/clk/at91/clk-audio-pll.c +++ b/drivers/clk/at91/clk-audio-pll.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <linux/regmap.h> | 43 | #include <linux/regmap.h> |
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | 45 | ||
46 | #include "pmc.h" | ||
47 | |||
46 | #define AUDIO_PLL_DIV_FRAC BIT(22) | 48 | #define AUDIO_PLL_DIV_FRAC BIT(22) |
47 | #define AUDIO_PLL_ND_MAX (AT91_PMC_AUDIO_PLL_ND_MASK >> \ | 49 | #define AUDIO_PLL_ND_MAX (AT91_PMC_AUDIO_PLL_ND_MASK >> \ |
48 | AT91_PMC_AUDIO_PLL_ND_OFFSET) | 50 | AT91_PMC_AUDIO_PLL_ND_OFFSET) |
@@ -444,85 +446,156 @@ static const struct clk_ops audio_pll_pmc_ops = { | |||
444 | .set_rate = clk_audio_pll_pmc_set_rate, | 446 | .set_rate = clk_audio_pll_pmc_set_rate, |
445 | }; | 447 | }; |
446 | 448 | ||
447 | static int of_sama5d2_clk_audio_pll_setup(struct device_node *np, | 449 | struct clk_hw * __init |
448 | struct clk_init_data *init, | 450 | at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name, |
449 | struct clk_hw *hw, | 451 | const char *parent_name) |
450 | struct regmap **clk_audio_regmap) | ||
451 | { | 452 | { |
452 | struct regmap *regmap; | 453 | struct clk_audio_frac *frac_ck; |
453 | const char *parent_names[1]; | 454 | struct clk_init_data init = {}; |
454 | int ret; | 455 | int ret; |
455 | 456 | ||
456 | regmap = syscon_node_to_regmap(of_get_parent(np)); | 457 | frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL); |
457 | if (IS_ERR(regmap)) | 458 | if (!frac_ck) |
458 | return PTR_ERR(regmap); | 459 | return ERR_PTR(-ENOMEM); |
459 | 460 | ||
460 | init->name = np->name; | 461 | init.name = name; |
461 | of_clk_parent_fill(np, parent_names, 1); | 462 | init.ops = &audio_pll_frac_ops; |
462 | init->parent_names = parent_names; | 463 | init.parent_names = &parent_name; |
463 | init->num_parents = 1; | 464 | init.num_parents = 1; |
465 | init.flags = CLK_SET_RATE_GATE; | ||
464 | 466 | ||
465 | hw->init = init; | 467 | frac_ck->hw.init = &init; |
466 | *clk_audio_regmap = regmap; | 468 | frac_ck->regmap = regmap; |
467 | 469 | ||
468 | ret = clk_hw_register(NULL, hw); | 470 | ret = clk_hw_register(NULL, &frac_ck->hw); |
469 | if (ret) | 471 | if (ret) { |
470 | return ret; | 472 | kfree(frac_ck); |
473 | return ERR_PTR(ret); | ||
474 | } | ||
471 | 475 | ||
472 | return of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); | 476 | return &frac_ck->hw; |
473 | } | 477 | } |
474 | 478 | ||
475 | static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) | 479 | static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) |
476 | { | 480 | { |
477 | struct clk_audio_frac *frac_ck; | 481 | struct clk_hw *hw; |
478 | struct clk_init_data init = {}; | 482 | const char *name = np->name; |
483 | const char *parent_name; | ||
484 | struct regmap *regmap; | ||
479 | 485 | ||
480 | frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL); | 486 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
481 | if (!frac_ck) | 487 | if (IS_ERR(regmap)) |
482 | return; | 488 | return; |
483 | 489 | ||
484 | init.ops = &audio_pll_frac_ops; | 490 | parent_name = of_clk_get_parent_name(np, 0); |
485 | init.flags = CLK_SET_RATE_GATE; | ||
486 | 491 | ||
487 | if (of_sama5d2_clk_audio_pll_setup(np, &init, &frac_ck->hw, | 492 | hw = at91_clk_register_audio_pll_frac(regmap, name, parent_name); |
488 | &frac_ck->regmap)) | 493 | if (IS_ERR(hw)) |
489 | kfree(frac_ck); | 494 | return; |
495 | |||
496 | of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); | ||
490 | } | 497 | } |
491 | 498 | ||
492 | static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np) | 499 | struct clk_hw * __init |
500 | at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name, | ||
501 | const char *parent_name) | ||
493 | { | 502 | { |
494 | struct clk_audio_pad *apad_ck; | 503 | struct clk_audio_pad *apad_ck; |
495 | struct clk_init_data init = {}; | 504 | struct clk_init_data init; |
505 | int ret; | ||
496 | 506 | ||
497 | apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL); | 507 | apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL); |
498 | if (!apad_ck) | 508 | if (!apad_ck) |
499 | return; | 509 | return ERR_PTR(-ENOMEM); |
500 | 510 | ||
511 | init.name = name; | ||
501 | init.ops = &audio_pll_pad_ops; | 512 | init.ops = &audio_pll_pad_ops; |
513 | init.parent_names = &parent_name; | ||
514 | init.num_parents = 1; | ||
502 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | | 515 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | |
503 | CLK_SET_RATE_PARENT; | 516 | CLK_SET_RATE_PARENT; |
504 | 517 | ||
505 | if (of_sama5d2_clk_audio_pll_setup(np, &init, &apad_ck->hw, | 518 | apad_ck->hw.init = &init; |
506 | &apad_ck->regmap)) | 519 | apad_ck->regmap = regmap; |
520 | |||
521 | ret = clk_hw_register(NULL, &apad_ck->hw); | ||
522 | if (ret) { | ||
507 | kfree(apad_ck); | 523 | kfree(apad_ck); |
524 | return ERR_PTR(ret); | ||
525 | } | ||
526 | |||
527 | return &apad_ck->hw; | ||
508 | } | 528 | } |
509 | 529 | ||
510 | static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np) | 530 | static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np) |
531 | { | ||
532 | struct clk_hw *hw; | ||
533 | const char *name = np->name; | ||
534 | const char *parent_name; | ||
535 | struct regmap *regmap; | ||
536 | |||
537 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
538 | if (IS_ERR(regmap)) | ||
539 | return; | ||
540 | |||
541 | parent_name = of_clk_get_parent_name(np, 0); | ||
542 | |||
543 | hw = at91_clk_register_audio_pll_pad(regmap, name, parent_name); | ||
544 | if (IS_ERR(hw)) | ||
545 | return; | ||
546 | |||
547 | of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); | ||
548 | } | ||
549 | |||
550 | struct clk_hw * __init | ||
551 | at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name, | ||
552 | const char *parent_name) | ||
511 | { | 553 | { |
512 | struct clk_audio_pmc *apmc_ck; | 554 | struct clk_audio_pmc *apmc_ck; |
513 | struct clk_init_data init = {}; | 555 | struct clk_init_data init; |
556 | int ret; | ||
514 | 557 | ||
515 | apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL); | 558 | apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL); |
516 | if (!apmc_ck) | 559 | if (!apmc_ck) |
517 | return; | 560 | return ERR_PTR(-ENOMEM); |
518 | 561 | ||
562 | init.name = name; | ||
519 | init.ops = &audio_pll_pmc_ops; | 563 | init.ops = &audio_pll_pmc_ops; |
564 | init.parent_names = &parent_name; | ||
565 | init.num_parents = 1; | ||
520 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | | 566 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | |
521 | CLK_SET_RATE_PARENT; | 567 | CLK_SET_RATE_PARENT; |
522 | 568 | ||
523 | if (of_sama5d2_clk_audio_pll_setup(np, &init, &apmc_ck->hw, | 569 | apmc_ck->hw.init = &init; |
524 | &apmc_ck->regmap)) | 570 | apmc_ck->regmap = regmap; |
571 | |||
572 | ret = clk_hw_register(NULL, &apmc_ck->hw); | ||
573 | if (ret) { | ||
525 | kfree(apmc_ck); | 574 | kfree(apmc_ck); |
575 | return ERR_PTR(ret); | ||
576 | } | ||
577 | |||
578 | return &apmc_ck->hw; | ||
579 | } | ||
580 | |||
581 | static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np) | ||
582 | { | ||
583 | struct clk_hw *hw; | ||
584 | const char *name = np->name; | ||
585 | const char *parent_name; | ||
586 | struct regmap *regmap; | ||
587 | |||
588 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
589 | if (IS_ERR(regmap)) | ||
590 | return; | ||
591 | |||
592 | parent_name = of_clk_get_parent_name(np, 0); | ||
593 | |||
594 | hw = at91_clk_register_audio_pll_pmc(regmap, name, parent_name); | ||
595 | if (IS_ERR(hw)) | ||
596 | return; | ||
597 | |||
598 | of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); | ||
526 | } | 599 | } |
527 | 600 | ||
528 | CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup, | 601 | CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup, |