From patchwork Wed Mar 7 21:20:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sascha Hauer X-Patchwork-Id: 7138 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id A983723E76 for ; Wed, 7 Mar 2012 21:21:01 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 72A74A1852B for ; Wed, 7 Mar 2012 21:21:01 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id e36so12283422iag.11 for ; Wed, 07 Mar 2012 13:21:01 -0800 (PST) Received: by 10.42.145.72 with SMTP id e8mr2294920icv.0.1331155261216; Wed, 07 Mar 2012 13:21:01 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.53.18 with SMTP id k18csp22491ibg; Wed, 7 Mar 2012 13:21:00 -0800 (PST) Received: by 10.180.103.35 with SMTP id ft3mr6993345wib.0.1331155259157; Wed, 07 Mar 2012 13:20:59 -0800 (PST) Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de. [92.198.50.35]) by mx.google.com with ESMTPS id g7si19608036wee.59.2012.03.07.13.20.58 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 07 Mar 2012 13:20:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of sha@pengutronix.de designates 92.198.50.35 as permitted sender) client-ip=92.198.50.35; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of sha@pengutronix.de designates 92.198.50.35 as permitted sender) smtp.mail=sha@pengutronix.de Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1S5OHd-0005n3-Uu; Wed, 07 Mar 2012 22:20:29 +0100 Received: from sha by dude.hi.pengutronix.de with local (Exim 4.77) (envelope-from ) id 1S5OHZ-0004Kf-Gf; Wed, 07 Mar 2012 22:20:25 +0100 Date: Wed, 7 Mar 2012 22:20:25 +0100 From: Sascha Hauer To: Mike Turquette Cc: Russell King , Andrew Lunn , linaro-dev@lists.linaro.org, Grant Likely , Saravana Kannan , Jamie Iles , Jeremy Kerr , Mike Turquette , Magnus Damm , Deepak Saxena , linux-arm-kernel@lists.infradead.org, Arnd Bergman , patches@linaro.org, Rob Herring , Thomas Gleixner , Richard Zhao , Shawn Guo , Paul Walmsley , Linus Walleij , Mark Brown , Stephen Boyd , linux-kernel@vger.kernel.org, Amit Kucheria Subject: Re: [PATCH v5 4/4] clk: basic clock hardware types Message-ID: <20120307212025.GC26882@pengutronix.de> References: <1330763341-3437-1-git-send-email-mturquette@linaro.org> <1330763341-3437-5-git-send-email-mturquette@linaro.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1330763341-3437-5-git-send-email-mturquette@linaro.org> X-Sent-From: Pengutronix Hildesheim X-URL: http://www.pengutronix.de/ X-IRC: #ptxdist @freenode X-Accept-Language: de,en X-Accept-Content-Type: text/plain X-Uptime: 22:15:48 up 116 days, 5:02, 29 users, load average: 0.00, 0.07, 0.11 User-Agent: Mutt/1.5.21 (2010-09-15) X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: sha@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: patches@linaro.org X-Gm-Message-State: ALoCoQmZ7JA18G/Tn2I7lyC7ZqbHbKHzOp8LRNx5B9IabuhOrpdVhe+TSSFGT/qCO9lXcbmjEFaW On Sat, Mar 03, 2012 at 12:29:01AM -0800, Mike Turquette wrote: > +struct clk *clk_register_divider(struct device *dev, const char *name, > + const char *parent_name, unsigned long flags, > + void __iomem *reg, u8 shift, u8 width, > + u8 clk_divider_flags, spinlock_t *lock) > +{ > + struct clk_divider *div; > + char **parent_names = NULL; > + u8 len; > + > + div = kmalloc(sizeof(struct clk_divider), GFP_KERNEL); > + > + if (!div) { > + pr_err("%s: could not allocate divider clk\n", __func__); > + return ERR_PTR(-ENOMEM); > + } > + > + /* struct clk_divider assignments */ > + div->reg = reg; > + div->shift = shift; > + div->width = width; > + div->flags = clk_divider_flags; > + div->lock = lock; > + > + if (parent_name) { > + parent_names = kmalloc(sizeof(char *), GFP_KERNEL); > + > + if (! parent_names) > + goto out; > + > + len = sizeof(char) * strlen(parent_name); > + > + parent_names[0] = kmalloc(len, GFP_KERNEL); > + > + if (!parent_names[0]) > + goto out; > + > + strncpy(parent_names[0], parent_name, len); > + } > + > +out: > + return clk_register(dev, name, > + &clk_divider_ops, &div->hw, > + parent_names, > + (parent_name ? 1 : 0), > + flags); > +} clk_register_divider and also clk_register_gate have some problems. First you allocate memory with exactly the string length without the terminating 0. Then the functions leak memory when clk_register fails. Could you fold in the following patch to fix this? Sascha 8<-------------------------------------------------- fix divider/gate registration Signed-off-by: Sascha Hauer --- drivers/clk/clk-divider.c | 34 +++++++++++++++------------------- drivers/clk/clk-gate.c | 33 ++++++++++++++------------------- include/linux/clk-provider.h | 2 ++ 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 8f02930..99b6b55 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -156,14 +156,13 @@ struct clk *clk_register_divider(struct device *dev, const char *name, u8 clk_divider_flags, spinlock_t *lock) { struct clk_divider *div; - char **parent_names = NULL; - u8 len; + struct clk *clk; - div = kmalloc(sizeof(struct clk_divider), GFP_KERNEL); + div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); if (!div) { pr_err("%s: could not allocate divider clk\n", __func__); - return ERR_PTR(-ENOMEM); + return NULL; } /* struct clk_divider assignments */ @@ -174,25 +173,22 @@ struct clk *clk_register_divider(struct device *dev, const char *name, div->lock = lock; if (parent_name) { - parent_names = kmalloc(sizeof(char *), GFP_KERNEL); - - if (! parent_names) - goto out; - - len = sizeof(char) * strlen(parent_name); - - parent_names[0] = kmalloc(len, GFP_KERNEL); - - if (!parent_names[0]) + div->parent[0] = kstrdup(parent_name, GFP_KERNEL); + if (!div->parent[0]) goto out; - - strncpy(parent_names[0], parent_name, len); } -out: - return clk_register(dev, name, + clk = clk_register(dev, name, &clk_divider_ops, &div->hw, - parent_names, + div->parent, (parent_name ? 1 : 0), flags); + if (clk) + return clk; + +out: + kfree(div->parent[0]); + kfree(div); + + return NULL; } diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index e831f7b..92c0489 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -80,14 +80,13 @@ struct clk *clk_register_gate(struct device *dev, const char *name, u8 clk_gate_flags, spinlock_t *lock) { struct clk_gate *gate; - char **parent_names = NULL; - u8 len; + struct clk *clk; - gate = kmalloc(sizeof(struct clk_gate), GFP_KERNEL); + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); if (!gate) { pr_err("%s: could not allocate gated clk\n", __func__); - return ERR_PTR(-ENOMEM); + return NULL; } /* struct clk_gate assignments */ @@ -97,25 +96,21 @@ struct clk *clk_register_gate(struct device *dev, const char *name, gate->lock = lock; if (parent_name) { - parent_names = kmalloc(sizeof(char *), GFP_KERNEL); - - if (! parent_names) - goto out; - - len = sizeof(char) * strlen(parent_name); - - parent_names[0] = kmalloc(len, GFP_KERNEL); - - if (!parent_names[0]) + gate->parent[0] = kstrdup(parent_name, GFP_KERNEL); + if (!gate->parent[0]) goto out; - - strncpy(parent_names[0], parent_name, len); } -out: - return clk_register(dev, name, + clk = clk_register(dev, name, &clk_gate_ops, &gate->hw, - parent_names, + gate->parent, (parent_name ? 1 : 0), flags); + if (clk) + return clk; +out: + kfree(gate->parent[0]); + kfree(gate); + + return NULL; } diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 9b7dd5e..ed1f918 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -174,6 +174,7 @@ struct clk_gate { u8 bit_idx; u8 flags; spinlock_t *lock; + char *parent[1]; }; #define CLK_GATE_SET_TO_DISABLE BIT(0) @@ -210,6 +211,7 @@ struct clk_divider { u8 width; u8 flags; spinlock_t *lock; + char *parent[1]; }; #define CLK_DIVIDER_ONE_BASED BIT(0)