aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXing Zheng <zhengxing@rock-chips.com>2016-03-08 21:37:04 -0500
committerHeiko Stuebner <heiko@sntech.de>2016-03-27 07:03:34 -0400
commitef1d9feeccc094f59b72bb11fe14ec886eb574d3 (patch)
treeaa1b6e1c3588d53459f206e92e4ad2fb4629f28c
parent268aebaa2410152bf91ea1ede6b284ff8138822d (diff)
clk: rockchip: Add support for multiple clock providers
There are need to support Multi-CRUs probability in future, but it is not supported on the current Rockchip Clock Framework. Therefore, this patch add support a provider as the parameter handler when we call the clock register functions for per CRU. Signed-off-by: Xing Zheng <zhengxing@rock-chips.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
-rw-r--r--drivers/clk/rockchip/clk-pll.c30
-rw-r--r--drivers/clk/rockchip/clk-rk3036.c17
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c44
-rw-r--r--drivers/clk/rockchip/clk-rk3228.c17
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c19
-rw-r--r--drivers/clk/rockchip/clk-rk3368.c21
-rw-r--r--drivers/clk/rockchip/clk.c148
-rw-r--r--drivers/clk/rockchip/clk.h51
8 files changed, 229 insertions, 118 deletions
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 5de797e34d54..27be66a2a358 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -46,6 +46,8 @@ struct rockchip_clk_pll {
46 const struct rockchip_pll_rate_table *rate_table; 46 const struct rockchip_pll_rate_table *rate_table;
47 unsigned int rate_count; 47 unsigned int rate_count;
48 spinlock_t *lock; 48 spinlock_t *lock;
49
50 struct rockchip_clk_provider *ctx;
49}; 51};
50 52
51#define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw) 53#define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
@@ -90,7 +92,7 @@ static long rockchip_pll_round_rate(struct clk_hw *hw,
90 */ 92 */
91static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) 93static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
92{ 94{
93 struct regmap *grf = rockchip_clk_get_grf(); 95 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
94 unsigned int val; 96 unsigned int val;
95 int delay = 24000000, ret; 97 int delay = 24000000, ret;
96 98
@@ -251,7 +253,7 @@ static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
251 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 253 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
252 const struct rockchip_pll_rate_table *rate; 254 const struct rockchip_pll_rate_table *rate;
253 unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate); 255 unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate);
254 struct regmap *grf = rockchip_clk_get_grf(); 256 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
255 257
256 if (IS_ERR(grf)) { 258 if (IS_ERR(grf)) {
257 pr_debug("%s: grf regmap not available, aborting rate change\n", 259 pr_debug("%s: grf regmap not available, aborting rate change\n",
@@ -490,7 +492,7 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
490 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 492 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
491 const struct rockchip_pll_rate_table *rate; 493 const struct rockchip_pll_rate_table *rate;
492 unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate); 494 unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
493 struct regmap *grf = rockchip_clk_get_grf(); 495 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
494 496
495 if (IS_ERR(grf)) { 497 if (IS_ERR(grf)) {
496 pr_debug("%s: grf regmap not available, aborting rate change\n", 498 pr_debug("%s: grf regmap not available, aborting rate change\n",
@@ -563,7 +565,7 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
563 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb); 565 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
564 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf 566 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
565 || rate->nb != cur.nb) { 567 || rate->nb != cur.nb) {
566 struct regmap *grf = rockchip_clk_get_grf(); 568 struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
567 569
568 if (IS_ERR(grf)) 570 if (IS_ERR(grf))
569 return; 571 return;
@@ -595,12 +597,13 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
595 * Common registering of pll clocks 597 * Common registering of pll clocks
596 */ 598 */
597 599
598struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 600struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
601 enum rockchip_pll_type pll_type,
599 const char *name, const char *const *parent_names, 602 const char *name, const char *const *parent_names,
600 u8 num_parents, void __iomem *base, int con_offset, 603 u8 num_parents, int con_offset, int grf_lock_offset,
601 int grf_lock_offset, int lock_shift, int mode_offset, 604 int lock_shift, int mode_offset, int mode_shift,
602 int mode_shift, struct rockchip_pll_rate_table *rate_table, 605 struct rockchip_pll_rate_table *rate_table,
603 u8 clk_pll_flags, spinlock_t *lock) 606 u8 clk_pll_flags)
604{ 607{
605 const char *pll_parents[3]; 608 const char *pll_parents[3];
606 struct clk_init_data init; 609 struct clk_init_data init;
@@ -624,11 +627,11 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
624 /* create the mux on top of the real pll */ 627 /* create the mux on top of the real pll */
625 pll->pll_mux_ops = &clk_mux_ops; 628 pll->pll_mux_ops = &clk_mux_ops;
626 pll_mux = &pll->pll_mux; 629 pll_mux = &pll->pll_mux;
627 pll_mux->reg = base + mode_offset; 630 pll_mux->reg = ctx->reg_base + mode_offset;
628 pll_mux->shift = mode_shift; 631 pll_mux->shift = mode_shift;
629 pll_mux->mask = PLL_MODE_MASK; 632 pll_mux->mask = PLL_MODE_MASK;
630 pll_mux->flags = 0; 633 pll_mux->flags = 0;
631 pll_mux->lock = lock; 634 pll_mux->lock = &ctx->lock;
632 pll_mux->hw.init = &init; 635 pll_mux->hw.init = &init;
633 636
634 if (pll_type == pll_rk3036 || pll_type == pll_rk3066) 637 if (pll_type == pll_rk3036 || pll_type == pll_rk3066)
@@ -695,11 +698,12 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
695 698
696 pll->hw.init = &init; 699 pll->hw.init = &init;
697 pll->type = pll_type; 700 pll->type = pll_type;
698 pll->reg_base = base + con_offset; 701 pll->reg_base = ctx->reg_base + con_offset;
699 pll->lock_offset = grf_lock_offset; 702 pll->lock_offset = grf_lock_offset;
700 pll->lock_shift = lock_shift; 703 pll->lock_shift = lock_shift;
701 pll->flags = clk_pll_flags; 704 pll->flags = clk_pll_flags;
702 pll->lock = lock; 705 pll->lock = &ctx->lock;
706 pll->ctx = ctx;
703 707
704 pll_clk = clk_register(NULL, &pll->hw); 708 pll_clk = clk_register(NULL, &pll->hw);
705 if (IS_ERR(pll_clk)) { 709 if (IS_ERR(pll_clk)) {
diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c
index f9cbba0eac36..c7c8260e1c66 100644
--- a/drivers/clk/rockchip/clk-rk3036.c
+++ b/drivers/clk/rockchip/clk-rk3036.c
@@ -440,6 +440,7 @@ static const char *const rk3036_critical_clocks[] __initconst = {
440 440
441static void __init rk3036_clk_init(struct device_node *np) 441static void __init rk3036_clk_init(struct device_node *np)
442{ 442{
443 struct rockchip_clk_provider *ctx;
443 void __iomem *reg_base; 444 void __iomem *reg_base;
444 struct clk *clk; 445 struct clk *clk;
445 446
@@ -449,22 +450,26 @@ static void __init rk3036_clk_init(struct device_node *np)
449 return; 450 return;
450 } 451 }
451 452
452 rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 453 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
454 if (IS_ERR(ctx)) {
455 pr_err("%s: rockchip clk init failed\n", __func__);
456 return;
457 }
453 458
454 clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); 459 clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
455 if (IS_ERR(clk)) 460 if (IS_ERR(clk))
456 pr_warn("%s: could not register clock usb480m: %ld\n", 461 pr_warn("%s: could not register clock usb480m: %ld\n",
457 __func__, PTR_ERR(clk)); 462 __func__, PTR_ERR(clk));
458 463
459 rockchip_clk_register_plls(rk3036_pll_clks, 464 rockchip_clk_register_plls(ctx, rk3036_pll_clks,
460 ARRAY_SIZE(rk3036_pll_clks), 465 ARRAY_SIZE(rk3036_pll_clks),
461 RK3036_GRF_SOC_STATUS0); 466 RK3036_GRF_SOC_STATUS0);
462 rockchip_clk_register_branches(rk3036_clk_branches, 467 rockchip_clk_register_branches(ctx, rk3036_clk_branches,
463 ARRAY_SIZE(rk3036_clk_branches)); 468 ARRAY_SIZE(rk3036_clk_branches));
464 rockchip_clk_protect_critical(rk3036_critical_clocks, 469 rockchip_clk_protect_critical(rk3036_critical_clocks,
465 ARRAY_SIZE(rk3036_critical_clocks)); 470 ARRAY_SIZE(rk3036_critical_clocks));
466 471
467 rockchip_clk_register_armclk(ARMCLK, "armclk", 472 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
468 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 473 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
469 &rk3036_cpuclk_data, rk3036_cpuclk_rates, 474 &rk3036_cpuclk_data, rk3036_cpuclk_rates,
470 ARRAY_SIZE(rk3036_cpuclk_rates)); 475 ARRAY_SIZE(rk3036_cpuclk_rates));
@@ -472,6 +477,8 @@ static void __init rk3036_clk_init(struct device_node *np)
472 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 477 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
473 ROCKCHIP_SOFTRST_HIWORD_MASK); 478 ROCKCHIP_SOFTRST_HIWORD_MASK);
474 479
475 rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL); 480 rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
481
482 rockchip_clk_of_add_provider(np, ctx);
476} 483}
477CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init); 484CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index e832403a0f9f..0fcce2295b37 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -759,57 +759,74 @@ static const char *const rk3188_critical_clocks[] __initconst = {
759 "hclk_cpubus" 759 "hclk_cpubus"
760}; 760};
761 761
762static void __init rk3188_common_clk_init(struct device_node *np) 762static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np)
763{ 763{
764 struct rockchip_clk_provider *ctx;
764 void __iomem *reg_base; 765 void __iomem *reg_base;
765 766
766 reg_base = of_iomap(np, 0); 767 reg_base = of_iomap(np, 0);
767 if (!reg_base) { 768 if (!reg_base) {
768 pr_err("%s: could not map cru region\n", __func__); 769 pr_err("%s: could not map cru region\n", __func__);
769 return; 770 return ERR_PTR(-ENOMEM);
770 } 771 }
771 772
772 rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 773 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
774 if (IS_ERR(ctx)) {
775 pr_err("%s: rockchip clk init failed\n", __func__);
776 return ERR_PTR(-ENOMEM);
777 }
773 778
774 rockchip_clk_register_branches(common_clk_branches, 779 rockchip_clk_register_branches(ctx, common_clk_branches,
775 ARRAY_SIZE(common_clk_branches)); 780 ARRAY_SIZE(common_clk_branches));
776 781
777 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 782 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
778 ROCKCHIP_SOFTRST_HIWORD_MASK); 783 ROCKCHIP_SOFTRST_HIWORD_MASK);
779 784
780 rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL); 785 rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
786
787 return ctx;
781} 788}
782 789
783static void __init rk3066a_clk_init(struct device_node *np) 790static void __init rk3066a_clk_init(struct device_node *np)
784{ 791{
785 rk3188_common_clk_init(np); 792 struct rockchip_clk_provider *ctx;
786 rockchip_clk_register_plls(rk3066_pll_clks, 793
794 ctx = rk3188_common_clk_init(np);
795 if (IS_ERR(ctx))
796 return;
797
798 rockchip_clk_register_plls(ctx, rk3066_pll_clks,
787 ARRAY_SIZE(rk3066_pll_clks), 799 ARRAY_SIZE(rk3066_pll_clks),
788 RK3066_GRF_SOC_STATUS); 800 RK3066_GRF_SOC_STATUS);
789 rockchip_clk_register_branches(rk3066a_clk_branches, 801 rockchip_clk_register_branches(ctx, rk3066a_clk_branches,
790 ARRAY_SIZE(rk3066a_clk_branches)); 802 ARRAY_SIZE(rk3066a_clk_branches));
791 rockchip_clk_register_armclk(ARMCLK, "armclk", 803 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
792 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 804 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
793 &rk3066_cpuclk_data, rk3066_cpuclk_rates, 805 &rk3066_cpuclk_data, rk3066_cpuclk_rates,
794 ARRAY_SIZE(rk3066_cpuclk_rates)); 806 ARRAY_SIZE(rk3066_cpuclk_rates));
795 rockchip_clk_protect_critical(rk3188_critical_clocks, 807 rockchip_clk_protect_critical(rk3188_critical_clocks,
796 ARRAY_SIZE(rk3188_critical_clocks)); 808 ARRAY_SIZE(rk3188_critical_clocks));
809 rockchip_clk_of_add_provider(np, ctx);
797} 810}
798CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init); 811CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
799 812
800static void __init rk3188a_clk_init(struct device_node *np) 813static void __init rk3188a_clk_init(struct device_node *np)
801{ 814{
815 struct rockchip_clk_provider *ctx;
802 struct clk *clk1, *clk2; 816 struct clk *clk1, *clk2;
803 unsigned long rate; 817 unsigned long rate;
804 int ret; 818 int ret;
805 819
806 rk3188_common_clk_init(np); 820 ctx = rk3188_common_clk_init(np);
807 rockchip_clk_register_plls(rk3188_pll_clks, 821 if (IS_ERR(ctx))
822 return;
823
824 rockchip_clk_register_plls(ctx, rk3188_pll_clks,
808 ARRAY_SIZE(rk3188_pll_clks), 825 ARRAY_SIZE(rk3188_pll_clks),
809 RK3188_GRF_SOC_STATUS); 826 RK3188_GRF_SOC_STATUS);
810 rockchip_clk_register_branches(rk3188_clk_branches, 827 rockchip_clk_register_branches(ctx, rk3188_clk_branches,
811 ARRAY_SIZE(rk3188_clk_branches)); 828 ARRAY_SIZE(rk3188_clk_branches));
812 rockchip_clk_register_armclk(ARMCLK, "armclk", 829 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
813 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 830 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
814 &rk3188_cpuclk_data, rk3188_cpuclk_rates, 831 &rk3188_cpuclk_data, rk3188_cpuclk_rates,
815 ARRAY_SIZE(rk3188_cpuclk_rates)); 832 ARRAY_SIZE(rk3188_cpuclk_rates));
@@ -833,6 +850,7 @@ static void __init rk3188a_clk_init(struct device_node *np)
833 850
834 rockchip_clk_protect_critical(rk3188_critical_clocks, 851 rockchip_clk_protect_critical(rk3188_critical_clocks,
835 ARRAY_SIZE(rk3188_critical_clocks)); 852 ARRAY_SIZE(rk3188_critical_clocks));
853 rockchip_clk_of_add_provider(np, ctx);
836} 854}
837CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init); 855CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
838 856
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index 4b4137e85125..c112b2f95224 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -628,6 +628,7 @@ static const char *const rk3228_critical_clocks[] __initconst = {
628 628
629static void __init rk3228_clk_init(struct device_node *np) 629static void __init rk3228_clk_init(struct device_node *np)
630{ 630{
631 struct rockchip_clk_provider *ctx;
631 void __iomem *reg_base; 632 void __iomem *reg_base;
632 633
633 reg_base = of_iomap(np, 0); 634 reg_base = of_iomap(np, 0);
@@ -636,17 +637,21 @@ static void __init rk3228_clk_init(struct device_node *np)
636 return; 637 return;
637 } 638 }
638 639
639 rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 640 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
641 if (IS_ERR(ctx)) {
642 pr_err("%s: rockchip clk init failed\n", __func__);
643 return;
644 }
640 645
641 rockchip_clk_register_plls(rk3228_pll_clks, 646 rockchip_clk_register_plls(ctx, rk3228_pll_clks,
642 ARRAY_SIZE(rk3228_pll_clks), 647 ARRAY_SIZE(rk3228_pll_clks),
643 RK3228_GRF_SOC_STATUS0); 648 RK3228_GRF_SOC_STATUS0);
644 rockchip_clk_register_branches(rk3228_clk_branches, 649 rockchip_clk_register_branches(ctx, rk3228_clk_branches,
645 ARRAY_SIZE(rk3228_clk_branches)); 650 ARRAY_SIZE(rk3228_clk_branches));
646 rockchip_clk_protect_critical(rk3228_critical_clocks, 651 rockchip_clk_protect_critical(rk3228_critical_clocks,
647 ARRAY_SIZE(rk3228_critical_clocks)); 652 ARRAY_SIZE(rk3228_critical_clocks));
648 653
649 rockchip_clk_register_armclk(ARMCLK, "armclk", 654 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
650 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 655 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
651 &rk3228_cpuclk_data, rk3228_cpuclk_rates, 656 &rk3228_cpuclk_data, rk3228_cpuclk_rates,
652 ARRAY_SIZE(rk3228_cpuclk_rates)); 657 ARRAY_SIZE(rk3228_cpuclk_rates));
@@ -654,6 +659,8 @@ static void __init rk3228_clk_init(struct device_node *np)
654 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 659 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
655 ROCKCHIP_SOFTRST_HIWORD_MASK); 660 ROCKCHIP_SOFTRST_HIWORD_MASK);
656 661
657 rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL); 662 rockchip_register_restart_notifier(ctx, RK3228_GLB_SRST_FST, NULL);
663
664 rockchip_clk_of_add_provider(np, ctx);
658} 665}
659CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init); 666CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 00faf3f9b179..d1031d1149ce 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -881,6 +881,7 @@ static struct syscore_ops rk3288_clk_syscore_ops = {
881 881
882static void __init rk3288_clk_init(struct device_node *np) 882static void __init rk3288_clk_init(struct device_node *np)
883{ 883{
884 struct rockchip_clk_provider *ctx;
884 struct clk *clk; 885 struct clk *clk;
885 886
886 rk3288_cru_base = of_iomap(np, 0); 887 rk3288_cru_base = of_iomap(np, 0);
@@ -889,7 +890,11 @@ static void __init rk3288_clk_init(struct device_node *np)
889 return; 890 return;
890 } 891 }
891 892
892 rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); 893 ctx = rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS);
894 if (IS_ERR(ctx)) {
895 pr_err("%s: rockchip clk init failed\n", __func__);
896 return;
897 }
893 898
894 /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ 899 /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
895 clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); 900 clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1);
@@ -897,17 +902,17 @@ static void __init rk3288_clk_init(struct device_node *np)
897 pr_warn("%s: could not register clock pclk_wdt: %ld\n", 902 pr_warn("%s: could not register clock pclk_wdt: %ld\n",
898 __func__, PTR_ERR(clk)); 903 __func__, PTR_ERR(clk));
899 else 904 else
900 rockchip_clk_add_lookup(clk, PCLK_WDT); 905 rockchip_clk_add_lookup(ctx, clk, PCLK_WDT);
901 906
902 rockchip_clk_register_plls(rk3288_pll_clks, 907 rockchip_clk_register_plls(ctx, rk3288_pll_clks,
903 ARRAY_SIZE(rk3288_pll_clks), 908 ARRAY_SIZE(rk3288_pll_clks),
904 RK3288_GRF_SOC_STATUS1); 909 RK3288_GRF_SOC_STATUS1);
905 rockchip_clk_register_branches(rk3288_clk_branches, 910 rockchip_clk_register_branches(ctx, rk3288_clk_branches,
906 ARRAY_SIZE(rk3288_clk_branches)); 911 ARRAY_SIZE(rk3288_clk_branches));
907 rockchip_clk_protect_critical(rk3288_critical_clocks, 912 rockchip_clk_protect_critical(rk3288_critical_clocks,
908 ARRAY_SIZE(rk3288_critical_clocks)); 913 ARRAY_SIZE(rk3288_critical_clocks));
909 914
910 rockchip_clk_register_armclk(ARMCLK, "armclk", 915 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
911 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 916 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
912 &rk3288_cpuclk_data, rk3288_cpuclk_rates, 917 &rk3288_cpuclk_data, rk3288_cpuclk_rates,
913 ARRAY_SIZE(rk3288_cpuclk_rates)); 918 ARRAY_SIZE(rk3288_cpuclk_rates));
@@ -916,8 +921,10 @@ static void __init rk3288_clk_init(struct device_node *np)
916 rk3288_cru_base + RK3288_SOFTRST_CON(0), 921 rk3288_cru_base + RK3288_SOFTRST_CON(0),
917 ROCKCHIP_SOFTRST_HIWORD_MASK); 922 ROCKCHIP_SOFTRST_HIWORD_MASK);
918 923
919 rockchip_register_restart_notifier(RK3288_GLB_SRST_FST, 924 rockchip_register_restart_notifier(ctx, RK3288_GLB_SRST_FST,
920 rk3288_clk_shutdown); 925 rk3288_clk_shutdown);
921 register_syscore_ops(&rk3288_clk_syscore_ops); 926 register_syscore_ops(&rk3288_clk_syscore_ops);
927
928 rockchip_clk_of_add_provider(np, ctx);
922} 929}
923CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); 930CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c
index c26ff4a36dcd..3121414cfd63 100644
--- a/drivers/clk/rockchip/clk-rk3368.c
+++ b/drivers/clk/rockchip/clk-rk3368.c
@@ -862,6 +862,7 @@ static const char *const rk3368_critical_clocks[] __initconst = {
862 862
863static void __init rk3368_clk_init(struct device_node *np) 863static void __init rk3368_clk_init(struct device_node *np)
864{ 864{
865 struct rockchip_clk_provider *ctx;
865 void __iomem *reg_base; 866 void __iomem *reg_base;
866 struct clk *clk; 867 struct clk *clk;
867 868
@@ -871,7 +872,11 @@ static void __init rk3368_clk_init(struct device_node *np)
871 return; 872 return;
872 } 873 }
873 874
874 rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 875 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
876 if (IS_ERR(ctx)) {
877 pr_err("%s: rockchip clk init failed\n", __func__);
878 return;
879 }
875 880
876 /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ 881 /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */
877 clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); 882 clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1);
@@ -879,22 +884,22 @@ static void __init rk3368_clk_init(struct device_node *np)
879 pr_warn("%s: could not register clock pclk_wdt: %ld\n", 884 pr_warn("%s: could not register clock pclk_wdt: %ld\n",
880 __func__, PTR_ERR(clk)); 885 __func__, PTR_ERR(clk));
881 else 886 else
882 rockchip_clk_add_lookup(clk, PCLK_WDT); 887 rockchip_clk_add_lookup(ctx, clk, PCLK_WDT);
883 888
884 rockchip_clk_register_plls(rk3368_pll_clks, 889 rockchip_clk_register_plls(ctx, rk3368_pll_clks,
885 ARRAY_SIZE(rk3368_pll_clks), 890 ARRAY_SIZE(rk3368_pll_clks),
886 RK3368_GRF_SOC_STATUS0); 891 RK3368_GRF_SOC_STATUS0);
887 rockchip_clk_register_branches(rk3368_clk_branches, 892 rockchip_clk_register_branches(ctx, rk3368_clk_branches,
888 ARRAY_SIZE(rk3368_clk_branches)); 893 ARRAY_SIZE(rk3368_clk_branches));
889 rockchip_clk_protect_critical(rk3368_critical_clocks, 894 rockchip_clk_protect_critical(rk3368_critical_clocks,
890 ARRAY_SIZE(rk3368_critical_clocks)); 895 ARRAY_SIZE(rk3368_critical_clocks));
891 896
892 rockchip_clk_register_armclk(ARMCLKB, "armclkb", 897 rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb",
893 mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p), 898 mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p),
894 &rk3368_cpuclkb_data, rk3368_cpuclkb_rates, 899 &rk3368_cpuclkb_data, rk3368_cpuclkb_rates,
895 ARRAY_SIZE(rk3368_cpuclkb_rates)); 900 ARRAY_SIZE(rk3368_cpuclkb_rates));
896 901
897 rockchip_clk_register_armclk(ARMCLKL, "armclkl", 902 rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl",
898 mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p), 903 mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p),
899 &rk3368_cpuclkl_data, rk3368_cpuclkl_rates, 904 &rk3368_cpuclkl_data, rk3368_cpuclkl_rates,
900 ARRAY_SIZE(rk3368_cpuclkl_rates)); 905 ARRAY_SIZE(rk3368_cpuclkl_rates));
@@ -902,6 +907,8 @@ static void __init rk3368_clk_init(struct device_node *np)
902 rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0), 907 rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0),
903 ROCKCHIP_SOFTRST_HIWORD_MASK); 908 ROCKCHIP_SOFTRST_HIWORD_MASK);
904 909
905 rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL); 910 rockchip_register_restart_notifier(ctx, RK3368_GLB_SRST_FST, NULL);
911
912 rockchip_clk_of_add_provider(np, ctx);
906} 913}
907CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init); 914CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index ec06350c78c4..5618a8761dee 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -2,6 +2,9 @@
2 * Copyright (c) 2014 MundoReader S.L. 2 * Copyright (c) 2014 MundoReader S.L.
3 * Author: Heiko Stuebner <heiko@sntech.de> 3 * Author: Heiko Stuebner <heiko@sntech.de>
4 * 4 *
5 * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
6 * Author: Xing Zheng <zhengxing@rock-chips.com>
7 *
5 * based on 8 * based on
6 * 9 *
7 * samsung/clk.c 10 * samsung/clk.c
@@ -157,7 +160,8 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
157 return notifier_from_errno(ret); 160 return notifier_from_errno(ret);
158} 161}
159 162
160static struct clk *rockchip_clk_register_frac_branch(const char *name, 163static struct clk *rockchip_clk_register_frac_branch(
164 struct rockchip_clk_provider *ctx, const char *name,
161 const char *const *parent_names, u8 num_parents, 165 const char *const *parent_names, u8 num_parents,
162 void __iomem *base, int muxdiv_offset, u8 div_flags, 166 void __iomem *base, int muxdiv_offset, u8 div_flags,
163 int gate_offset, u8 gate_shift, u8 gate_flags, 167 int gate_offset, u8 gate_shift, u8 gate_flags,
@@ -250,7 +254,7 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name,
250 if (IS_ERR(mux_clk)) 254 if (IS_ERR(mux_clk))
251 return clk; 255 return clk;
252 256
253 rockchip_clk_add_lookup(mux_clk, child->id); 257 rockchip_clk_add_lookup(ctx, mux_clk, child->id);
254 258
255 /* notifier on the fraction divider to catch rate changes */ 259 /* notifier on the fraction divider to catch rate changes */
256 if (frac->mux_frac_idx >= 0) { 260 if (frac->mux_frac_idx >= 0) {
@@ -314,66 +318,94 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name,
314 return clk; 318 return clk;
315} 319}
316 320
317static DEFINE_SPINLOCK(clk_lock); 321struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np,
318static struct clk **clk_table; 322 void __iomem *base, unsigned long nr_clks)
319static void __iomem *reg_base;
320static struct clk_onecell_data clk_data;
321static struct device_node *cru_node;
322static struct regmap *grf;
323
324void __init rockchip_clk_init(struct device_node *np, void __iomem *base,
325 unsigned long nr_clks)
326{ 323{
327 reg_base = base; 324 struct rockchip_clk_provider *ctx;
328 cru_node = np; 325 struct clk **clk_table;
329 grf = ERR_PTR(-EPROBE_DEFER); 326 int i;
327
328 ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL);
329 if (!ctx) {
330 pr_err("%s: Could not allocate clock provider context\n",
331 __func__);
332 return ERR_PTR(-ENOMEM);
333 }
330 334
331 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); 335 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
332 if (!clk_table) 336 if (!clk_table) {
333 pr_err("%s: could not allocate clock lookup table\n", __func__); 337 pr_err("%s: Could not allocate clock lookup table\n",
338 __func__);
339 goto err_free;
340 }
341
342 for (i = 0; i < nr_clks; ++i)
343 clk_table[i] = ERR_PTR(-ENOENT);
334 344
335 clk_data.clks = clk_table; 345 ctx->reg_base = base;
336 clk_data.clk_num = nr_clks; 346 ctx->clk_data.clks = clk_table;
337 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 347 ctx->clk_data.clk_num = nr_clks;
348 ctx->cru_node = np;
349 ctx->grf = ERR_PTR(-EPROBE_DEFER);
350 spin_lock_init(&ctx->lock);
351
352 return ctx;
353
354err_free:
355 kfree(ctx);
356 return ERR_PTR(-ENOMEM);
357}
358
359void __init rockchip_clk_of_add_provider(struct device_node *np,
360 struct rockchip_clk_provider *ctx)
361{
362 if (np) {
363 if (of_clk_add_provider(np, of_clk_src_onecell_get,
364 &ctx->clk_data))
365 pr_err("%s: could not register clk provider\n", __func__);
366 }
338} 367}
339 368
340struct regmap *rockchip_clk_get_grf(void) 369struct regmap *rockchip_clk_get_grf(struct rockchip_clk_provider *ctx)
341{ 370{
342 if (IS_ERR(grf)) 371 if (IS_ERR(ctx->grf))
343 grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf"); 372 ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node, "rockchip,grf");
344 return grf; 373 return ctx->grf;
345} 374}
346 375
347void rockchip_clk_add_lookup(struct clk *clk, unsigned int id) 376void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
377 struct clk *clk, unsigned int id)
348{ 378{
349 if (clk_table && id) 379 if (ctx->clk_data.clks && id)
350 clk_table[id] = clk; 380 ctx->clk_data.clks[id] = clk;
351} 381}
352 382
353void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list, 383void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
384 struct rockchip_pll_clock *list,
354 unsigned int nr_pll, int grf_lock_offset) 385 unsigned int nr_pll, int grf_lock_offset)
355{ 386{
356 struct clk *clk; 387 struct clk *clk;
357 int idx; 388 int idx;
358 389
359 for (idx = 0; idx < nr_pll; idx++, list++) { 390 for (idx = 0; idx < nr_pll; idx++, list++) {
360 clk = rockchip_clk_register_pll(list->type, list->name, 391 clk = rockchip_clk_register_pll(ctx, list->type, list->name,
361 list->parent_names, list->num_parents, 392 list->parent_names, list->num_parents,
362 reg_base, list->con_offset, grf_lock_offset, 393 list->con_offset, grf_lock_offset,
363 list->lock_shift, list->mode_offset, 394 list->lock_shift, list->mode_offset,
364 list->mode_shift, list->rate_table, 395 list->mode_shift, list->rate_table,
365 list->pll_flags, &clk_lock); 396 list->pll_flags);
366 if (IS_ERR(clk)) { 397 if (IS_ERR(clk)) {
367 pr_err("%s: failed to register clock %s\n", __func__, 398 pr_err("%s: failed to register clock %s\n", __func__,
368 list->name); 399 list->name);
369 continue; 400 continue;
370 } 401 }
371 402
372 rockchip_clk_add_lookup(clk, list->id); 403 rockchip_clk_add_lookup(ctx, clk, list->id);
373 } 404 }
374} 405}
375 406
376void __init rockchip_clk_register_branches( 407void __init rockchip_clk_register_branches(
408 struct rockchip_clk_provider *ctx,
377 struct rockchip_clk_branch *list, 409 struct rockchip_clk_branch *list,
378 unsigned int nr_clk) 410 unsigned int nr_clk)
379{ 411{
@@ -389,56 +421,56 @@ void __init rockchip_clk_register_branches(
389 case branch_mux: 421 case branch_mux:
390 clk = clk_register_mux(NULL, list->name, 422 clk = clk_register_mux(NULL, list->name,
391 list->parent_names, list->num_parents, 423 list->parent_names, list->num_parents,
392 flags, reg_base + list->muxdiv_offset, 424 flags, ctx->reg_base + list->muxdiv_offset,
393 list->mux_shift, list->mux_width, 425 list->mux_shift, list->mux_width,
394 list->mux_flags, &clk_lock); 426 list->mux_flags, &ctx->lock);
395 break; 427 break;
396 case branch_divider: 428 case branch_divider:
397 if (list->div_table) 429 if (list->div_table)
398 clk = clk_register_divider_table(NULL, 430 clk = clk_register_divider_table(NULL,
399 list->name, list->parent_names[0], 431 list->name, list->parent_names[0],
400 flags, reg_base + list->muxdiv_offset, 432 flags, ctx->reg_base + list->muxdiv_offset,
401 list->div_shift, list->div_width, 433 list->div_shift, list->div_width,
402 list->div_flags, list->div_table, 434 list->div_flags, list->div_table,
403 &clk_lock); 435 &ctx->lock);
404 else 436 else
405 clk = clk_register_divider(NULL, list->name, 437 clk = clk_register_divider(NULL, list->name,
406 list->parent_names[0], flags, 438 list->parent_names[0], flags,
407 reg_base + list->muxdiv_offset, 439 ctx->reg_base + list->muxdiv_offset,
408 list->div_shift, list->div_width, 440 list->div_shift, list->div_width,
409 list->div_flags, &clk_lock); 441 list->div_flags, &ctx->lock);
410 break; 442 break;
411 case branch_fraction_divider: 443 case branch_fraction_divider:
412 clk = rockchip_clk_register_frac_branch(list->name, 444 clk = rockchip_clk_register_frac_branch(ctx, list->name,
413 list->parent_names, list->num_parents, 445 list->parent_names, list->num_parents,
414 reg_base, list->muxdiv_offset, list->div_flags, 446 ctx->reg_base, list->muxdiv_offset, list->div_flags,
415 list->gate_offset, list->gate_shift, 447 list->gate_offset, list->gate_shift,
416 list->gate_flags, flags, list->child, 448 list->gate_flags, flags, list->child,
417 &clk_lock); 449 &ctx->lock);
418 break; 450 break;
419 case branch_gate: 451 case branch_gate:
420 flags |= CLK_SET_RATE_PARENT; 452 flags |= CLK_SET_RATE_PARENT;
421 453
422 clk = clk_register_gate(NULL, list->name, 454 clk = clk_register_gate(NULL, list->name,
423 list->parent_names[0], flags, 455 list->parent_names[0], flags,
424 reg_base + list->gate_offset, 456 ctx->reg_base + list->gate_offset,
425 list->gate_shift, list->gate_flags, &clk_lock); 457 list->gate_shift, list->gate_flags, &ctx->lock);
426 break; 458 break;
427 case branch_composite: 459 case branch_composite:
428 clk = rockchip_clk_register_branch(list->name, 460 clk = rockchip_clk_register_branch(list->name,
429 list->parent_names, list->num_parents, 461 list->parent_names, list->num_parents,
430 reg_base, list->muxdiv_offset, list->mux_shift, 462 ctx->reg_base, list->muxdiv_offset, list->mux_shift,
431 list->mux_width, list->mux_flags, 463 list->mux_width, list->mux_flags,
432 list->div_shift, list->div_width, 464 list->div_shift, list->div_width,
433 list->div_flags, list->div_table, 465 list->div_flags, list->div_table,
434 list->gate_offset, list->gate_shift, 466 list->gate_offset, list->gate_shift,
435 list->gate_flags, flags, &clk_lock); 467 list->gate_flags, flags, &ctx->lock);
436 break; 468 break;
437 case branch_mmc: 469 case branch_mmc:
438 clk = rockchip_clk_register_mmc( 470 clk = rockchip_clk_register_mmc(
439 list->name, 471 list->name,
440 list->parent_names, list->num_parents, 472 list->parent_names, list->num_parents,
441 reg_base + list->muxdiv_offset, 473 ctx->reg_base + list->muxdiv_offset,
442 list->div_shift 474 list->div_shift
443 ); 475 );
444 break; 476 break;
@@ -446,16 +478,16 @@ void __init rockchip_clk_register_branches(
446 clk = rockchip_clk_register_inverter( 478 clk = rockchip_clk_register_inverter(
447 list->name, list->parent_names, 479 list->name, list->parent_names,
448 list->num_parents, 480 list->num_parents,
449 reg_base + list->muxdiv_offset, 481 ctx->reg_base + list->muxdiv_offset,
450 list->div_shift, list->div_flags, &clk_lock); 482 list->div_shift, list->div_flags, &ctx->lock);
451 break; 483 break;
452 case branch_factor: 484 case branch_factor:
453 clk = rockchip_clk_register_factor_branch( 485 clk = rockchip_clk_register_factor_branch(
454 list->name, list->parent_names, 486 list->name, list->parent_names,
455 list->num_parents, reg_base, 487 list->num_parents, ctx->reg_base,
456 list->div_shift, list->div_width, 488 list->div_shift, list->div_width,
457 list->gate_offset, list->gate_shift, 489 list->gate_offset, list->gate_shift,
458 list->gate_flags, flags, &clk_lock); 490 list->gate_flags, flags, &ctx->lock);
459 break; 491 break;
460 } 492 }
461 493
@@ -472,11 +504,12 @@ void __init rockchip_clk_register_branches(
472 continue; 504 continue;
473 } 505 }
474 506
475 rockchip_clk_add_lookup(clk, list->id); 507 rockchip_clk_add_lookup(ctx, clk, list->id);
476 } 508 }
477} 509}
478 510
479void __init rockchip_clk_register_armclk(unsigned int lookup_id, 511void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
512 unsigned int lookup_id,
480 const char *name, const char *const *parent_names, 513 const char *name, const char *const *parent_names,
481 u8 num_parents, 514 u8 num_parents,
482 const struct rockchip_cpuclk_reg_data *reg_data, 515 const struct rockchip_cpuclk_reg_data *reg_data,
@@ -486,15 +519,15 @@ void __init rockchip_clk_register_armclk(unsigned int lookup_id,
486 struct clk *clk; 519 struct clk *clk;
487 520
488 clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents, 521 clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents,
489 reg_data, rates, nrates, reg_base, 522 reg_data, rates, nrates, ctx->reg_base,
490 &clk_lock); 523 &ctx->lock);
491 if (IS_ERR(clk)) { 524 if (IS_ERR(clk)) {
492 pr_err("%s: failed to register clock %s: %ld\n", 525 pr_err("%s: failed to register clock %s: %ld\n",
493 __func__, name, PTR_ERR(clk)); 526 __func__, name, PTR_ERR(clk));
494 return; 527 return;
495 } 528 }
496 529
497 rockchip_clk_add_lookup(clk, lookup_id); 530 rockchip_clk_add_lookup(ctx, clk, lookup_id);
498} 531}
499 532
500void __init rockchip_clk_protect_critical(const char *const clocks[], 533void __init rockchip_clk_protect_critical(const char *const clocks[],
@@ -511,6 +544,7 @@ void __init rockchip_clk_protect_critical(const char *const clocks[],
511 } 544 }
512} 545}
513 546
547static void __iomem *rst_base;
514static unsigned int reg_restart; 548static unsigned int reg_restart;
515static void (*cb_restart)(void); 549static void (*cb_restart)(void);
516static int rockchip_restart_notify(struct notifier_block *this, 550static int rockchip_restart_notify(struct notifier_block *this,
@@ -519,7 +553,7 @@ static int rockchip_restart_notify(struct notifier_block *this,
519 if (cb_restart) 553 if (cb_restart)
520 cb_restart(); 554 cb_restart();
521 555
522 writel(0xfdb9, reg_base + reg_restart); 556 writel(0xfdb9, rst_base + reg_restart);
523 return NOTIFY_DONE; 557 return NOTIFY_DONE;
524} 558}
525 559
@@ -528,10 +562,12 @@ static struct notifier_block rockchip_restart_handler = {
528 .priority = 128, 562 .priority = 128,
529}; 563};
530 564
531void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void)) 565void __init rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
566 unsigned int reg, void (*cb)(void))
532{ 567{
533 int ret; 568 int ret;
534 569
570 rst_base = ctx->reg_base;
535 reg_restart = reg; 571 reg_restart = reg;
536 cb_restart = cb; 572 cb_restart = cb;
537 ret = register_restart_handler(&rockchip_restart_handler); 573 ret = register_restart_handler(&rockchip_restart_handler);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 4133bfc8f827..e243d509da89 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -27,6 +27,7 @@
27#define CLK_ROCKCHIP_CLK_H 27#define CLK_ROCKCHIP_CLK_H
28 28
29#include <linux/io.h> 29#include <linux/io.h>
30#include <linux/clk-provider.h>
30 31
31struct clk; 32struct clk;
32 33
@@ -127,6 +128,22 @@ enum rockchip_pll_type {
127 .nb = _nb, \ 128 .nb = _nb, \
128} 129}
129 130
131/**
132 * struct rockchip_clk_provider: information about clock provider
133 * @reg_base: virtual address for the register base.
134 * @clk_data: holds clock related data like clk* and number of clocks.
135 * @cru_node: device-node of the clock-provider
136 * @grf: regmap of the general-register-files syscon
137 * @lock: maintains exclusion between callbacks for a given clock-provider.
138 */
139struct rockchip_clk_provider {
140 void __iomem *reg_base;
141 struct clk_onecell_data clk_data;
142 struct device_node *cru_node;
143 struct regmap *grf;
144 spinlock_t lock;
145};
146
130struct rockchip_pll_rate_table { 147struct rockchip_pll_rate_table {
131 unsigned long rate; 148 unsigned long rate;
132 unsigned int nr; 149 unsigned int nr;
@@ -194,12 +211,13 @@ struct rockchip_pll_clock {
194 .rate_table = _rtable, \ 211 .rate_table = _rtable, \
195 } 212 }
196 213
197struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 214struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
215 enum rockchip_pll_type pll_type,
198 const char *name, const char *const *parent_names, 216 const char *name, const char *const *parent_names,
199 u8 num_parents, void __iomem *base, int con_offset, 217 u8 num_parents, int con_offset, int grf_lock_offset,
200 int grf_lock_offset, int lock_shift, int reg_mode, 218 int lock_shift, int mode_offset, int mode_shift,
201 int mode_shift, struct rockchip_pll_rate_table *rate_table, 219 struct rockchip_pll_rate_table *rate_table,
202 u8 clk_pll_flags, spinlock_t *lock); 220 u8 clk_pll_flags);
203 221
204struct rockchip_cpuclk_clksel { 222struct rockchip_cpuclk_clksel {
205 int reg; 223 int reg;
@@ -558,21 +576,28 @@ struct rockchip_clk_branch {
558 .gate_flags = gf, \ 576 .gate_flags = gf, \
559 } 577 }
560 578
561void rockchip_clk_init(struct device_node *np, void __iomem *base, 579struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
562 unsigned long nr_clks); 580 void __iomem *base, unsigned long nr_clks);
563struct regmap *rockchip_clk_get_grf(void); 581void rockchip_clk_of_add_provider(struct device_node *np,
564void rockchip_clk_add_lookup(struct clk *clk, unsigned int id); 582 struct rockchip_clk_provider *ctx);
565void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list, 583struct regmap *rockchip_clk_get_grf(struct rockchip_clk_provider *ctx);
584void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
585 struct clk *clk, unsigned int id);
586void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
587 struct rockchip_clk_branch *list,
566 unsigned int nr_clk); 588 unsigned int nr_clk);
567void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list, 589void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
590 struct rockchip_pll_clock *pll_list,
568 unsigned int nr_pll, int grf_lock_offset); 591 unsigned int nr_pll, int grf_lock_offset);
569void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name, 592void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
593 unsigned int lookup_id, const char *name,
570 const char *const *parent_names, u8 num_parents, 594 const char *const *parent_names, u8 num_parents,
571 const struct rockchip_cpuclk_reg_data *reg_data, 595 const struct rockchip_cpuclk_reg_data *reg_data,
572 const struct rockchip_cpuclk_rate_table *rates, 596 const struct rockchip_cpuclk_rate_table *rates,
573 int nrates); 597 int nrates);
574void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); 598void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
575void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void)); 599void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
600 unsigned int reg, void (*cb)(void));
576 601
577#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 602#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0)
578 603