Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Stephen Boyd and committed by
Stephen Boyd
f37fccce a38c9410

+41 -51
+35 -41
drivers/clk/bcm/clk-kona-setup.c
··· 696 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 701 struct kona_clk *bcm_clk; 703 702 704 - if (!clk) 703 + if (!hw) 705 704 return; 706 705 707 - hw = __clk_get_hw(clk); 708 - if (!hw) { 709 - pr_err("%s: clk %p has null hw pointer\n", __func__, clk); 710 - return; 711 - } 712 - clk_unregister(clk); 706 + clk_hw_unregister(hw); 713 707 714 708 bcm_clk = to_kona_clk(hw); 715 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 715 struct clk_init_data *init_data = &bcm_clk->init_data; 721 - struct clk *clk = NULL; 722 716 723 717 switch (bcm_clk->type) { 724 718 case bcm_clk_peri: 725 - if (peri_clk_setup(bcm_clk->u.data, init_data)) 726 - return NULL; 719 + ret = peri_clk_setup(bcm_clk->u.data, init_data); 720 + if (ret) 721 + return ret; 727 722 break; 728 723 default: 729 724 pr_err("%s: clock type %d invalid for %s\n", __func__, 730 725 (int)bcm_clk->type, init_data->name); 731 - return NULL; 726 + return -EINVAL; 732 727 } 733 728 734 729 /* Make sure everything makes sense before we set it up */ 735 730 if (!kona_clk_valid(bcm_clk)) { 736 731 pr_err("%s: clock data invalid for %s\n", __func__, 737 732 init_data->name); 733 + ret = -EINVAL; 738 734 goto out_teardown; 739 735 } 740 736 741 737 bcm_clk->hw.init = init_data; 742 - clk = clk_register(NULL, &bcm_clk->hw); 743 - if (IS_ERR(clk)) { 744 - pr_err("%s: error registering clock %s (%ld)\n", __func__, 745 - init_data->name, PTR_ERR(clk)); 738 + ret = clk_hw_register(NULL, &bcm_clk->hw); 739 + if (ret) { 740 + pr_err("%s: error registering clock %s (%d)\n", __func__, 741 + init_data->name, ret); 746 742 goto out_teardown; 747 743 } 748 - BUG_ON(!clk); 749 744 750 - return clk; 745 + return 0; 751 746 out_teardown: 752 747 bcm_clk_teardown(bcm_clk); 753 748 754 - return NULL; 749 + return ret; 755 750 } 756 751 757 752 static void ccu_clks_teardown(struct ccu_data *ccu) 758 753 { 759 754 u32 i; 760 755 761 - for (i = 0; i < ccu->clk_data.clk_num; i++) 762 - kona_clk_teardown(ccu->clk_data.clks[i]); 763 - kfree(ccu->clk_data.clks); 756 + for (i = 0; i < ccu->clk_num; i++) 757 + kona_clk_teardown(&ccu->kona_clks[i].hw); 764 758 } 765 759 766 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 762 if (!ccu->base) 771 763 return; 772 764 ··· 785 793 return true; 786 794 } 787 795 796 + static struct clk_hw * 797 + of_clk_kona_onecell_get(struct of_phandle_args *clkspec, void *data) 798 + { 799 + struct ccu_data *ccu = data; 800 + unsigned int idx = clkspec->args[0]; 801 + 802 + if (idx >= ccu->clk_num) { 803 + pr_err("%s: invalid index %u\n", __func__, idx); 804 + return ERR_PTR(-EINVAL); 805 + } 806 + 807 + return &ccu->kona_clks[idx].hw; 808 + } 809 + 788 810 /* 789 811 * Set up a CCU. Call the provided ccu_clks_setup callback to 790 812 * initialize the array of clocks provided by the CCU. ··· 810 804 resource_size_t range; 811 805 unsigned int i; 812 806 int ret; 813 - 814 - if (ccu->clk_data.clk_num) { 815 - size_t size; 816 - 817 - size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks); 818 - ccu->clk_data.clks = kzalloc(size, GFP_KERNEL); 819 - if (!ccu->clk_data.clks) { 820 - pr_err("%s: unable to allocate %u clocks for %s\n", 821 - __func__, ccu->clk_data.clk_num, node->name); 822 - return; 823 - } 824 - } 825 807 826 808 ret = of_address_to_resource(node, 0, &res); 827 809 if (ret) { ··· 845 851 * the clock framework clock array (in ccu->data). Then 846 852 * register as a provider for these clocks. 847 853 */ 848 - for (i = 0; i < ccu->clk_data.clk_num; i++) { 854 + for (i = 0; i < ccu->clk_num; i++) { 849 855 if (!ccu->kona_clks[i].ccu) 850 856 continue; 851 - ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]); 857 + kona_clk_setup(&ccu->kona_clks[i]); 852 858 } 853 859 854 - ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); 860 + ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu); 855 861 if (ret) { 856 862 pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, 857 863 node->name, ret);
+4 -5
drivers/clk/bcm/clk-kona.c
··· 1256 1256 { 1257 1257 unsigned long flags; 1258 1258 unsigned int which; 1259 - struct clk **clks = ccu->clk_data.clks; 1260 1259 struct kona_clk *kona_clks = ccu->kona_clks; 1261 1260 bool success = true; 1262 1261 1263 1262 flags = ccu_lock(ccu); 1264 1263 __ccu_write_enable(ccu); 1265 1264 1266 - for (which = 0; which < ccu->clk_data.clk_num; which++) { 1267 - struct kona_clk *bcm_clk; 1265 + for (which = 0; which < ccu->clk_num; which++) { 1266 + struct kona_clk *bcm_clk = &kona_clks[which]; 1268 1267 1269 - if (!clks[which]) 1268 + if (!bcm_clk->ccu) 1270 1269 continue; 1271 - bcm_clk = &kona_clks[which]; 1270 + 1272 1271 success &= __kona_clk_init(bcm_clk); 1273 1272 } 1274 1273
+2 -5
drivers/clk/bcm/clk-kona.h
··· 481 481 bool write_enabled; /* write access is currently enabled */ 482 482 struct ccu_policy policy; 483 483 struct device_node *node; 484 - struct clk_onecell_data clk_data; 484 + size_t clk_num; 485 485 const char *name; 486 486 u32 range; /* byte range of address space */ 487 487 struct kona_clk kona_clks[]; /* must be last */ ··· 491 491 #define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ 492 492 .name = #_name "_ccu", \ 493 493 .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ 494 - .clk_data = { \ 495 - .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \ 496 - } 494 + .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT 497 495 498 496 /* Exported globals */ 499 497 ··· 503 505 extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, 504 506 u32 billionths); 505 507 506 - extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk); 507 508 extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, 508 509 struct device_node *node); 509 510 extern bool __init kona_ccu_init(struct ccu_data *ccu);