aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/bcm/clk-kona-setup.c
diff options
context:
space:
mode:
authorAlex Elder <elder@linaro.org>2014-04-21 17:11:41 -0400
committerMike Turquette <mturquette@linaro.org>2014-04-30 14:51:35 -0400
commit03548ec06ad3ec75d5b212fa832e4e617334ea09 (patch)
tree3746d54ef058113437fea44065947de4aa05a47f /drivers/clk/bcm/clk-kona-setup.c
parentb12151ca5cd76e5ed9c75ef02b2f5d2aa5b45808 (diff)
clk: bcm281xx: define CCU clock data statically
Rather than "manually" setting up each CCU's clock entries at run time, define a flexible array of generic Kona clock structures within the CCU structure itself. Each of these entries contains generic kona clock information (like its CCU pointer and clock framework initialization data). Each also has a pointer to a structure contianing clock type-dependent initialization data (like register definitions). Since we'll iterate over these arrays we need to be sure they have slots for all potential clock index values. (E.g. for the root CCU we must have at least BCM281XX_ROOT_CCU_CLOCK_COUNT slots.) To ensure this we always define an extra entry and fill it using the special initializer LAST_KONA_CLK. Just about everything we need to know about a clock can be defined statically. As a result, kona_clk_setup() can be changed to take just a kona_clk structure as its argument, and peri_clk_setup() can be simplified. With the information pre-defined we are also able to handle most clock setup genericially. We can do away with the CCU-specific callback functions that previously were needed to set up the entries in CCU's clock array. Move the definition of the ccu_data structure down in "clk-kona.h" to avoid a forward dependency. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/bcm/clk-kona-setup.c')
-rw-r--r--drivers/clk/bcm/clk-kona-setup.c60
1 files changed, 25 insertions, 35 deletions
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c
index 4d1ca5372eff..825a2f2ab052 100644
--- a/drivers/clk/bcm/clk-kona-setup.c
+++ b/drivers/clk/bcm/clk-kona-setup.c
@@ -567,7 +567,6 @@ static void peri_clk_teardown(struct peri_clk_data *data,
567 struct clk_init_data *init_data) 567 struct clk_init_data *init_data)
568{ 568{
569 clk_sel_teardown(&data->sel, init_data); 569 clk_sel_teardown(&data->sel, init_data);
570 init_data->ops = NULL;
571} 570}
572 571
573/* 572/*
@@ -576,10 +575,9 @@ static void peri_clk_teardown(struct peri_clk_data *data,
576 * that can be assigned if the clock has one or more parent clocks 575 * that can be assigned if the clock has one or more parent clocks
577 * associated with it. 576 * associated with it.
578 */ 577 */
579static int peri_clk_setup(struct ccu_data *ccu, struct peri_clk_data *data, 578static int
580 struct clk_init_data *init_data) 579peri_clk_setup(struct peri_clk_data *data, struct clk_init_data *init_data)
581{ 580{
582 init_data->ops = &kona_peri_clk_ops;
583 init_data->flags = CLK_IGNORE_UNUSED; 581 init_data->flags = CLK_IGNORE_UNUSED;
584 582
585 return clk_sel_setup(data->clocks, &data->sel, init_data); 583 return clk_sel_setup(data->clocks, &data->sel, init_data);
@@ -617,39 +615,26 @@ static void kona_clk_teardown(struct clk *clk)
617 bcm_clk_teardown(bcm_clk); 615 bcm_clk_teardown(bcm_clk);
618} 616}
619 617
620struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, 618struct clk *kona_clk_setup(struct kona_clk *bcm_clk)
621 enum bcm_clk_type type, void *data)
622{ 619{
623 struct kona_clk *bcm_clk; 620 struct clk_init_data *init_data = &bcm_clk->init_data;
624 struct clk_init_data *init_data;
625 struct clk *clk = NULL; 621 struct clk *clk = NULL;
626 622
627 bcm_clk = kzalloc(sizeof(*bcm_clk), GFP_KERNEL); 623 switch (bcm_clk->type) {
628 if (!bcm_clk) {
629 pr_err("%s: failed to allocate bcm_clk for %s\n", __func__,
630 name);
631 return NULL;
632 }
633 bcm_clk->ccu = ccu;
634 bcm_clk->init_data.name = name;
635
636 init_data = &bcm_clk->init_data;
637 init_data->name = name;
638 switch (type) {
639 case bcm_clk_peri: 624 case bcm_clk_peri:
640 if (peri_clk_setup(ccu, data, init_data)) 625 if (peri_clk_setup(bcm_clk->u.data, init_data))
641 goto out_free; 626 return NULL;
642 break; 627 break;
643 default: 628 default:
644 data = NULL; 629 pr_err("%s: clock type %d invalid for %s\n", __func__,
645 break; 630 (int)bcm_clk->type, init_data->name);
631 return NULL;
646 } 632 }
647 bcm_clk->type = type;
648 bcm_clk->u.data = data;
649 633
650 /* Make sure everything makes sense before we set it up */ 634 /* Make sure everything makes sense before we set it up */
651 if (!kona_clk_valid(bcm_clk)) { 635 if (!kona_clk_valid(bcm_clk)) {
652 pr_err("%s: clock data invalid for %s\n", __func__, name); 636 pr_err("%s: clock data invalid for %s\n", __func__,
637 init_data->name);
653 goto out_teardown; 638 goto out_teardown;
654 } 639 }
655 640
@@ -657,7 +642,7 @@ struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name,
657 clk = clk_register(NULL, &bcm_clk->hw); 642 clk = clk_register(NULL, &bcm_clk->hw);
658 if (IS_ERR(clk)) { 643 if (IS_ERR(clk)) {
659 pr_err("%s: error registering clock %s (%ld)\n", __func__, 644 pr_err("%s: error registering clock %s (%ld)\n", __func__,
660 name, PTR_ERR(clk)); 645 init_data->name, PTR_ERR(clk));
661 goto out_teardown; 646 goto out_teardown;
662 } 647 }
663 BUG_ON(!clk); 648 BUG_ON(!clk);
@@ -665,8 +650,6 @@ struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name,
665 return clk; 650 return clk;
666out_teardown: 651out_teardown:
667 bcm_clk_teardown(bcm_clk); 652 bcm_clk_teardown(bcm_clk);
668out_free:
669 kfree(bcm_clk);
670 653
671 return NULL; 654 return NULL;
672} 655}
@@ -701,11 +684,11 @@ static void kona_ccu_teardown(struct ccu_data *ccu)
701 * initialize the array of clocks provided by the CCU. 684 * initialize the array of clocks provided by the CCU.
702 */ 685 */
703void __init kona_dt_ccu_setup(struct ccu_data *ccu, 686void __init kona_dt_ccu_setup(struct ccu_data *ccu,
704 struct device_node *node, 687 struct device_node *node)
705 int (*ccu_clks_setup)(struct ccu_data *))
706{ 688{
707 struct resource res = { 0 }; 689 struct resource res = { 0 };
708 resource_size_t range; 690 resource_size_t range;
691 unsigned int i;
709 int ret; 692 int ret;
710 693
711 if (ccu->clk_data.clk_num) { 694 if (ccu->clk_data.clk_num) {
@@ -744,9 +727,16 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
744 ccu->node = of_node_get(node); 727 ccu->node = of_node_get(node);
745 list_add_tail(&ccu->links, &ccu_list); 728 list_add_tail(&ccu->links, &ccu_list);
746 729
747 /* Set up clocks array (in ccu->clk_data) */ 730 /*
748 if (ccu_clks_setup(ccu)) 731 * Set up each defined kona clock and save the result in
749 goto out_err; 732 * the clock framework clock array (in ccu->data). Then
733 * register as a provider for these clocks.
734 */
735 for (i = 0; i < ccu->clk_data.clk_num; i++) {
736 if (!ccu->kona_clks[i].ccu)
737 continue;
738 ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]);
739 }
750 740
751 ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); 741 ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data);
752 if (ret) { 742 if (ret) {