diff options
author | Stephen Boyd <stephen.boyd@linaro.org> | 2016-06-01 19:15:05 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2016-08-24 19:06:18 -0400 |
commit | f37fccce4cc19238f0742494a37d3efad346dfe7 (patch) | |
tree | 4f46f2cd3170937886459a0e8b4f1f021173a3d9 | |
parent | a38c94106e0dc77490ff820450c0c4af3b57fbc7 (diff) |
clk: bcm: kona: Migrate to clk_hw based registration and OF APIs
Now that we can use clk_hw pointers we don't need to have two
duplicate arrays holding the same mapping of clk index to clk_hw
pointer. Implement a custom clk_hw provider function to map the
OF specifier to the clk_hw instance for it.
Cc: Alex Elder <elder@linaro.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-rw-r--r-- | drivers/clk/bcm/clk-kona-setup.c | 76 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-kona.c | 9 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-kona.h | 7 |
3 files changed, 41 insertions, 51 deletions
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c index 526b0b0e9a9f..f2359b3b73bc 100644 --- a/drivers/clk/bcm/clk-kona-setup.c +++ b/drivers/clk/bcm/clk-kona-setup.c | |||
@@ -696,77 +696,69 @@ static void bcm_clk_teardown(struct kona_clk *bcm_clk) | |||
696 | bcm_clk->type = bcm_clk_none; | 696 | bcm_clk->type = bcm_clk_none; |
697 | } | 697 | } |
698 | 698 | ||
699 | static void kona_clk_teardown(struct clk *clk) | 699 | static void kona_clk_teardown(struct clk_hw *hw) |
700 | { | 700 | { |
701 | struct clk_hw *hw; | ||
702 | struct kona_clk *bcm_clk; | 701 | struct kona_clk *bcm_clk; |
703 | 702 | ||
704 | if (!clk) | 703 | if (!hw) |
705 | return; | 704 | return; |
706 | 705 | ||
707 | hw = __clk_get_hw(clk); | 706 | clk_hw_unregister(hw); |
708 | if (!hw) { | ||
709 | pr_err("%s: clk %p has null hw pointer\n", __func__, clk); | ||
710 | return; | ||
711 | } | ||
712 | clk_unregister(clk); | ||
713 | 707 | ||
714 | bcm_clk = to_kona_clk(hw); | 708 | bcm_clk = to_kona_clk(hw); |
715 | bcm_clk_teardown(bcm_clk); | 709 | bcm_clk_teardown(bcm_clk); |
716 | } | 710 | } |
717 | 711 | ||
718 | struct clk *kona_clk_setup(struct kona_clk *bcm_clk) | 712 | static int kona_clk_setup(struct kona_clk *bcm_clk) |
719 | { | 713 | { |
714 | int ret; | ||
720 | struct clk_init_data *init_data = &bcm_clk->init_data; | 715 | struct clk_init_data *init_data = &bcm_clk->init_data; |
721 | struct clk *clk = NULL; | ||
722 | 716 | ||
723 | switch (bcm_clk->type) { | 717 | switch (bcm_clk->type) { |
724 | case bcm_clk_peri: | 718 | case bcm_clk_peri: |
725 | if (peri_clk_setup(bcm_clk->u.data, init_data)) | 719 | ret = peri_clk_setup(bcm_clk->u.data, init_data); |
726 | return NULL; | 720 | if (ret) |
721 | return ret; | ||
727 | break; | 722 | break; |
728 | default: | 723 | default: |
729 | pr_err("%s: clock type %d invalid for %s\n", __func__, | 724 | pr_err("%s: clock type %d invalid for %s\n", __func__, |
730 | (int)bcm_clk->type, init_data->name); | 725 | (int)bcm_clk->type, init_data->name); |
731 | return NULL; | 726 | return -EINVAL; |
732 | } | 727 | } |
733 | 728 | ||
734 | /* Make sure everything makes sense before we set it up */ | 729 | /* Make sure everything makes sense before we set it up */ |
735 | if (!kona_clk_valid(bcm_clk)) { | 730 | if (!kona_clk_valid(bcm_clk)) { |
736 | pr_err("%s: clock data invalid for %s\n", __func__, | 731 | pr_err("%s: clock data invalid for %s\n", __func__, |
737 | init_data->name); | 732 | init_data->name); |
733 | ret = -EINVAL; | ||
738 | goto out_teardown; | 734 | goto out_teardown; |
739 | } | 735 | } |
740 | 736 | ||
741 | bcm_clk->hw.init = init_data; | 737 | bcm_clk->hw.init = init_data; |
742 | clk = clk_register(NULL, &bcm_clk->hw); | 738 | ret = clk_hw_register(NULL, &bcm_clk->hw); |
743 | if (IS_ERR(clk)) { | 739 | if (ret) { |
744 | pr_err("%s: error registering clock %s (%ld)\n", __func__, | 740 | pr_err("%s: error registering clock %s (%d)\n", __func__, |
745 | init_data->name, PTR_ERR(clk)); | 741 | init_data->name, ret); |
746 | goto out_teardown; | 742 | goto out_teardown; |
747 | } | 743 | } |
748 | BUG_ON(!clk); | ||
749 | 744 | ||
750 | return clk; | 745 | return 0; |
751 | out_teardown: | 746 | out_teardown: |
752 | bcm_clk_teardown(bcm_clk); | 747 | bcm_clk_teardown(bcm_clk); |
753 | 748 | ||
754 | return NULL; | 749 | return ret; |
755 | } | 750 | } |
756 | 751 | ||
757 | static void ccu_clks_teardown(struct ccu_data *ccu) | 752 | static void ccu_clks_teardown(struct ccu_data *ccu) |
758 | { | 753 | { |
759 | u32 i; | 754 | u32 i; |
760 | 755 | ||
761 | for (i = 0; i < ccu->clk_data.clk_num; i++) | 756 | for (i = 0; i < ccu->clk_num; i++) |
762 | kona_clk_teardown(ccu->clk_data.clks[i]); | 757 | kona_clk_teardown(&ccu->kona_clks[i].hw); |
763 | kfree(ccu->clk_data.clks); | ||
764 | } | 758 | } |
765 | 759 | ||
766 | static void kona_ccu_teardown(struct ccu_data *ccu) | 760 | static void kona_ccu_teardown(struct ccu_data *ccu) |
767 | { | 761 | { |
768 | kfree(ccu->clk_data.clks); | ||
769 | ccu->clk_data.clks = NULL; | ||
770 | if (!ccu->base) | 762 | if (!ccu->base) |
771 | return; | 763 | return; |
772 | 764 | ||
@@ -793,6 +785,20 @@ static bool ccu_data_valid(struct ccu_data *ccu) | |||
793 | return true; | 785 | return true; |
794 | } | 786 | } |
795 | 787 | ||
788 | static struct clk_hw * | ||
789 | of_clk_kona_onecell_get(struct of_phandle_args *clkspec, void *data) | ||
790 | { | ||
791 | struct ccu_data *ccu = data; | ||
792 | unsigned int idx = clkspec->args[0]; | ||
793 | |||
794 | if (idx >= ccu->clk_num) { | ||
795 | pr_err("%s: invalid index %u\n", __func__, idx); | ||
796 | return ERR_PTR(-EINVAL); | ||
797 | } | ||
798 | |||
799 | return &ccu->kona_clks[idx].hw; | ||
800 | } | ||
801 | |||
796 | /* | 802 | /* |
797 | * Set up a CCU. Call the provided ccu_clks_setup callback to | 803 | * Set up a CCU. Call the provided ccu_clks_setup callback to |
798 | * initialize the array of clocks provided by the CCU. | 804 | * initialize the array of clocks provided by the CCU. |
@@ -805,18 +811,6 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu, | |||
805 | unsigned int i; | 811 | unsigned int i; |
806 | int ret; | 812 | int ret; |
807 | 813 | ||
808 | if (ccu->clk_data.clk_num) { | ||
809 | size_t size; | ||
810 | |||
811 | size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks); | ||
812 | ccu->clk_data.clks = kzalloc(size, GFP_KERNEL); | ||
813 | if (!ccu->clk_data.clks) { | ||
814 | pr_err("%s: unable to allocate %u clocks for %s\n", | ||
815 | __func__, ccu->clk_data.clk_num, node->name); | ||
816 | return; | ||
817 | } | ||
818 | } | ||
819 | |||
820 | ret = of_address_to_resource(node, 0, &res); | 814 | ret = of_address_to_resource(node, 0, &res); |
821 | if (ret) { | 815 | if (ret) { |
822 | pr_err("%s: no valid CCU registers found for %s\n", __func__, | 816 | pr_err("%s: no valid CCU registers found for %s\n", __func__, |
@@ -851,13 +845,13 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu, | |||
851 | * the clock framework clock array (in ccu->data). Then | 845 | * the clock framework clock array (in ccu->data). Then |
852 | * register as a provider for these clocks. | 846 | * register as a provider for these clocks. |
853 | */ | 847 | */ |
854 | for (i = 0; i < ccu->clk_data.clk_num; i++) { | 848 | for (i = 0; i < ccu->clk_num; i++) { |
855 | if (!ccu->kona_clks[i].ccu) | 849 | if (!ccu->kona_clks[i].ccu) |
856 | continue; | 850 | continue; |
857 | ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]); | 851 | kona_clk_setup(&ccu->kona_clks[i]); |
858 | } | 852 | } |
859 | 853 | ||
860 | ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); | 854 | ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu); |
861 | if (ret) { | 855 | if (ret) { |
862 | pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, | 856 | pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, |
863 | node->name, ret); | 857 | node->name, ret); |
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c index 3a15347b4233..eee64b9e5d10 100644 --- a/drivers/clk/bcm/clk-kona.c +++ b/drivers/clk/bcm/clk-kona.c | |||
@@ -1256,19 +1256,18 @@ bool __init kona_ccu_init(struct ccu_data *ccu) | |||
1256 | { | 1256 | { |
1257 | unsigned long flags; | 1257 | unsigned long flags; |
1258 | unsigned int which; | 1258 | unsigned int which; |
1259 | struct clk **clks = ccu->clk_data.clks; | ||
1260 | struct kona_clk *kona_clks = ccu->kona_clks; | 1259 | struct kona_clk *kona_clks = ccu->kona_clks; |
1261 | bool success = true; | 1260 | bool success = true; |
1262 | 1261 | ||
1263 | flags = ccu_lock(ccu); | 1262 | flags = ccu_lock(ccu); |
1264 | __ccu_write_enable(ccu); | 1263 | __ccu_write_enable(ccu); |
1265 | 1264 | ||
1266 | for (which = 0; which < ccu->clk_data.clk_num; which++) { | 1265 | for (which = 0; which < ccu->clk_num; which++) { |
1267 | struct kona_clk *bcm_clk; | 1266 | struct kona_clk *bcm_clk = &kona_clks[which]; |
1268 | 1267 | ||
1269 | if (!clks[which]) | 1268 | if (!bcm_clk->ccu) |
1270 | continue; | 1269 | continue; |
1271 | bcm_clk = &kona_clks[which]; | 1270 | |
1272 | success &= __kona_clk_init(bcm_clk); | 1271 | success &= __kona_clk_init(bcm_clk); |
1273 | } | 1272 | } |
1274 | 1273 | ||
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h index 906576ec97b6..f4b39bb5558a 100644 --- a/drivers/clk/bcm/clk-kona.h +++ b/drivers/clk/bcm/clk-kona.h | |||
@@ -481,7 +481,7 @@ struct ccu_data { | |||
481 | bool write_enabled; /* write access is currently enabled */ | 481 | bool write_enabled; /* write access is currently enabled */ |
482 | struct ccu_policy policy; | 482 | struct ccu_policy policy; |
483 | struct device_node *node; | 483 | struct device_node *node; |
484 | struct clk_onecell_data clk_data; | 484 | size_t clk_num; |
485 | const char *name; | 485 | const char *name; |
486 | u32 range; /* byte range of address space */ | 486 | u32 range; /* byte range of address space */ |
487 | struct kona_clk kona_clks[]; /* must be last */ | 487 | struct kona_clk kona_clks[]; /* must be last */ |
@@ -491,9 +491,7 @@ struct ccu_data { | |||
491 | #define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ | 491 | #define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ |
492 | .name = #_name "_ccu", \ | 492 | .name = #_name "_ccu", \ |
493 | .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ | 493 | .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ |
494 | .clk_data = { \ | 494 | .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT |
495 | .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \ | ||
496 | } | ||
497 | 495 | ||
498 | /* Exported globals */ | 496 | /* Exported globals */ |
499 | 497 | ||
@@ -505,7 +503,6 @@ extern u64 scaled_div_max(struct bcm_clk_div *div); | |||
505 | extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, | 503 | extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, |
506 | u32 billionths); | 504 | u32 billionths); |
507 | 505 | ||
508 | extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk); | ||
509 | extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, | 506 | extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, |
510 | struct device_node *node); | 507 | struct device_node *node); |
511 | extern bool __init kona_ccu_init(struct ccu_data *ccu); | 508 | extern bool __init kona_ccu_init(struct ccu_data *ccu); |