From patchwork Thu Jun 13 01:48:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 2712981 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id E8E2CC1459 for ; Thu, 13 Jun 2013 01:50:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 110DC201F9 for ; Thu, 13 Jun 2013 01:50:58 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5067A201F0 for ; Thu, 13 Jun 2013 01:50:56 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Umwfm-0000v9-Kg; Thu, 13 Jun 2013 01:49:58 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Umwff-0005Mj-5w; Thu, 13 Jun 2013 01:49:51 +0000 Received: from smtp.codeaurora.org ([198.145.11.231]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UmwfO-0005Ix-C0 for linux-arm-kernel@lists.infradead.org; Thu, 13 Jun 2013 01:49:36 +0000 Received: from smtp.codeaurora.org (localhost [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id E5F8A13F106; Thu, 13 Jun 2013 01:49:13 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 486) id D8B1213F10C; Thu, 13 Jun 2013 01:49:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from sboyd-linux.qualcomm.com (i-global252.qualcomm.com [199.106.103.252]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: sboyd@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 166C713F106; Thu, 13 Jun 2013 01:49:13 +0000 (UTC) From: Stephen Boyd To: linux-arm-kernel@lists.infradead.org Subject: [RFC/PATCH 02/13] clk: Add of_init_clk_data() to parse common clock bindings Date: Wed, 12 Jun 2013 18:48:58 -0700 Message-Id: <1371088149-22562-3-git-send-email-sboyd@codeaurora.org> X-Mailer: git-send-email 1.8.3.1.378.g9926f66 In-Reply-To: <1371088149-22562-1-git-send-email-sboyd@codeaurora.org> References: <1371088149-22562-1-git-send-email-sboyd@codeaurora.org> X-Virus-Scanned: ClamAV using ClamSMTP X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130612_214934_631878_66F7E2A1 X-CRM114-Status: GOOD ( 25.59 ) X-Spam-Score: -2.1 (--) Cc: linux-arm-msm@vger.kernel.org, Saravana Kannan , Mike Turquette , linux-kernel@vger.kernel.org, Rob Herring X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Consolidate DT parsing for the common bits of a clock binding in one place to simplify clock drivers. This also has the added benefit of standardizing how the clock names used by the common clock framework are generated from the DT bindings. We always use the first clock-output-names string if it exists, otherwise we fall back to the node name. To be slightly more efficient and make the caller's life easier, we introduce a shallow copy flag so that the clock core knows to just copy the pointers to the strings and not the string contents. Otherwise the callers of this function would have to free the strings allocated here which could be cumbersome. Cc: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 59 +++++++++++++++++++++++++++++++++++++++++++- include/linux/clk-provider.h | 3 +++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 85b661d..282b10e 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1803,6 +1803,10 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) { int i, ret; + hw->clk = clk; + if (hw->init->flags & CLK_SHALLOW_COPY) + return PTR_RET(__clk_register(dev, hw)); + clk->name = kstrdup(hw->init->name, GFP_KERNEL); if (!clk->name) { pr_err("%s: could not allocate clk->name\n", __func__); @@ -1813,7 +1817,6 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) clk->hw = hw; clk->flags = hw->init->flags; clk->num_parents = hw->init->num_parents; - hw->clk = clk; /* allocate local copy in case parent_names is __initdata */ clk->parent_names = kzalloc((sizeof(char*) * clk->num_parents), @@ -2225,4 +2228,58 @@ void __init of_clk_init(const struct of_device_id *matches) clk_init_cb(np); } } + +/** + * of_init_clk_data() - Initialize a clk_init_data struct from a DT node + * @np: node to initialize struct from + * @init: struct to initialize + * + * Populates the clk_init_data struct by parsing the device node for + * properties matching the common clock binding. Returns 0 on success + * and a negative error code on failure. + */ +int of_init_clk_data(struct device_node *np, struct clk_init_data *init) +{ + struct of_phandle_args s; + const char **names = NULL, **p; + const char *name; + int i; + + if (of_property_read_string(np, "clock-output-names", &name) < 0) + name = np->name; + init->name = kstrdup(name, GFP_KERNEL); + if (!init->name) + return -ENOMEM; + + for (i = 0; of_parse_phandle_with_args(np, "clocks", "#clock-cells", + i, &s) == 0; i++) { + p = krealloc(names, sizeof(*names) * (i + 1), GFP_KERNEL); + if (!p) + goto err; + names = p; + + if (of_property_read_string(s.np, "clock-output-names", + &name) < 0) + name = s.np->name; + names[i] = kstrdup(name, GFP_KERNEL); + if (!names[i]) + goto err; + of_node_put(s.np); + } + + init->parent_names = names; + init->num_parents = i; + init->flags = init->num_parents ? 0 : CLK_IS_ROOT; + init->flags |= CLK_SHALLOW_COPY; + + return 0; +err: + of_node_put(s.np); + while (--i >= 0) + kfree(names[i]); + kfree(names); + kfree(init->name); + return -ENOMEM; +} +EXPORT_SYMBOL_GPL(of_init_clk_data); #endif diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index d6057eb..bdcc655 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -28,6 +28,7 @@ #define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ #define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ +#define CLK_SHALLOW_COPY BIT(8) /* don't copy the initdata strings */ struct clk_hw; @@ -451,6 +452,8 @@ const char *of_clk_get_parent_name(struct device_node *np, int index); void of_clk_init(const struct of_device_id *matches); +int of_init_clk_data(struct device_node *np, struct clk_init_data *init); + #define CLK_OF_DECLARE(name, compat, fn) \ static const struct of_device_id __clk_of_table_##name \ __used __section(__clk_of_table) \