From patchwork Mon Jul 30 08:36:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Edworthy X-Patchwork-Id: 10548749 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6037A13BB for ; Mon, 30 Jul 2018 08:36:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 52CFD29979 for ; Mon, 30 Jul 2018 08:36:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 46971299A8; Mon, 30 Jul 2018 08:36:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC17429979 for ; Mon, 30 Jul 2018 08:36:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726573AbeG3KK0 (ORCPT ); Mon, 30 Jul 2018 06:10:26 -0400 Received: from relmlor3.renesas.com ([210.160.252.173]:57931 "EHLO relmlie2.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726520AbeG3KK0 (ORCPT ); Mon, 30 Jul 2018 06:10:26 -0400 Received: from unknown (HELO relmlir2.idc.renesas.com) ([10.200.68.152]) by relmlie2.idc.renesas.com with ESMTP; 30 Jul 2018 17:36:31 +0900 Received: from relmlii2.idc.renesas.com (relmlii2.idc.renesas.com [10.200.68.66]) by relmlir2.idc.renesas.com (Postfix) with ESMTP id BD09784630; Mon, 30 Jul 2018 17:36:28 +0900 (JST) X-IronPort-AV: E=Sophos;i="5.51,422,1526310000"; d="scan'208";a="288300616" Received: from unknown (HELO vbox.ree.adwin.renesas.com) ([10.226.37.67]) by relmlii2.idc.renesas.com with ESMTP; 30 Jul 2018 17:36:25 +0900 From: Phil Edworthy To: Michael Turquette , Stephen Boyd , Russell King Cc: Geert Uytterhoeven , Simon Horman , Andy Shevchenko , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Phil Edworthy Subject: [PATCH v2 1/2] clk: Add of_clk_get_by_name_optional() function Date: Mon, 30 Jul 2018 09:36:07 +0100 Message-Id: <1532939768-7018-2-git-send-email-phil.edworthy@renesas.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1532939768-7018-1-git-send-email-phil.edworthy@renesas.com> References: <1532939768-7018-1-git-send-email-phil.edworthy@renesas.com> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Quite a few drivers get an optional clock, e.g. a clock required to access peripheral's registers that is always enabled on some devices. This function behaves the same as of_clk_get_by_name() except that it will return NULL instead of -ENOENT. This makes error checking for users easier and allows clk_prepare_enable, etc to be called on the returned reference without additional checks. Signed-off-by: Phil Edworthy --- drivers/clk/clkdev.c | 34 ++++++++++++++++++++++++++++++---- include/linux/clk.h | 1 + 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 9ab3db8..c1b7262 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get); static struct clk *__of_clk_get_by_name(struct device_node *np, const char *dev_id, - const char *name) + const char *name, + bool optional) { struct clk *clk = ERR_PTR(-ENOENT); @@ -73,6 +74,8 @@ static struct clk *__of_clk_get_by_name(struct device_node *np, if (!IS_ERR(clk)) { break; } else if (name && index >= 0) { + if (optional && PTR_ERR(clk) == -ENOENT) + clk = NULL; if (PTR_ERR(clk) != -EPROBE_DEFER) pr_err("ERROR: could not get clock %pOF:%s(%i)\n", np, name ? name : "", index); @@ -106,15 +109,38 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name) if (!np) return ERR_PTR(-ENOENT); - return __of_clk_get_by_name(np, np->full_name, name); + return __of_clk_get_by_name(np, np->full_name, name, false); } EXPORT_SYMBOL(of_clk_get_by_name); +/** + * of_clk_get_by_name_optional() - Parse and lookup an optional clock referenced + * by a device node + * @np: pointer to clock consumer node + * @name: name of consumer's clock input, or NULL for the first clock reference + * + * This function parses the clocks and clock-names properties, + * and uses them to look up the struct clk from the registered list of clock + * providers. + * It behaves the same as of_clk_get_by_name(), except when no clock is found. + * In this case, instead of returning -ENOENT, it returns NULL. + */ +struct clk *of_clk_get_by_name_optional(struct device_node *np, + const char *name) +{ + if (!np) + return ERR_PTR(-ENOENT); + + return __of_clk_get_by_name(np, np->full_name, name, true); +} +EXPORT_SYMBOL(of_clk_get_by_name_optional); + #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */ static struct clk *__of_clk_get_by_name(struct device_node *np, const char *dev_id, - const char *name) + const char *name, + bool optional) { return ERR_PTR(-ENOENT); } @@ -197,7 +223,7 @@ struct clk *clk_get(struct device *dev, const char *con_id) struct clk *clk; if (dev && dev->of_node) { - clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id); + clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false); if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) return clk; } diff --git a/include/linux/clk.h b/include/linux/clk.h index 4f750c4..8cb5455 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -777,6 +777,7 @@ static inline void clk_bulk_disable_unprepare(int num_clks, #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) struct clk *of_clk_get(struct device_node *np, int index); struct clk *of_clk_get_by_name(struct device_node *np, const char *name); +struct clk *of_clk_get_by_name_optional(struct device_node *np, const char *name); struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec); #else static inline struct clk *of_clk_get(struct device_node *np, int index)