Since clk_register_clkdev() is exported for modules the caller should get a
pointer to the allocated resources. Otherwise the memory leak is guaranteed on
the ->remove() stage.

Cc: Tomeu Vizoso <tomeu.viz...@collabora.com>
Reviewed-by: Mika Westerberg <mika.westerb...@linux.intel.com>
Acked-by: Sylwester Nawrocki <s.nawro...@samsung.com>
Signed-off-by: Andy Shevchenko <andriy.shevche...@linux.intel.com>
---
 arch/arm/mach-vexpress/spc.c           |  5 ++++-
 arch/mips/ath79/clock.c                |  6 +++---
 drivers/clk/clk-bcm2835.c              | 12 +++++++-----
 drivers/clk/clk-max-gen.c              |  9 ++++-----
 drivers/clk/clk-xgene.c                |  6 +++---
 drivers/clk/clkdev.c                   | 15 ++++++++++-----
 drivers/clk/samsung/clk-pll.c          | 15 +++++++++------
 drivers/clk/samsung/clk-s3c2410-dclk.c | 22 +++++++++++----------
 drivers/clk/samsung/clk.c              | 35 +++++++++++++++++++---------------
 include/linux/clkdev.h                 |  2 +-
 10 files changed, 73 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c
index f61158c..0477007 100644
--- a/arch/arm/mach-vexpress/spc.c
+++ b/arch/arm/mach-vexpress/spc.c
@@ -568,6 +568,8 @@ static int __init ve_spc_clk_init(void)
 
        for_each_possible_cpu(cpu) {
                struct device *cpu_dev = get_cpu_device(cpu);
+               struct clk_lookup *cl;
+
                if (!cpu_dev) {
                        pr_warn("failed to get cpu%d device\n", cpu);
                        continue;
@@ -577,7 +579,8 @@ static int __init ve_spc_clk_init(void)
                        pr_warn("failed to register cpu%d clock\n", cpu);
                        continue;
                }
-               if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
+               cl = clk_register_clkdev(clk, NULL, dev_name(cpu_dev));
+               if (IS_ERR(cl)) {
                        pr_warn("failed to register cpu%d clock lookup\n", cpu);
                        continue;
                }
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index 26479f4..db5ed95 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -35,7 +35,7 @@ struct clk {
 static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate)
 {
        struct clk *clk;
-       int err;
+       struct clk_lookup *cl;
 
        clk = kzalloc(sizeof(*clk), GFP_KERNEL);
        if (!clk)
@@ -43,8 +43,8 @@ static void __init ath79_add_sys_clkdev(const char *id, 
unsigned long rate)
 
        clk->rate = rate;
 
-       err = clk_register_clkdev(clk, id, NULL);
-       if (err)
+       cl = clk_register_clkdev(clk, id, NULL);
+       if (IS_ERR(cl))
                panic("unable to register %s clock device", id);
 }
 
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c
index 6b950ca..6243527 100644
--- a/drivers/clk/clk-bcm2835.c
+++ b/drivers/clk/clk-bcm2835.c
@@ -30,7 +30,7 @@
 void __init bcm2835_init_clocks(void)
 {
        struct clk *clk;
-       int ret;
+       struct clk_lookup *cl;
 
        clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT,
                                        250000000);
@@ -46,15 +46,17 @@ void __init bcm2835_init_clocks(void)
                                        3000000);
        if (IS_ERR(clk))
                pr_err("uart0_pclk not registered\n");
-       ret = clk_register_clkdev(clk, NULL, "20201000.uart");
-       if (ret)
+
+       cl = clk_register_clkdev(clk, NULL, "20201000.uart");
+       if (IS_ERR(cl))
                pr_err("uart0_pclk alias not registered\n");
 
        clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
                                        125000000);
        if (IS_ERR(clk))
                pr_err("uart1_pclk not registered\n");
-       ret = clk_register_clkdev(clk, NULL, "20215000.uart");
-       if (ret)
+
+       cl = clk_register_clkdev(clk, NULL, "20215000.uart");
+       if (IS_ERR(cl))
                pr_err("uart1_pclk alias not registered\n");
 }
diff --git a/drivers/clk/clk-max-gen.c b/drivers/clk/clk-max-gen.c
index 6505049..cd19136 100644
--- a/drivers/clk/clk-max-gen.c
+++ b/drivers/clk/clk-max-gen.c
@@ -92,16 +92,15 @@ static struct clk *max_gen_clk_register(struct device *dev,
 {
        struct clk *clk;
        struct clk_hw *hw = &max_gen->hw;
-       int ret;
+       struct clk_lookup *cl;
 
        clk = devm_clk_register(dev, hw);
        if (IS_ERR(clk))
                return clk;
 
-       ret = clk_register_clkdev(clk, hw->init->name, NULL);
-
-       if (ret)
-               return ERR_PTR(ret);
+       cl = clk_register_clkdev(clk, hw->init->name, NULL);
+       if (IS_ERR(cl))
+               return ERR_CAST(cl);
 
        return clk;
 }
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index dd8a62d..ce5bf4d 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -401,8 +401,8 @@ static struct clk *xgene_register_clk(struct device *dev,
 {
        struct xgene_clk *apmclk;
        struct clk *clk;
+       struct clk_lookup *cl;
        struct clk_init_data init;
-       int rc;
 
        /* allocate the APM clock structure */
        apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);
@@ -431,8 +431,8 @@ static struct clk *xgene_register_clk(struct device *dev,
        }
 
        /* Register the clock for lookup */
-       rc = clk_register_clkdev(clk, name, NULL);
-       if (rc != 0) {
+       cl = clk_register_clkdev(clk, name, NULL);
+       if (IS_ERR(cl)) {
                pr_err("%s: could not register lookup clk %s\n",
                        __func__, name);
        }
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 1fcb6ef..c8f67ca 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -320,29 +320,34 @@ EXPORT_SYMBOL(clkdev_drop);
  * clkdev.
  *
  * To make things easier for mass registration, we detect error clks
- * from a previous clk_register() call, and return the error code for
+ * from a previous clk_register() call, and return the error pointer for
  * those.  This is to permit this function to be called immediately
  * after clk_register().
+ *
+ * Return:
+ * A pointer to the allocated struct clk_lookup is returned on success, or
+ * error pointer otherwise. The caller may use clkdev_drop() to free the
+ * allocated resources.
  */
-int clk_register_clkdev(struct clk *clk, const char *con_id,
+struct clk_lookup *clk_register_clkdev(struct clk *clk, const char *con_id,
        const char *dev_fmt, ...)
 {
        struct clk_lookup *cl;
        va_list ap;
 
        if (IS_ERR(clk))
-               return PTR_ERR(clk);
+               return ERR_CAST(clk);
 
        va_start(ap, dev_fmt);
        cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
        va_end(ap);
 
        if (!cl)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        clkdev_add(cl);
 
-       return 0;
+       return cl;
 }
 EXPORT_SYMBOL(clk_register_clkdev);
 
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 9d70e5c..e213e35 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -927,6 +927,7 @@ struct clk * __init samsung_clk_register_pll2550x(const 
char *name,
 {
        struct samsung_clk_pll2550x *pll;
        struct clk *clk;
+       struct clk_lookup *cl;
        struct clk_init_data init;
 
        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
@@ -952,7 +953,8 @@ struct clk * __init samsung_clk_register_pll2550x(const 
char *name,
                kfree(pll);
        }
 
-       if (clk_register_clkdev(clk, name, NULL))
+       cl = clk_register_clkdev(clk, name, NULL);
+       if (IS_ERR(cl))
                pr_err("%s: failed to register lookup for %s", __func__, name);
 
        return clk;
@@ -1161,8 +1163,9 @@ static void __init _samsung_clk_register_pll(struct 
samsung_clk_provider *ctx,
 {
        struct samsung_clk_pll *pll;
        struct clk *clk;
+       struct clk_lookup *cl;
        struct clk_init_data init;
-       int ret, len;
+       int len;
 
        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
        if (!pll) {
@@ -1296,10 +1299,10 @@ static void __init _samsung_clk_register_pll(struct 
samsung_clk_provider *ctx,
        if (!pll_clk->alias)
                return;
 
-       ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
-       if (ret)
-               pr_err("%s: failed to register lookup for %s : %d",
-                       __func__, pll_clk->name, ret);
+       cl = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
+       if (IS_ERR(cl))
+               pr_err("%s: failed to register lookup for %s : %ld",
+                       __func__, pll_clk->name, PTR_ERR(cl));
 }
 
 void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c 
b/drivers/clk/samsung/clk-s3c2410-dclk.c
index f4f29ed6..6f07b23 100644
--- a/drivers/clk/samsung/clk-s3c2410-dclk.c
+++ b/drivers/clk/samsung/clk-s3c2410-dclk.c
@@ -238,8 +238,9 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
        struct s3c24xx_dclk *s3c24xx_dclk;
        struct resource *mem;
        struct clk **clk_table;
+       struct clk_lookup *cl;
        struct s3c24xx_dclk_drv_data *dclk_variant;
-       int ret, i;
+       int ret = 0, i;
 
        s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk),
                                    GFP_KERNEL);
@@ -309,17 +310,18 @@ static int s3c24xx_dclk_probe(struct platform_device 
*pdev)
                        goto err_clk_register;
                }
 
-       ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
-       if (!ret)
-               ret = clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
-       if (!ret)
-               ret = clk_register_clkdev(clk_table[MUX_CLKOUT0],
+       cl = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
+       if (!IS_ERR(cl))
+               cl = clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
+       if (!IS_ERR(cl))
+               cl = clk_register_clkdev(clk_table[MUX_CLKOUT0],
                                          "clkout0", NULL);
-       if (!ret)
-               ret = clk_register_clkdev(clk_table[MUX_CLKOUT1],
+       if (!IS_ERR(cl))
+               cl = clk_register_clkdev(clk_table[MUX_CLKOUT1],
                                          "clkout1", NULL);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register aliases, %d\n", ret);
+       if (IS_ERR(cl)) {
+               dev_err(&pdev->dev, "failed to register aliases, %ld\n",
+                       PTR_ERR(cl));
                goto err_clk_register;
        }
 
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index 9e1f88c..eb52ab1 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -102,7 +102,8 @@ void __init samsung_clk_register_alias(struct 
samsung_clk_provider *ctx,
                                unsigned int nr_clk)
 {
        struct clk *clk;
-       unsigned int idx, ret;
+       struct clk_lookup *cl;
+       unsigned int idx;
 
        if (!ctx->clk_data.clks) {
                pr_err("%s: clock table missing\n", __func__);
@@ -123,8 +124,8 @@ void __init samsung_clk_register_alias(struct 
samsung_clk_provider *ctx,
                        continue;
                }
 
-               ret = clk_register_clkdev(clk, list->alias, list->dev_name);
-               if (ret)
+               cl = clk_register_clkdev(clk, list->alias, list->dev_name);
+               if (IS_ERR(cl))
                        pr_err("%s: failed to register lookup %s\n",
                                        __func__, list->alias);
        }
@@ -135,7 +136,8 @@ void __init samsung_clk_register_fixed_rate(struct 
samsung_clk_provider *ctx,
                struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
 {
        struct clk *clk;
-       unsigned int idx, ret;
+       struct clk_lookup *cl;
+       unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
                clk = clk_register_fixed_rate(NULL, list->name,
@@ -152,8 +154,8 @@ void __init samsung_clk_register_fixed_rate(struct 
samsung_clk_provider *ctx,
                 * Unconditionally add a clock lookup for the fixed rate clocks.
                 * There are not many of these on any of Samsung platforms.
                 */
-               ret = clk_register_clkdev(clk, list->name, NULL);
-               if (ret)
+               cl = clk_register_clkdev(clk, list->name, NULL);
+               if (IS_ERR(cl))
                        pr_err("%s: failed to register clock lookup for %s",
                                __func__, list->name);
        }
@@ -185,7 +187,8 @@ void __init samsung_clk_register_mux(struct 
samsung_clk_provider *ctx,
                                unsigned int nr_clk)
 {
        struct clk *clk;
-       unsigned int idx, ret;
+       struct clk_lookup *cl;
+       unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
                clk = clk_register_mux(NULL, list->name, list->parent_names,
@@ -202,9 +205,9 @@ void __init samsung_clk_register_mux(struct 
samsung_clk_provider *ctx,
 
                /* register a clock lookup only if a clock alias is specified */
                if (list->alias) {
-                       ret = clk_register_clkdev(clk, list->alias,
+                       cl = clk_register_clkdev(clk, list->alias,
                                                list->dev_name);
-                       if (ret)
+                       if (IS_ERR(cl))
                                pr_err("%s: failed to register lookup %s\n",
                                                __func__, list->alias);
                }
@@ -217,7 +220,8 @@ void __init samsung_clk_register_div(struct 
samsung_clk_provider *ctx,
                                unsigned int nr_clk)
 {
        struct clk *clk;
-       unsigned int idx, ret;
+       struct clk_lookup *cl;
+       unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
                if (list->table)
@@ -241,9 +245,9 @@ void __init samsung_clk_register_div(struct 
samsung_clk_provider *ctx,
 
                /* register a clock lookup only if a clock alias is specified */
                if (list->alias) {
-                       ret = clk_register_clkdev(clk, list->alias,
+                       cl = clk_register_clkdev(clk, list->alias,
                                                list->dev_name);
-                       if (ret)
+                       if (IS_ERR(cl))
                                pr_err("%s: failed to register lookup %s\n",
                                                __func__, list->alias);
                }
@@ -256,7 +260,8 @@ void __init samsung_clk_register_gate(struct 
samsung_clk_provider *ctx,
                                unsigned int nr_clk)
 {
        struct clk *clk;
-       unsigned int idx, ret;
+       struct clk_lookup *cl;
+       unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
                clk = clk_register_gate(NULL, list->name, list->parent_name,
@@ -270,9 +275,9 @@ void __init samsung_clk_register_gate(struct 
samsung_clk_provider *ctx,
 
                /* register a clock lookup only if a clock alias is specified */
                if (list->alias) {
-                       ret = clk_register_clkdev(clk, list->alias,
+                       cl = clk_register_clkdev(clk, list->alias,
                                                        list->dev_name);
-                       if (ret)
+                       if (IS_ERR(cl))
                                pr_err("%s: failed to register lookup %s\n",
                                        __func__, list->alias);
                }
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index 94bad77..87ace2c 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -40,7 +40,7 @@ void clkdev_drop(struct clk_lookup *cl);
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, char *, struct device *);
 
-int clk_register_clkdev(struct clk *, const char *, const char *, ...);
+struct clk_lookup *clk_register_clkdev(struct clk *, const char *, const char 
*, ...);
 int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
 
 #ifdef CONFIG_COMMON_CLK
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to