X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?p=kvmfornfv.git;a=blobdiff_plain;f=kernel%2Fdrivers%2Fclk%2Fst%2Fclkgen-mux.c;h=5dc5ce21796065df6739d4e395a35ce5c50375b2;hp=ef6514636bfc98c61f6531db519b78c287f5790a;hb=e09b41010ba33a20a87472ee821fa407a5b8da36;hpb=f93b97fd65072de626c074dbe099a1fff05ce060 diff --git a/kernel/drivers/clk/st/clkgen-mux.c b/kernel/drivers/clk/st/clkgen-mux.c index ef6514636..5dc5ce217 100644 --- a/kernel/drivers/clk/st/clkgen-mux.c +++ b/kernel/drivers/clk/st/clkgen-mux.c @@ -15,7 +15,9 @@ #include #include +#include #include +#include "clkgen.h" static DEFINE_SPINLOCK(clkgena_divmux_lock); static DEFINE_SPINLOCK(clkgenf_lock); @@ -24,20 +26,17 @@ static const char ** __init clkgen_mux_get_parents(struct device_node *np, int *num_parents) { const char **parents; - int nparents, i; + int nparents; - nparents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + nparents = of_clk_get_parent_count(np); if (WARN_ON(nparents <= 0)) return ERR_PTR(-EINVAL); - parents = kzalloc(nparents * sizeof(const char *), GFP_KERNEL); + parents = kcalloc(nparents, sizeof(const char *), GFP_KERNEL); if (!parents) return ERR_PTR(-ENOMEM); - for (i = 0; i < nparents; i++) - parents[i] = of_clk_get_parent_name(np, i); - - *num_parents = nparents; + *num_parents = of_clk_parent_fill(np, parents, nparents); return parents; } @@ -131,7 +130,7 @@ static int clkgena_divmux_is_enabled(struct clk_hw *hw) return (s8)clk_mux_ops.get_parent(mux_hw) > 0; } -u8 clkgena_divmux_get_parent(struct clk_hw *hw) +static u8 clkgena_divmux_get_parent(struct clk_hw *hw) { struct clkgena_divmux *genamux = to_clkgena_divmux(hw); struct clk_hw *mux_hw = &genamux->mux.hw; @@ -141,7 +140,7 @@ u8 clkgena_divmux_get_parent(struct clk_hw *hw) genamux->muxsel = clk_mux_ops.get_parent(mux_hw); if ((s8)genamux->muxsel < 0) { pr_debug("%s: %s: Invalid parent, setting to default.\n", - __func__, __clk_get_name(hw->clk)); + __func__, clk_hw_get_name(hw)); genamux->muxsel = 0; } @@ -168,7 +167,7 @@ static int clkgena_divmux_set_parent(struct clk_hw *hw, u8 index) return 0; } -unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw, +static unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clkgena_divmux *genamux = to_clkgena_divmux(hw); @@ -215,7 +214,7 @@ static const struct clk_ops clkgena_divmux_ops = { /** * clk_register_genamux - register a genamux clock with the clock framework */ -struct clk *clk_register_genamux(const char *name, +static struct clk * __init clk_register_genamux(const char *name, const char **parent_names, u8 num_parents, void __iomem *reg, const struct clkgena_divmux_data *muxdata, @@ -237,7 +236,7 @@ struct clk *clk_register_genamux(const char *name, init.name = name; init.ops = &clkgena_divmux_ops; - init.flags = CLK_IS_BASIC; + init.flags = CLK_IS_BASIC | CLK_GET_RATE_NOCACHE; init.parent_names = parent_names; init.num_parents = num_parents; @@ -369,11 +368,10 @@ static const struct of_device_id clkgena_divmux_of_match[] = { {} }; -static void __iomem * __init clkgen_get_register_base( - struct device_node *np) +static void __iomem * __init clkgen_get_register_base(struct device_node *np) { struct device_node *pnode; - void __iomem *reg = NULL; + void __iomem *reg; pnode = of_get_parent(np); if (!pnode) @@ -385,7 +383,7 @@ static void __iomem * __init clkgen_get_register_base( return reg; } -void __init st_of_clkgena_divmux_setup(struct device_node *np) +static void __init st_of_clkgena_divmux_setup(struct device_node *np) { const struct of_device_id *match; const struct clkgena_divmux_data *data; @@ -398,7 +396,7 @@ void __init st_of_clkgena_divmux_setup(struct device_node *np) if (WARN_ON(!match)) return; - data = (struct clkgena_divmux_data *)match->data; + data = match->data; reg = clkgen_get_register_base(np); if (!reg) @@ -406,18 +404,18 @@ void __init st_of_clkgena_divmux_setup(struct device_node *np) parents = clkgen_mux_get_parents(np, &num_parents); if (IS_ERR(parents)) - return; + goto err_parents; clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); if (!clk_data) - goto err; + goto err_alloc; clk_data->clk_num = data->num_outputs; - clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *), + clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), GFP_KERNEL); if (!clk_data->clks) - goto err; + goto err_alloc_clks; for (i = 0; i < clk_data->clk_num; i++) { struct clk *clk; @@ -447,11 +445,13 @@ void __init st_of_clkgena_divmux_setup(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); return; err: - if (clk_data) - kfree(clk_data->clks); - + kfree(clk_data->clks); +err_alloc_clks: kfree(clk_data); +err_alloc: kfree(parents); +err_parents: + iounmap(reg); } CLK_OF_DECLARE(clkgenadivmux, "st,clkgena-divmux", st_of_clkgena_divmux_setup); @@ -485,13 +485,13 @@ static const struct of_device_id clkgena_prediv_of_match[] = { {} }; -void __init st_of_clkgena_prediv_setup(struct device_node *np) +static void __init st_of_clkgena_prediv_setup(struct device_node *np) { const struct of_device_id *match; void __iomem *reg; const char *parent_name, *clk_name; struct clk *clk; - struct clkgena_prediv_data *data; + const struct clkgena_prediv_data *data; match = of_match_node(clkgena_prediv_of_match, np); if (!match) { @@ -499,7 +499,7 @@ void __init st_of_clkgena_prediv_setup(struct device_node *np) return; } - data = (struct clkgena_prediv_data *)match->data; + data = match->data; reg = clkgen_get_register_base(np); if (!reg) @@ -507,17 +507,18 @@ void __init st_of_clkgena_prediv_setup(struct device_node *np) parent_name = of_clk_get_parent_name(np, 0); if (!parent_name) - return; + goto err; if (of_property_read_string_index(np, "clock-output-names", 0, &clk_name)) - return; + goto err; - clk = clk_register_divider_table(NULL, clk_name, parent_name, 0, + clk = clk_register_divider_table(NULL, clk_name, parent_name, + CLK_GET_RATE_NOCACHE, reg + data->offset, data->shift, 1, 0, data->table, NULL); if (IS_ERR(clk)) - return; + goto err; of_clk_add_provider(np, of_clk_src_simple_get, clk); pr_debug("%s: parent %s rate %u\n", @@ -526,6 +527,8 @@ void __init st_of_clkgena_prediv_setup(struct device_node *np) (unsigned int)clk_get_rate(clk)); return; +err: + iounmap(reg); } CLK_OF_DECLARE(clkgenaprediv, "st,clkgena-prediv", st_of_clkgena_prediv_setup); @@ -574,6 +577,7 @@ static struct clkgen_mux_data stih415_a9_mux_data = { .offset = 0, .shift = 1, .width = 2, + .lock = &clkgen_a9_lock, }; static struct clkgen_mux_data stih416_a9_mux_data = { .offset = 0, @@ -584,6 +588,7 @@ static struct clkgen_mux_data stih407_a9_mux_data = { .offset = 0x1a4, .shift = 0, .width = 2, + .lock = &clkgen_a9_lock, }; static const struct of_device_id mux_of_match[] = { @@ -622,14 +627,14 @@ static const struct of_device_id mux_of_match[] = { {} }; -void __init st_of_clkgen_mux_setup(struct device_node *np) +static void __init st_of_clkgen_mux_setup(struct device_node *np) { const struct of_device_id *match; struct clk *clk; void __iomem *reg; const char **parents; int num_parents; - struct clkgen_mux_data *data; + const struct clkgen_mux_data *data; match = of_match_node(mux_of_match, np); if (!match) { @@ -637,7 +642,7 @@ void __init st_of_clkgen_mux_setup(struct device_node *np) return; } - data = (struct clkgen_mux_data *)match->data; + data = match->data; reg = of_iomap(np, 0); if (!reg) { @@ -649,7 +654,7 @@ void __init st_of_clkgen_mux_setup(struct device_node *np) if (IS_ERR(parents)) { pr_err("%s: Failed to get parents (%ld)\n", __func__, PTR_ERR(parents)); - return; + goto err_parents; } clk = clk_register_mux(NULL, np->name, parents, num_parents, @@ -665,12 +670,14 @@ void __init st_of_clkgen_mux_setup(struct device_node *np) __clk_get_name(clk_get_parent(clk)), (unsigned int)clk_get_rate(clk)); + kfree(parents); of_clk_add_provider(np, of_clk_src_simple_get, clk); + return; err: kfree(parents); - - return; +err_parents: + iounmap(reg); } CLK_OF_DECLARE(clkgen_mux, "st,clkgen-mux", st_of_clkgen_mux_setup); @@ -699,19 +706,19 @@ static const struct of_device_id vcc_of_match[] = { {} }; -void __init st_of_clkgen_vcc_setup(struct device_node *np) +static void __init st_of_clkgen_vcc_setup(struct device_node *np) { const struct of_device_id *match; void __iomem *reg; const char **parents; int num_parents, i; struct clk_onecell_data *clk_data; - struct clkgen_vcc_data *data; + const struct clkgen_vcc_data *data; match = of_match_node(vcc_of_match, np); if (WARN_ON(!match)) return; - data = (struct clkgen_vcc_data *)match->data; + data = match->data; reg = of_iomap(np, 0); if (!reg) @@ -719,18 +726,18 @@ void __init st_of_clkgen_vcc_setup(struct device_node *np) parents = clkgen_mux_get_parents(np, &num_parents); if (IS_ERR(parents)) - return; + goto err_parents; clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); if (!clk_data) - goto err; + goto err_alloc; clk_data->clk_num = VCC_MAX_CHANNELS; - clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *), + clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), GFP_KERNEL); if (!clk_data->clks) - goto err; + goto err_alloc_clks; for (i = 0; i < clk_data->clk_num; i++) { struct clk *clk; @@ -749,21 +756,21 @@ void __init st_of_clkgen_vcc_setup(struct device_node *np) if (*clk_name == '\0') continue; - gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); + gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) - break; + goto err; - div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); + div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) { kfree(gate); - break; + goto err; } - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); + mux = kzalloc(sizeof(*mux), GFP_KERNEL); if (!mux) { kfree(gate); kfree(div); - break; + goto err; } gate->reg = reg + VCC_GATE_OFFSET; @@ -786,7 +793,8 @@ void __init st_of_clkgen_vcc_setup(struct device_node *np) &mux->hw, &clk_mux_ops, &div->hw, &clk_divider_ops, &gate->hw, &clk_gate_ops, - data->clk_flags); + data->clk_flags | + CLK_GET_RATE_NOCACHE); if (IS_ERR(clk)) { kfree(gate); kfree(div); @@ -821,10 +829,12 @@ err: kfree(container_of(composite->mux_hw, struct clk_mux, hw)); } - if (clk_data) - kfree(clk_data->clks); - + kfree(clk_data->clks); +err_alloc_clks: kfree(clk_data); +err_alloc: kfree(parents); +err_parents: + iounmap(reg); } CLK_OF_DECLARE(clkgen_vcc, "st,clkgen-vcc", st_of_clkgen_vcc_setup);