diff options
Diffstat (limited to 'drivers/clk/sunxi/clk-sunxi.c')
-rw-r--r-- | drivers/clk/sunxi/clk-sunxi.c | 36 |
1 files changed, 13 insertions, 23 deletions
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index aa4add580516..012714d94b42 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -656,7 +656,8 @@ static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = { }; static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, - const struct mux_data *data) + const struct mux_data *data, + unsigned long flags) { struct clk *clk; const char *clk_name = node->name; @@ -678,7 +679,7 @@ static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, } clk = clk_register_mux(NULL, clk_name, parents, i, - CLK_SET_RATE_PARENT, reg, + CLK_SET_RATE_PARENT | flags, reg, data->shift, SUNXI_MUX_GATE_WIDTH, 0, &clk_lock); @@ -703,29 +704,22 @@ out_unmap: static void __init sun4i_cpu_clk_setup(struct device_node *node) { - struct clk *clk; - - clk = sunxi_mux_clk_setup(node, &sun4i_cpu_mux_data); - if (!clk) - return; - /* Protect CPU clock */ - __clk_get(clk); - clk_prepare_enable(clk); + sunxi_mux_clk_setup(node, &sun4i_cpu_mux_data, CLK_IS_CRITICAL); } CLK_OF_DECLARE(sun4i_cpu, "allwinner,sun4i-a10-cpu-clk", sun4i_cpu_clk_setup); static void __init sun6i_ahb1_mux_clk_setup(struct device_node *node) { - sunxi_mux_clk_setup(node, &sun6i_a31_ahb1_mux_data); + sunxi_mux_clk_setup(node, &sun6i_a31_ahb1_mux_data, 0); } CLK_OF_DECLARE(sun6i_ahb1_mux, "allwinner,sun6i-a31-ahb1-mux-clk", sun6i_ahb1_mux_clk_setup); static void __init sun8i_ahb2_clk_setup(struct device_node *node) { - sunxi_mux_clk_setup(node, &sun8i_h3_ahb2_mux_data); + sunxi_mux_clk_setup(node, &sun8i_h3_ahb2_mux_data, 0); } CLK_OF_DECLARE(sun8i_ahb2, "allwinner,sun8i-h3-ahb2-clk", sun8i_ahb2_clk_setup); @@ -900,6 +894,7 @@ struct divs_data { u8 shift; /* otherwise it's a normal divisor with this shift */ u8 pow; /* is it power-of-two based? */ u8 gate; /* is it independently gateable? */ + bool critical; } div[SUNXI_DIVS_MAX_QTY]; }; @@ -915,7 +910,8 @@ static const struct divs_data pll5_divs_data __initconst = { .factors = &sun4i_pll5_data, .ndivs = 2, .div = { - { .shift = 0, .pow = 0, }, /* M, DDR */ + /* Protect PLL5_DDR */ + { .shift = 0, .pow = 0, .critical = true }, /* M, DDR */ { .shift = 16, .pow = 1, }, /* P, other */ /* No output for the base factor clock */ } @@ -1089,7 +1085,9 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, NULL, NULL, rate_hw, rate_ops, gate_hw, &clk_gate_ops, - clkflags); + clkflags | + data->div[i].critical ? + CLK_IS_CRITICAL : 0); WARN_ON(IS_ERR(clk_data->clks[i])); } @@ -1117,15 +1115,7 @@ out_unmap: static void __init sun4i_pll5_clk_setup(struct device_node *node) { - struct clk **clks; - - clks = sunxi_divs_clk_setup(node, &pll5_divs_data); - if (!clks) - return; - - /* Protect PLL5_DDR */ - __clk_get(clks[0]); - clk_prepare_enable(clks[0]); + sunxi_divs_clk_setup(node, &pll5_divs_data); } CLK_OF_DECLARE(sun4i_pll5, "allwinner,sun4i-a10-pll5-clk", sun4i_pll5_clk_setup); |