[PATCH v4 1/1] clkdev: change prototype of clk_register_clkdev()
From: Andy Shevchenko
Date: Wed May 06 2015 - 06:24:40 EST
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.vizoso@xxxxxxxxxxxxx>
Reviewed-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx>
Acked-by: Sylwester Nawrocki <s.nawrocki@xxxxxxxxxxx>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/