From patchwork Fri Apr 12 18:31:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899003 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 7A96817E1 for ; Fri, 12 Apr 2019 18:31:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5BE9D28EB6 for ; Fri, 12 Apr 2019 18:31:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D4CA2879E; Fri, 12 Apr 2019 18:31:53 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 E04E22879E for ; Fri, 12 Apr 2019 18:31:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726907AbfDLSbw (ORCPT ); Fri, 12 Apr 2019 14:31:52 -0400 Received: from mail.kernel.org ([198.145.29.99]:50318 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726905AbfDLSbw (ORCPT ); Fri, 12 Apr 2019 14:31:52 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8F938218CD; Fri, 12 Apr 2019 18:31:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093912; bh=HyBqBJLbHWUeQWX+cb/C4Wl/25IHsJuOK2Xzn81HSvM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QMXmOtwPTjD3kYgTbLxwvmjtmR2Oh8CWSUl52Dngr7bq+iyhKqnvaIxOIzVXhv7gL ms0+qyKR37MOnzXVeYeWvB+fShmPKMgL01WWk+/PJhMRyKyUMhzNA1v/bOjJ7YB9/h GAeJxlt3FdmcRWL0LXoXEFIfJa4Zqdnsm9Rc1zac= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai , Matti Vaittinen Subject: [PATCH v4 1/9] clkdev: Hold clocks_mutex while iterating clocks list Date: Fri, 12 Apr 2019 11:31:42 -0700 Message-Id: <20190412183150.102131-2-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 We recently introduced a change to support devm clk lookups. That change introduced a code-path that used clk_find() without holding the 'clocks_mutex'. Unfortunately, clk_find() iterates over the 'clocks' list and so we need to prevent the list from being modified at the same time. Do this by holding the mutex and checking to make sure it's held while iterating the list. Note, we don't really care if the lookup is freed after we find it with clk_find() because we're just doing a pointer comparison, but if we did care we would need to keep holding the mutex while we dereference the clk_lookup pointer. Fixes: 3eee6c7d119c ("clkdev: add managed clkdev lookup registration") Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Cc: Matti Vaittinen Signed-off-by: Stephen Boyd Acked-By: Matti Vaittinen --- I plan to take this through clk-fixes for v5.1-rc series. drivers/clk/clkdev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 8c4435c53f09..6e787cc9e5b9 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -46,6 +46,8 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) if (con_id) best_possible += 1; + lockdep_assert_held(&clocks_mutex); + list_for_each_entry(p, &clocks, node) { match = 0; if (p->dev_id) { @@ -402,7 +404,10 @@ void devm_clk_release_clkdev(struct device *dev, const char *con_id, struct clk_lookup *cl; int rval; + mutex_lock(&clocks_mutex); cl = clk_find(dev_id, con_id); + mutex_unlock(&clocks_mutex); + WARN_ON(!cl); rval = devres_release(dev, devm_clkdev_release, devm_clk_match_clkdev, cl); From patchwork Fri Apr 12 18:31:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899015 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 1FCE71515 for ; Fri, 12 Apr 2019 18:32:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0634328EB6 for ; Fri, 12 Apr 2019 18:32:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EECBE28EC7; Fri, 12 Apr 2019 18:32:32 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 71EB628EB6 for ; Fri, 12 Apr 2019 18:32:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727019AbfDLSbx (ORCPT ); Fri, 12 Apr 2019 14:31:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:50334 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726914AbfDLSbx (ORCPT ); Fri, 12 Apr 2019 14:31:53 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 26064218C3; Fri, 12 Apr 2019 18:31:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093912; bh=9nrE2eN80xxKdJ9WieNmrYl4QLOjjhrAG6XUmVRgGZo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DclFyroe13Qb1lWk3Qx7ERAxnNpTSQ0uc2RtGeQxHrgB+l7h7OArWZ0ydeVjIAZ10 woko8Z0r7yUL+hrH2NsIqPX4R0FwtASEo2c8h9aJyblqCrMUtcGl7amsJcCW032pEI FA5H72WRpQs89ZhySCLtBBiVQCz9nUFkL2rgNMd4= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai Subject: [PATCH v4 2/9] clkdev: Move clk creation outside of 'clocks_mutex' Date: Fri, 12 Apr 2019 11:31:43 -0700 Message-Id: <20190412183150.102131-3-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 We don't need to hold the 'clocks_mutex' here when we're creating a clk pointer from a clk_lookup structure. Instead, we just need to make sure that the lookup doesn't go away while we dereference the lookup pointer to extract the clk_hw pointer out of it. Let's move things around slightly so that we have a new function to get the clk_hw out of the lookup with the right locking and then chain the two together for what used to be __clk_get_sys(). Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Signed-off-by: Stephen Boyd --- drivers/clk/clkdev.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 6e787cc9e5b9..6f65bde696da 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -72,25 +72,26 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) return cl; } -static struct clk *__clk_get_sys(struct device *dev, const char *dev_id, - const char *con_id) +static struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id) { struct clk_lookup *cl; - struct clk *clk = NULL; + struct clk_hw *hw = ERR_PTR(-ENOENT); mutex_lock(&clocks_mutex); - cl = clk_find(dev_id, con_id); - if (!cl) - goto out; - - clk = clk_hw_create_clk(dev, cl->clk_hw, dev_id, con_id); - if (IS_ERR(clk)) - cl = NULL; -out: + if (cl) + hw = cl->clk_hw; mutex_unlock(&clocks_mutex); - return cl ? clk : ERR_PTR(-ENOENT); + return hw; +} + +static struct clk *__clk_get_sys(struct device *dev, const char *dev_id, + const char *con_id) +{ + struct clk_hw *hw = clk_find_hw(dev_id, con_id); + + return clk_hw_create_clk(dev, hw, dev_id, con_id); } struct clk *clk_get_sys(const char *dev_id, const char *con_id) From patchwork Fri Apr 12 18:31:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899019 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 95D8317E6 for ; Fri, 12 Apr 2019 18:32:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7DCED2879E for ; Fri, 12 Apr 2019 18:32:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7074F28EC6; Fri, 12 Apr 2019 18:32: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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 AB39A2879E for ; Fri, 12 Apr 2019 18:32:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727027AbfDLSc0 (ORCPT ); Fri, 12 Apr 2019 14:32:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:50350 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726905AbfDLSby (ORCPT ); Fri, 12 Apr 2019 14:31:54 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8DF4B218D2; Fri, 12 Apr 2019 18:31:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093912; bh=LZEUR8eiDUJq7nEmBI5Ou+kM+A9lWl2yePObSye2+60=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OHIBg7Hr26kVcuqViykm27cU+gZ4JgCKm1JSMHqjON69ChBm+n22PvKxW4PaZrr7U 5j6424nGaxkdl6wf5s9Zwa9v+3J/dfJ17MTnHQaxlqfryMQRYrlpg1gxpH1WxdtPED iDKYVEMW5/sWeRNpvDpqKlBxOm3QyZYLxx8mQir8= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai , Rob Herring Subject: [PATCH v4 3/9] clk: Prepare for clk registration API that uses DT nodes Date: Fri, 12 Apr 2019 11:31:44 -0700 Message-Id: <20190412183150.102131-4-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 Split out the body of the clk_register() function so it can be shared between the different types of registration APIs (DT, device). Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Cc: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 96053a96fe2f..d27775a73e67 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3313,18 +3313,7 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, return clk; } -/** - * clk_register - allocate a new clock, register it and return an opaque cookie - * @dev: device that is registering this clock - * @hw: link to hardware-specific clock data - * - * clk_register is the primary interface for populating the clock tree with new - * clock nodes. It returns a pointer to the newly allocated struct clk which - * cannot be dereferenced by driver code but may be used in conjunction with the - * rest of the clock API. In the event of an error clk_register will return an - * error code; drivers must test for an error code after calling clk_register. - */ -struct clk *clk_register(struct device *dev, struct clk_hw *hw) +static struct clk *__clk_register(struct device *dev, struct clk_hw *hw) { int i, ret; struct clk_core *core; @@ -3426,6 +3415,22 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) fail_out: return ERR_PTR(ret); } + +/** + * clk_register - allocate a new clock, register it and return an opaque cookie + * @dev: device that is registering this clock + * @hw: link to hardware-specific clock data + * + * clk_register is the primary interface for populating the clock tree with new + * clock nodes. It returns a pointer to the newly allocated struct clk which + * cannot be dereferenced by driver code but may be used in conjunction with the + * rest of the clock API. In the event of an error clk_register will return an + * error code; drivers must test for an error code after calling clk_register. + */ +struct clk *clk_register(struct device *dev, struct clk_hw *hw) +{ + return __clk_register(dev, hw); +} EXPORT_SYMBOL_GPL(clk_register); /** @@ -3440,7 +3445,7 @@ EXPORT_SYMBOL_GPL(clk_register); */ int clk_hw_register(struct device *dev, struct clk_hw *hw) { - return PTR_ERR_OR_ZERO(clk_register(dev, hw)); + return PTR_ERR_OR_ZERO(__clk_register(dev, hw)); } EXPORT_SYMBOL_GPL(clk_hw_register); From patchwork Fri Apr 12 18:31:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899017 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 689D217E1 for ; Fri, 12 Apr 2019 18:32:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4887028EB6 for ; Fri, 12 Apr 2019 18:32:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3CE5828EC4; Fri, 12 Apr 2019 18:32:33 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 C3C3828EC2 for ; Fri, 12 Apr 2019 18:32:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727253AbfDLScc (ORCPT ); Fri, 12 Apr 2019 14:32:32 -0400 Received: from mail.kernel.org ([198.145.29.99]:50366 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726998AbfDLSbx (ORCPT ); Fri, 12 Apr 2019 14:31:53 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 07613218E2; Fri, 12 Apr 2019 18:31:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093913; bh=Lu/9VefXJAzydhxIjej1T+ELCdL9m/fzpv8TsunMCNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QvPLFGT1GXjOboeqPPBAcckRG30U7zHLFyGRg25ud38AwbhLZXd+ikeM5hKtX6JPH 7Uv5aBBMHFZMZ75QzI+OfTsIqt9AXYoe7fkrdrkyzbN9vnPQz4FJiGti4i/6Rg9L5B LUNtqbaZpK02JuyCx2OdHXWRriPk8GSwuM5omh4c= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai , Greg Kroah-Hartman , Rob Herring Subject: [PATCH v4 4/9] driver core: Let dev_of_node() accept a NULL dev Date: Fri, 12 Apr 2019 11:31:45 -0700 Message-Id: <20190412183150.102131-5-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 We'd like to chain this in places where the 'dev' argument might be NULL. Let this function take a NULL 'dev' so this can work. Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Cc: Greg Kroah-Hartman Cc: Rob Herring Signed-off-by: Stephen Boyd Acked-by: Greg Kroah-Hartman --- Please ack/review so I can take this through clk tree. include/linux/device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/device.h b/include/linux/device.h index b425a7ee04ce..0370dd0b3ae7 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1231,7 +1231,7 @@ static inline void device_lock_assert(struct device *dev) static inline struct device_node *dev_of_node(struct device *dev) { - if (!IS_ENABLED(CONFIG_OF)) + if (!IS_ENABLED(CONFIG_OF) || !dev) return NULL; return dev->of_node; } From patchwork Fri Apr 12 18:31:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899013 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 B225517E1 for ; Fri, 12 Apr 2019 18:32:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8B2EE2879E for ; Fri, 12 Apr 2019 18:32:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F7CB28EC2; Fri, 12 Apr 2019 18:32:26 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 58E9C2879E for ; Fri, 12 Apr 2019 18:32:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727206AbfDLScU (ORCPT ); Fri, 12 Apr 2019 14:32:20 -0400 Received: from mail.kernel.org ([198.145.29.99]:50396 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727027AbfDLSby (ORCPT ); Fri, 12 Apr 2019 14:31:54 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 7BD47218FC; Fri, 12 Apr 2019 18:31:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093913; bh=zLRmPqxlLQc3AN/GbT8QG3oWhXh1GCS3AdlYegAqcRo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p9JmaqpgtwWfs0Y/DwXacpg/lotkuQDpJdkfcMMeA3b2fWgi6i4coXaYPZQwBbWKV N3U6MLwCW5qdbi+59iWg6F15dt+XhA4a9Y+49CWjhYYkLmB6wosFgGD8lBRZ+bvceA KCWy7PnvXORvl31kpYlmRcHTcltX3dWGgGjbdOos= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai , Rob Herring Subject: [PATCH v4 5/9] clk: Add of_clk_hw_register() API for early clk drivers Date: Fri, 12 Apr 2019 11:31:46 -0700 Message-Id: <20190412183150.102131-6-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 In some circumstances drivers register clks early and don't have access to a struct device because the device model isn't initialized yet. Add an API to let drivers register clks associated with a struct device_node so that these drivers can participate in getting parent clks through DT. Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Cc: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 26 +++++++++++++++++++++++--- include/linux/clk-provider.h | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d27775a73e67..ffa63ddcd408 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -45,6 +45,7 @@ struct clk_core { struct clk_hw *hw; struct module *owner; struct device *dev; + struct device_node *of_node; struct clk_core *parent; const char **parent_names; struct clk_core **parents; @@ -3313,7 +3314,8 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, return clk; } -static struct clk *__clk_register(struct device *dev, struct clk_hw *hw) +static struct clk * +__clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) { int i, ret; struct clk_core *core; @@ -3339,6 +3341,7 @@ static struct clk *__clk_register(struct device *dev, struct clk_hw *hw) if (dev && pm_runtime_enabled(dev)) core->rpm_enabled = true; core->dev = dev; + core->of_node = np; if (dev && dev->driver) core->owner = dev->driver->owner; core->hw = hw; @@ -3429,7 +3432,7 @@ static struct clk *__clk_register(struct device *dev, struct clk_hw *hw) */ struct clk *clk_register(struct device *dev, struct clk_hw *hw) { - return __clk_register(dev, hw); + return __clk_register(dev, dev_of_node(dev), hw); } EXPORT_SYMBOL_GPL(clk_register); @@ -3445,10 +3448,27 @@ EXPORT_SYMBOL_GPL(clk_register); */ int clk_hw_register(struct device *dev, struct clk_hw *hw) { - return PTR_ERR_OR_ZERO(__clk_register(dev, hw)); + return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw)); } EXPORT_SYMBOL_GPL(clk_hw_register); +/* + * of_clk_hw_register - register a clk_hw and return an error code + * @node: device_node of device that is registering this clock + * @hw: link to hardware-specific clock data + * + * of_clk_hw_register() is the primary interface for populating the clock tree + * with new clock nodes when a struct device is not available, but a struct + * device_node is. It returns an integer equal to zero indicating success or + * less than zero indicating failure. Drivers must test for an error code after + * calling of_clk_hw_register(). + */ +int of_clk_hw_register(struct device_node *node, struct clk_hw *hw) +{ + return PTR_ERR_OR_ZERO(__clk_register(NULL, node, hw)); +} +EXPORT_SYMBOL_GPL(of_clk_hw_register); + /* Free memory allocated for a clock. */ static void __clk_release(struct kref *ref) { diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index b7cf80a71293..7d2d97e15b76 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -773,6 +773,7 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw); int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw); int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw); +int __must_check of_clk_hw_register(struct device_node *node, struct clk_hw *hw); void clk_unregister(struct clk *clk); void devm_clk_unregister(struct device *dev, struct clk *clk); From patchwork Fri Apr 12 18:31:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899011 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 4E36B17E1 for ; Fri, 12 Apr 2019 18:32:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2DEC02879E for ; Fri, 12 Apr 2019 18:32:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 21BEF28EC2; Fri, 12 Apr 2019 18:32:16 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 F14F72879E for ; Fri, 12 Apr 2019 18:32:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727097AbfDLScO (ORCPT ); Fri, 12 Apr 2019 14:32:14 -0400 Received: from mail.kernel.org ([198.145.29.99]:50366 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727039AbfDLSbz (ORCPT ); Fri, 12 Apr 2019 14:31:55 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E8BAB218FE; Fri, 12 Apr 2019 18:31:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093914; bh=Hbes9ifb4OQdMNC/EuNRhWkJSSBV5O3Ajl4yOoxXj8g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qdPJTYNvgjK8x/lHCdgSSltUyjL+T3JG9nt+cC85vgOb0a2Tcc1aDKs8B/GuSuKTO b/dpuzH3Ha9YOFY+Y8pwyIxlAnXodiB9/KAO0C0MUpeqieJmTr2M+xdh/bTNh58wQ2 e8MIo+6Wbdt/edZwdO9qiAYS+z8yMrfw0Eq+ayJ8= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai , Rob Herring Subject: [PATCH v4 6/9] clk: Allow parents to be specified without string names Date: Fri, 12 Apr 2019 11:31:47 -0700 Message-Id: <20190412183150.102131-7-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 The common clk framework is lacking in ability to describe the clk topology without specifying strings for every possible parent-child link. There are a few drawbacks to the current approach: 1) String comparisons are used for everything, including describing topologies that are 'local' to a single clock controller. 2) clk providers (e.g. i2c clk drivers) need to create globally unique clk names to avoid collisions in the clk namespace, leading to awkward name generation code in various clk drivers. 3) DT bindings may not fully describe the clk topology and linkages between clk controllers because drivers can easily rely on globally unique strings to describe connections between clks. This leads to confusing DT bindings, complicated clk name generation code, and inefficient string comparisons during clk registration just so that the clk framework can detect the topology of the clk tree. Furthermore, some drivers call clk_get() and then __clk_get_name() to extract the globally unique clk name just so they can specify the parent of the clk they're registering. We have of_clk_parent_fill() but that mostly only works for single clks registered from a DT node, which isn't the norm. Let's simplify this all by introducing two new ways of specifying clk parents. The first method is an array of pointers to clk_hw structures corresponding to the parents at that index. This works for clks that are registered when we have access to all the clk_hw pointers for the parents. The second method is a mix of clk_hw pointers and strings of local and global parent clk names. If the .fw_name member of the map is set we'll look for that clk by performing a DT based lookup of the device the clk is registered with and the .name specified in the map. If that fails, we'll fallback to the .name member and perform a global clk name lookup like we've always done before. Using either one of these new methods is entirely optional. Existing drivers will continue to work, and they can migrate to this new approach as they see fit. Eventually, we'll want to get rid of the 'parent_names' array in struct clk_init_data and use one of these new methods instead. Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Cc: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 262 ++++++++++++++++++++++++++--------- include/linux/clk-provider.h | 19 +++ 2 files changed, 219 insertions(+), 62 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index ffa63ddcd408..de49a7c4214b 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -39,6 +39,13 @@ static LIST_HEAD(clk_notifier_list); /*** private data structures ***/ +struct clk_parent_map { + const struct clk_hw *hw; + struct clk_core *core; + const char *fw_name; + const char *name; +}; + struct clk_core { const char *name; const struct clk_ops *ops; @@ -47,8 +54,7 @@ struct clk_core { struct device *dev; struct device_node *of_node; struct clk_core *parent; - const char **parent_names; - struct clk_core **parents; + struct clk_parent_map *parents; u8 num_parents; u8 new_parent_index; unsigned long rate; @@ -317,17 +323,92 @@ static struct clk_core *clk_core_lookup(const char *name) return NULL; } +/** + * clk_core_get - Find the parent of a clk using a clock specifier in DT + * @core: clk to find parent of + * @name: name to search for in 'clock-names' of device providing clk + * + * This is the preferred method for clk providers to find the parent of a + * clk when that parent is external to the clk controller. The parent_names + * array is indexed and treated as a local name matching a string in the device + * node's 'clock-names' property. This allows clk providers to use their own + * namespace instead of looking for a globally unique parent string. + * + * For example the following DT snippet would allow a clock registered by the + * clock-controller@c001 that has a clk_init_data::parent_data array + * with 'xtal' in the 'name' member to find the clock provided by the + * clock-controller@f00abcd without needing to get the globally unique name of + * the xtal clk. + * + * parent: clock-controller@f00abcd { + * reg = <0xf00abcd 0xabcd>; + * #clock-cells = <0>; + * }; + * + * clock-controller@c001 { + * reg = <0xc001 0xf00d>; + * clocks = <&parent>; + * clock-names = "xtal"; + * #clock-cells = <1>; + * }; + * + * Returns: -ENOENT when the provider can't be found or the clk doesn't + * exist in the provider. -EINVAL when the name can't be found. NULL when the + * provider knows about the clk but it isn't provided on this system. + * A valid clk_core pointer when the clk can be found in the provider. + */ +static struct clk_core *clk_core_get(struct clk_core *core, const char *name) +{ + struct clk_hw *hw; + struct device_node *np = core->of_node; + + if (!np) + return ERR_PTR(-ENOENT); + + /* TODO: Support clkdev clk_lookups */ + hw = of_clk_get_hw(np, -1, name); + if (IS_ERR_OR_NULL(hw)) + return ERR_CAST(hw); + + return hw->core; +} + +static void clk_core_fill_parent_index(struct clk_core *core, u8 index) +{ + struct clk_parent_map *entry = &core->parents[index]; + struct clk_core *parent = ERR_PTR(-ENOENT); + + if (entry->hw) { + parent = entry->hw->core; + /* + * We have a direct reference but it isn't registered yet? Orphan it + * and let clk_reparent() update the orphan status when the parent + * is registered. + */ + if (!parent) + parent = ERR_PTR(-EPROBE_DEFER); + } else { + if (entry->fw_name) + parent = clk_core_get(core, entry->fw_name); + if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT) + parent = clk_core_lookup(entry->name); + } + + /* Only cache it if it's not an error */ + if (!IS_ERR(parent)) + entry->core = parent; +} + static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core, u8 index) { - if (!core || index >= core->num_parents) + if (!core || index >= core->num_parents || !core->parents) return NULL; - if (!core->parents[index]) - core->parents[index] = - clk_core_lookup(core->parent_names[index]); + if (!core->parents[index].core) + clk_core_fill_parent_index(core, index); - return core->parents[index]; + return core->parents[index].core; } struct clk_hw * @@ -1520,15 +1601,15 @@ static int clk_fetch_parent_index(struct clk_core *core, return -EINVAL; for (i = 0; i < core->num_parents; i++) { - if (core->parents[i] == parent) + if (core->parents[i].core == parent) return i; - if (core->parents[i]) + if (core->parents[i].core) continue; /* Fallback to comparing globally unique names */ - if (!strcmp(parent->name, core->parent_names[i])) { - core->parents[i] = parent; + if (!strcmp(parent->name, core->parents[i].name)) { + core->parents[i].core = parent; return i; } } @@ -2294,6 +2375,7 @@ void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent) bool clk_has_parent(struct clk *clk, struct clk *parent) { struct clk_core *core, *parent_core; + int i; /* NULL clocks should be nops, so return success if either is NULL. */ if (!clk || !parent) @@ -2306,8 +2388,11 @@ bool clk_has_parent(struct clk *clk, struct clk *parent) if (core->parent == parent_core) return true; - return match_string(core->parent_names, core->num_parents, - parent_core->name) >= 0; + for (i = 0; i < core->num_parents; i++) + if (!strcmp(core->parents[i].name, parent_core->name)) + return true; + + return false; } EXPORT_SYMBOL_GPL(clk_has_parent); @@ -2890,9 +2975,9 @@ static int possible_parents_show(struct seq_file *s, void *data) int i; for (i = 0; i < core->num_parents - 1; i++) - seq_printf(s, "%s ", core->parent_names[i]); + seq_printf(s, "%s ", core->parents[i].name); - seq_printf(s, "%s\n", core->parent_names[i]); + seq_printf(s, "%s\n", core->parents[i].name); return 0; } @@ -3026,7 +3111,7 @@ static inline void clk_debug_unregister(struct clk_core *core) */ static int __clk_core_init(struct clk_core *core) { - int i, ret; + int ret; struct clk_core *orphan; struct hlist_node *tmp2; unsigned long rate; @@ -3080,12 +3165,6 @@ static int __clk_core_init(struct clk_core *core) goto out; } - /* throw a WARN if any entries in parent_names are NULL */ - for (i = 0; i < core->num_parents; i++) - WARN(!core->parent_names[i], - "%s: invalid NULL in %s's .parent_names\n", - __func__, core->name); - core->parent = __clk_init_parent(core); /* @@ -3314,10 +3393,102 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, return clk; } +static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist) +{ + const char *dst; + + if (!src) { + if (must_exist) + return -EINVAL; + return 0; + } + + *dst_p = dst = kstrdup_const(src, GFP_KERNEL); + if (!dst) + return -ENOMEM; + + return 0; +} + +static int clk_core_populate_parent_map(struct clk_core *core) +{ + const struct clk_init_data *init = core->hw->init; + u8 num_parents = init->num_parents; + const char * const *parent_names = init->parent_names; + const struct clk_hw **parent_hws = init->parent_hws; + const struct clk_parent_data *parent_data = init->parent_data; + int i, ret = 0; + struct clk_parent_map *parents, *parent; + + if (!num_parents) + return 0; + + /* + * Avoid unnecessary string look-ups of clk_core's possible parents by + * having a cache of names/clk_hw pointers to clk_core pointers. + */ + parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL); + core->parents = parents; + if (!parents) + return -ENOMEM; + + /* Copy everything over because it might be __initdata */ + for (i = 0, parent = parents; i < num_parents; i++, parent++) { + if (parent_names) { + /* throw a WARN if any entries are NULL */ + WARN(!parent_names[i], + "%s: invalid NULL in %s's .parent_names\n", + __func__, core->name); + ret = clk_cpy_name(&parent->name, parent_names[i], + true); + } else if (parent_data) { + parent->hw = parent_data[i].hw; + ret = clk_cpy_name(&parent->fw_name, + parent_data[i].fw_name, false); + if (!ret) + ret = clk_cpy_name(&parent->name, + parent_data[i].name, + false); + } else if (parent_hws) { + parent->hw = parent_hws[i]; + } else { + ret = -EINVAL; + WARN(1, "Must specify parents if num_parents > 0\n"); + } + + if (ret) { + do { + kfree_const(parents[i].name); + kfree_const(parents[i].fw_name); + } while (--i >= 0); + kfree(parents); + + return ret; + } + } + + return 0; +} + +static void clk_core_free_parent_map(struct clk_core *core) +{ + int i = core->num_parents; + + if (!core->num_parents) + return; + + while (--i >= 0) { + kfree_const(core->parents[i].name); + kfree_const(core->parents[i].fw_name); + } + + kfree(core->parents); +} + static struct clk * __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) { - int i, ret; + int ret; struct clk_core *core; core = kzalloc(sizeof(*core), GFP_KERNEL); @@ -3351,33 +3522,9 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) core->max_rate = ULONG_MAX; hw->core = core; - /* allocate local copy in case parent_names is __initdata */ - core->parent_names = kcalloc(core->num_parents, sizeof(char *), - GFP_KERNEL); - - if (!core->parent_names) { - ret = -ENOMEM; - goto fail_parent_names; - } - - - /* copy each string name in case parent_names is __initdata */ - for (i = 0; i < core->num_parents; i++) { - core->parent_names[i] = kstrdup_const(hw->init->parent_names[i], - GFP_KERNEL); - if (!core->parent_names[i]) { - ret = -ENOMEM; - goto fail_parent_names_copy; - } - } - - /* avoid unnecessary string look-ups of clk_core's possible parents. */ - core->parents = kcalloc(core->num_parents, sizeof(*core->parents), - GFP_KERNEL); - if (!core->parents) { - ret = -ENOMEM; + ret = clk_core_populate_parent_map(core); + if (ret) goto fail_parents; - }; INIT_HLIST_HEAD(&core->clks); @@ -3388,7 +3535,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) hw->clk = alloc_clk(core, NULL, NULL); if (IS_ERR(hw->clk)) { ret = PTR_ERR(hw->clk); - goto fail_parents; + goto fail_create_clk; } clk_core_link_consumer(hw->core, hw->clk); @@ -3404,13 +3551,9 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) free_clk(hw->clk); hw->clk = NULL; +fail_create_clk: + clk_core_free_parent_map(core); fail_parents: - kfree(core->parents); -fail_parent_names_copy: - while (--i >= 0) - kfree_const(core->parent_names[i]); - kfree(core->parent_names); -fail_parent_names: fail_ops: kfree_const(core->name); fail_name: @@ -3473,15 +3616,10 @@ EXPORT_SYMBOL_GPL(of_clk_hw_register); static void __clk_release(struct kref *ref) { struct clk_core *core = container_of(ref, struct clk_core, ref); - int i = core->num_parents; lockdep_assert_held(&prepare_lock); - kfree(core->parents); - while (--i >= 0) - kfree_const(core->parent_names[i]); - - kfree(core->parent_names); + clk_core_free_parent_map(core); kfree_const(core->name); kfree(core); } diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7d2d97e15b76..95d5a9d4e8c3 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -250,6 +250,18 @@ struct clk_ops { void (*debug_init)(struct clk_hw *hw, struct dentry *dentry); }; +/** + * struct clk_parent_data - clk parent information + * @hw: parent clk_hw pointer (used for clk providers with internal clks) + * @fw_name: parent name local to provider registering clk + * @name: globally unique parent name (used as a fallback) + */ +struct clk_parent_data { + const struct clk_hw *hw; + const char *fw_name; + const char *name; +}; + /** * struct clk_init_data - holds init data that's common to all clocks and is * shared between the clock provider and the common clock framework. @@ -257,13 +269,20 @@ struct clk_ops { * @name: clock name * @ops: operations this clock supports * @parent_names: array of string names for all possible parents + * @parent_data: array of parent data for all possible parents (when some + * parents are external to the clk controller) + * @parent_hws: array of pointers to all possible parents (when all parents + * are internal to the clk controller) * @num_parents: number of possible parents * @flags: framework-level hints and quirks */ struct clk_init_data { const char *name; const struct clk_ops *ops; + /* Only one of the following three should be assigned */ const char * const *parent_names; + const struct clk_parent_data *parent_data; + const struct clk_hw **parent_hws; u8 num_parents; unsigned long flags; }; From patchwork Fri Apr 12 18:31:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899007 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 9E73117E1 for ; Fri, 12 Apr 2019 18:31:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 80FE12879E for ; Fri, 12 Apr 2019 18:31:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7566F28EC7; Fri, 12 Apr 2019 18:31:59 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 007D428EB6 for ; Fri, 12 Apr 2019 18:31:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727091AbfDLSb6 (ORCPT ); Fri, 12 Apr 2019 14:31:58 -0400 Received: from mail.kernel.org ([198.145.29.99]:50478 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727059AbfDLSbz (ORCPT ); Fri, 12 Apr 2019 14:31:55 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6DCFA218FF; Fri, 12 Apr 2019 18:31:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093914; bh=J/xGoKvpAn8VN6F0LRcxO6cDYVGFyNVvjKQEpBW6ETw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VBVd1KvYbclyKAO7npK8PM617+Ss03DjRysOi2b1hVNA0ZrNqpw7wlHtVoJCMdA9Q 0p4IxcYXtjrXRZ2TDdV0h8p6zVLh2rwnCL9Wdbrs42LFJ38LCBRoLw9qiL+NVjtDxg kjxJDzkM6Ep2j3nvP3vt6jGY3cBPZyvXNcUGGDpc= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai Subject: [PATCH v4 7/9] clk: Look for parents with clkdev based clk_lookups Date: Fri, 12 Apr 2019 11:31:48 -0700 Message-Id: <20190412183150.102131-8-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 In addition to looking for DT based parents, support clkdev based clk_lookups. This should allow non-DT based clk drivers to participate in the parent lookup process. Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 27 ++++++++++++++++++--------- drivers/clk/clk.h | 2 ++ drivers/clk/clkdev.c | 2 +- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index de49a7c4214b..42f29fd6bfd8 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -324,14 +324,15 @@ static struct clk_core *clk_core_lookup(const char *name) } /** - * clk_core_get - Find the parent of a clk using a clock specifier in DT + * clk_core_get - Find the clk_core parent of a clk * @core: clk to find parent of - * @name: name to search for in 'clock-names' of device providing clk + * @name: name to search for * * This is the preferred method for clk providers to find the parent of a * clk when that parent is external to the clk controller. The parent_names * array is indexed and treated as a local name matching a string in the device - * node's 'clock-names' property. This allows clk providers to use their own + * node's 'clock-names' property or as the 'con_id' matching the device's + * dev_name() in a clk_lookup. This allows clk providers to use their own * namespace instead of looking for a globally unique parent string. * * For example the following DT snippet would allow a clock registered by the @@ -359,15 +360,23 @@ static struct clk_core *clk_core_lookup(const char *name) */ static struct clk_core *clk_core_get(struct clk_core *core, const char *name) { - struct clk_hw *hw; + struct clk_hw *hw = ERR_PTR(-ENOENT); + struct device *dev = core->dev; + const char *dev_id = dev ? dev_name(dev) : NULL; struct device_node *np = core->of_node; - if (!np) - return ERR_PTR(-ENOENT); + if (np) + hw = of_clk_get_hw(np, -1, name); - /* TODO: Support clkdev clk_lookups */ - hw = of_clk_get_hw(np, -1, name); - if (IS_ERR_OR_NULL(hw)) + /* + * If the DT search above couldn't find the provider or the provider + * didn't know about this clk, fallback to looking up via clkdev based + * clk_lookups + */ + if (PTR_ERR(hw) == -ENOENT) + hw = clk_find_hw(dev_id, name); + + if (IS_ERR(hw)) return ERR_CAST(hw); return hw->core; diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 553f531cc232..d8400d623b34 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -19,6 +19,8 @@ static inline struct clk_hw *of_clk_get_hw(struct device_node *np, } #endif +struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id); + #ifdef CONFIG_COMMON_CLK struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id, const char *con_id); diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 6f65bde696da..2afc8df8acff 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -72,7 +72,7 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) return cl; } -static struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id) +struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id) { struct clk_lookup *cl; struct clk_hw *hw = ERR_PTR(-ENOENT); From patchwork Fri Apr 12 18:31:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899009 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 829B217E6 for ; Fri, 12 Apr 2019 18:31:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 677F428EC2 for ; Fri, 12 Apr 2019 18:31:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5BDFB28EC4; Fri, 12 Apr 2019 18:31:59 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 D3CB12879E for ; Fri, 12 Apr 2019 18:31:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727081AbfDLSb5 (ORCPT ); Fri, 12 Apr 2019 14:31:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:50350 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727065AbfDLSbz (ORCPT ); Fri, 12 Apr 2019 14:31:55 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D5849218D9; Fri, 12 Apr 2019 18:31:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093915; bh=jiLNbmEM7Idc3pt65bEuMUpgmufpjAZ+SN1eZ0ORQxQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iWs6oxVhXKz3fFxukKWnf06n7xo5ktMhKIBrgqEQmix2dt51VxdWw8zInpXBCPJow 0Bu04UTV+Yh6W88D236c7BgiZ88E+VnG6Tb7zVWrEmMUY+b/+HbuVeOSSbD2xQO8CT IO3GMq/XwqSl3c5JP3/CgFVDtHsuJyLdHySGm0nU= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai Subject: [PATCH v4 8/9] clk: Allow parents to be specified via clkspec index Date: Fri, 12 Apr 2019 11:31:49 -0700 Message-Id: <20190412183150.102131-9-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 Some clk providers are simple DT nodes that only have a 'clocks' property without having an associated 'clock-names' property. In these cases, we want to let these clk providers point to their parent clks without having to dereference the 'clocks' property at probe time to figure out the parent's globally unique clk name. Let's add an 'index' property to the parent_data structure so that clk providers can indicate that their parent is a particular index in the 'clocks' DT property. Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 18 +++++++++++------- include/linux/clk-provider.h | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 42f29fd6bfd8..65fe50b139ea 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -44,6 +44,7 @@ struct clk_parent_map { struct clk_core *core; const char *fw_name; const char *name; + int index; }; struct clk_core { @@ -326,7 +327,8 @@ static struct clk_core *clk_core_lookup(const char *name) /** * clk_core_get - Find the clk_core parent of a clk * @core: clk to find parent of - * @name: name to search for + * @name: name to search for (if string based) + * @index: index to use for search (if DT index based) * * This is the preferred method for clk providers to find the parent of a * clk when that parent is external to the clk controller. The parent_names @@ -358,22 +360,23 @@ static struct clk_core *clk_core_lookup(const char *name) * provider knows about the clk but it isn't provided on this system. * A valid clk_core pointer when the clk can be found in the provider. */ -static struct clk_core *clk_core_get(struct clk_core *core, const char *name) +static struct clk_core *clk_core_get(struct clk_core *core, const char *name, + int index) { struct clk_hw *hw = ERR_PTR(-ENOENT); struct device *dev = core->dev; const char *dev_id = dev ? dev_name(dev) : NULL; struct device_node *np = core->of_node; - if (np) - hw = of_clk_get_hw(np, -1, name); + if (np && index >= 0) + hw = of_clk_get_hw(np, index, name); /* * If the DT search above couldn't find the provider or the provider * didn't know about this clk, fallback to looking up via clkdev based * clk_lookups */ - if (PTR_ERR(hw) == -ENOENT) + if (PTR_ERR(hw) == -ENOENT && name) hw = clk_find_hw(dev_id, name); if (IS_ERR(hw)) @@ -397,8 +400,7 @@ static void clk_core_fill_parent_index(struct clk_core *core, u8 index) if (!parent) parent = ERR_PTR(-EPROBE_DEFER); } else { - if (entry->fw_name) - parent = clk_core_get(core, entry->fw_name); + parent = clk_core_get(core, entry->fw_name, entry->index); if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT) parent = clk_core_lookup(entry->name); } @@ -3443,6 +3445,7 @@ static int clk_core_populate_parent_map(struct clk_core *core) /* Copy everything over because it might be __initdata */ for (i = 0, parent = parents; i < num_parents; i++, parent++) { + parent->index = -1; if (parent_names) { /* throw a WARN if any entries are NULL */ WARN(!parent_names[i], @@ -3452,6 +3455,7 @@ static int clk_core_populate_parent_map(struct clk_core *core) true); } else if (parent_data) { parent->hw = parent_data[i].hw; + parent->index = parent_data[i].index; ret = clk_cpy_name(&parent->fw_name, parent_data[i].fw_name, false); if (!ret) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 95d5a9d4e8c3..12fef24b740f 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -255,11 +255,13 @@ struct clk_ops { * @hw: parent clk_hw pointer (used for clk providers with internal clks) * @fw_name: parent name local to provider registering clk * @name: globally unique parent name (used as a fallback) + * @index: parent index local to provider registering clk (if @fw_name absent) */ struct clk_parent_data { const struct clk_hw *hw; const char *fw_name; const char *name; + int index; }; /** From patchwork Fri Apr 12 18:31:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10899005 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 A5BF51515 for ; Fri, 12 Apr 2019 18:31:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C23C2879E for ; Fri, 12 Apr 2019 18:31:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F8EE28EC2; Fri, 12 Apr 2019 18:31:58 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 03AA82879E for ; Fri, 12 Apr 2019 18:31:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727079AbfDLSb5 (ORCPT ); Fri, 12 Apr 2019 14:31:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:50396 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727069AbfDLSb4 (ORCPT ); Fri, 12 Apr 2019 14:31:56 -0400 Received: from mail.kernel.org (unknown [104.132.0.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 476EA218FD; Fri, 12 Apr 2019 18:31:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555093915; bh=HcIechYl/c6FVy1DBpjkLY6E2a4oNKzK9h0x6CXvb6U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I5LVaitt0gaP9Kgq/jQq6EjSMNPxDolCIh2FYdQEkRl1dmXI1sr03GhxZ7hIDuK3a 63fD2KVZFKqGwVYOx9PUoTcSUR/nAUBhrMegibf8LE1MkFA+ml/bkDu3UiLHMjk1Vy N6JbNZ5Di9f2ErAysLQx11oQKlNJazUKrD2p9EZU= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Miquel Raynal , Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai Subject: [PATCH v4 9/9] clk: fixed-factor: Let clk framework find parent Date: Fri, 12 Apr 2019 11:31:50 -0700 Message-Id: <20190412183150.102131-10-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190412183150.102131-1-sboyd@kernel.org> References: <20190412183150.102131-1-sboyd@kernel.org> MIME-Version: 1.0 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 Convert this driver to a more modern way of specifying parents now that we have a way to specify clk parents by DT index. This lets us nicely avoid a problem where a parent clk name isn't know because the parent clk hasn't been registered yet. Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Signed-off-by: Stephen Boyd --- drivers/clk/clk-fixed-factor.c | 53 +++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 241b3f8c61a9..67cc7e515e42 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -64,12 +64,14 @@ const struct clk_ops clk_fixed_factor_ops = { }; EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); -struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned int mult, unsigned int div) +static struct clk_hw * +__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, + const char *name, const char *parent_name, int index, + unsigned long flags, unsigned int mult, unsigned int div) { struct clk_fixed_factor *fix; struct clk_init_data init; + struct clk_parent_data pdata = { .index = index }; struct clk_hw *hw; int ret; @@ -85,11 +87,17 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, init.name = name; init.ops = &clk_fixed_factor_ops; init.flags = flags | CLK_IS_BASIC; - init.parent_names = &parent_name; + if (parent_name) + init.parent_names = &parent_name; + else + init.parent_data = &pdata; init.num_parents = 1; hw = &fix->hw; - ret = clk_hw_register(dev, hw); + if (dev) + ret = clk_hw_register(dev, hw); + else + ret = of_clk_hw_register(np, hw); if (ret) { kfree(fix); hw = ERR_PTR(ret); @@ -97,6 +105,14 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, return hw; } + +struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, + const char *name, const char *parent_name, unsigned long flags, + unsigned int mult, unsigned int div) +{ + return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1, flags, + mult, div); +} EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); struct clk *clk_register_fixed_factor(struct device *dev, const char *name, @@ -143,11 +159,10 @@ static const struct of_device_id set_rate_parent_matches[] = { { /* Sentinel */ }, }; -static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) +static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node) { - struct clk *clk; + struct clk_hw *hw; const char *clk_name = node->name; - const char *parent_name; unsigned long flags = 0; u32 div, mult; int ret; @@ -165,30 +180,28 @@ static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) } of_property_read_string(node, "clock-output-names", &clk_name); - parent_name = of_clk_get_parent_name(node, 0); if (of_match_node(set_rate_parent_matches, node)) flags |= CLK_SET_RATE_PARENT; - clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, - mult, div); - if (IS_ERR(clk)) { + hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0, + flags, mult, div); + if (IS_ERR(hw)) { /* - * If parent clock is not registered, registration would fail. * Clear OF_POPULATED flag so that clock registration can be * attempted again from probe function. */ of_node_clear_flag(node, OF_POPULATED); - return clk; + return ERR_CAST(hw); } - ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); if (ret) { - clk_unregister(clk); + clk_hw_unregister_fixed_factor(hw); return ERR_PTR(ret); } - return clk; + return hw; } /** @@ -203,17 +216,17 @@ CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock", static int of_fixed_factor_clk_remove(struct platform_device *pdev) { - struct clk *clk = platform_get_drvdata(pdev); + struct clk_hw *clk = platform_get_drvdata(pdev); of_clk_del_provider(pdev->dev.of_node); - clk_unregister_fixed_factor(clk); + clk_hw_unregister_fixed_factor(clk); return 0; } static int of_fixed_factor_clk_probe(struct platform_device *pdev) { - struct clk *clk; + struct clk_hw *clk; /* * This function is not executed when of_fixed_factor_clk_setup