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

clk: mediatek: mt8173: Fix enabling of critical clocks

On the MT8173 the clocks are provided by different units. To enable
the critical clocks we must be sure that all parent clocks are already
registered, otherwise the parents of the critical clocks end up being
unused and get disabled later. To find a place where all parents are
registered we try each time after we've registered some clocks if
all known providers are present now and only then we enable the critical
clocks

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
[sboyd@codeaurora.org: Marked function and data __init]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>

authored by

Sascha Hauer and committed by
Stephen Boyd
7b2a4635 3be6d8ce

+21 -5
+21 -5
drivers/clk/mediatek/clk-mt8173.c
··· 700 700 MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), 701 701 }; 702 702 703 + static struct clk_onecell_data *mt8173_top_clk_data __initdata; 704 + static struct clk_onecell_data *mt8173_pll_clk_data __initdata; 705 + 706 + static void __init mtk_clk_enable_critical(void) 707 + { 708 + if (!mt8173_top_clk_data || !mt8173_pll_clk_data) 709 + return; 710 + 711 + clk_prepare_enable(mt8173_pll_clk_data->clks[CLK_APMIXED_ARMCA15PLL]); 712 + clk_prepare_enable(mt8173_pll_clk_data->clks[CLK_APMIXED_ARMCA7PLL]); 713 + clk_prepare_enable(mt8173_top_clk_data->clks[CLK_TOP_MEM_SEL]); 714 + clk_prepare_enable(mt8173_top_clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]); 715 + clk_prepare_enable(mt8173_top_clk_data->clks[CLK_TOP_CCI400_SEL]); 716 + clk_prepare_enable(mt8173_top_clk_data->clks[CLK_TOP_RTC_SEL]); 717 + } 718 + 703 719 static void __init mtk_topckgen_init(struct device_node *node) 704 720 { 705 721 struct clk_onecell_data *clk_data; ··· 728 712 return; 729 713 } 730 714 731 - clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); 715 + mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); 732 716 733 717 mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data); 734 718 mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); 735 719 mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, 736 720 &mt8173_clk_lock, clk_data); 737 721 738 - clk_prepare_enable(clk_data->clks[CLK_TOP_CCI400_SEL]); 739 - 740 722 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); 741 723 if (r) 742 724 pr_err("%s(): could not register clock provider: %d\n", 743 725 __func__, r); 726 + 727 + mtk_clk_enable_critical(); 744 728 } 745 729 CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8173-topckgen", mtk_topckgen_init); 746 730 ··· 834 818 { 835 819 struct clk_onecell_data *clk_data; 836 820 837 - clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); 821 + mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); 838 822 if (!clk_data) 839 823 return; 840 824 841 825 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); 842 826 843 - clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMCA15PLL]); 827 + mtk_clk_enable_critical(); 844 828 } 845 829 CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys", 846 830 mtk_apmixedsys_init);