Use a flexible array member to combine allocations.

As kmemdup_array is really kcalloc + memcpy and kzalloc_flex kzalloc +
kcalloc, kzalloc and kcalloc combine leaving the memcpy.

Signed-off-by: Rosen Penev <[email protected]>
---
 drivers/clk/samsung/clk-cpu.c | 30 +++++++++++-------------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index ffc33e5decf5..ad08d6288baa 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -101,11 +101,11 @@ struct exynos_cpuclk {
        const struct clk_hw                     *alt_parent;
        void __iomem                            *base;
        spinlock_t                              *lock;
-       const struct exynos_cpuclk_cfg_data     *cfg;
        const unsigned long                     num_cfgs;
        struct notifier_block                   clk_nb;
        unsigned long                           flags;
        const struct exynos_cpuclk_chip         *chip;
+       struct exynos_cpuclk_cfg_data           cfg[];
 };
 
 /* ---- Common code --------------------------------------------------------- 
*/
@@ -660,10 +660,6 @@ static int __init exynos_register_cpu_clock(struct 
samsung_clk_provider *ctx,
                return -EINVAL;
        }
 
-       cpuclk = kzalloc_obj(*cpuclk);
-       if (!cpuclk)
-               return -ENOMEM;
-
        parent_name = clk_hw_get_name(parent);
 
        init.name = clk_data->name;
@@ -672,6 +668,15 @@ static int __init exynos_register_cpu_clock(struct 
samsung_clk_provider *ctx,
        init.num_parents = 1;
        init.ops = &exynos_cpuclk_clk_ops;
 
+       /* Find count of configuration rates in cfg */
+       for (num_cfgs = 0; clk_data->cfg[num_cfgs].prate != 0; )
+               num_cfgs++;
+
+       cpuclk = kzalloc_flex(*cpuclk, cfg, num_cfgs);
+       if (!cpuclk)
+               return -ENOMEM;
+
+       memcpy(cpuclk->cfg, clk_data->cfg, num_cfgs * sizeof(*cpuclk->cfg));
        cpuclk->alt_parent = alt_parent;
        cpuclk->hw.init = &init;
        cpuclk->base = ctx->reg_base + clk_data->offset;
@@ -687,29 +692,16 @@ static int __init exynos_register_cpu_clock(struct 
samsung_clk_provider *ctx,
                goto free_cpuclk;
        }
 
-       /* Find count of configuration rates in cfg */
-       for (num_cfgs = 0; clk_data->cfg[num_cfgs].prate != 0; )
-               num_cfgs++;
-
-       cpuclk->cfg = kmemdup_array(clk_data->cfg, num_cfgs, 
sizeof(*cpuclk->cfg),
-                                   GFP_KERNEL);
-       if (!cpuclk->cfg) {
-               ret = -ENOMEM;
-               goto unregister_clk_nb;
-       }
-
        ret = clk_hw_register(NULL, &cpuclk->hw);
        if (ret) {
                pr_err("%s: could not register cpuclk %s\n", __func__,
                       clk_data->name);
-               goto free_cpuclk_data;
+               goto unregister_clk_nb;
        }
 
        samsung_clk_add_lookup(ctx, &cpuclk->hw, clk_data->id);
        return 0;
 
-free_cpuclk_data:
-       kfree(cpuclk->cfg);
 unregister_clk_nb:
        clk_notifier_unregister(parent->clk, &cpuclk->clk_nb);
 free_cpuclk:
-- 
2.53.0


Reply via email to