From patchwork Tue Feb 26 22:34:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10830891 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 9D5E91390 for ; Tue, 26 Feb 2019 22:35:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 89F1C2CDCD for ; Tue, 26 Feb 2019 22:35:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7E4DF2CE49; Tue, 26 Feb 2019 22:35:15 +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 ADD932CDCD for ; Tue, 26 Feb 2019 22:35:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729463AbfBZWfF (ORCPT ); Tue, 26 Feb 2019 17:35:05 -0500 Received: from mail.kernel.org ([198.145.29.99]:48228 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729154AbfBZWec (ORCPT ); Tue, 26 Feb 2019 17:34:32 -0500 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 DEB5D21874; Tue, 26 Feb 2019 22:34:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551220471; bh=sM9+js7IZRf/8Ngn8rWh/XzWSauHe7ffLH25ayUuXrU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tS/Dluldv5tItK/ZCT/aFvsozKFPWoMnj6uC3G/kdEo98dv8QlLt7tSrfNxIWmop+ 7AkfoAHpca4an4vLhJHPiXnq8Ed2GTVZBt2VF9mIRDa4FfngRNvC6qu+LRpPrL71EH k0EQgBIZ6rmawbEC3nVsPoSrTdBIp8A1G00Ef+0o= 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 v2 1/8] clk: Combine __clk_get() and __clk_create_clk() Date: Tue, 26 Feb 2019 14:34:22 -0800 Message-Id: <20190226223429.193873-2-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog In-Reply-To: <20190226223429.193873-1-sboyd@kernel.org> References: <20190226223429.193873-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 __clk_get() function is practically a private clk implementation detail now. No architecture defines it, and given that new code should be using the common clk framework there isn't a need for it to keep existing just to serve clkdev purposes. Let's fold it into the __clk_create_clk() function and make that a little more generic by renaming it to clk_hw_create_clk(). This will allow the framework to create a struct clk handle to a particular clk_hw pointer and link it up as a consumer wherever that's needed. Doing this also lets us get rid of the __clk_free_clk() API that had to be kept in sync with __clk_put(). Splitting that API up into the "link and unlink from consumer list" phase and "free the clk pointer" phase allows us to reuse that logic in a couple places, simplifying the code. 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 | 140 +++++++++++++++++++++++++++++-------------- drivers/clk/clk.h | 10 +--- drivers/clk/clkdev.c | 9 +-- 3 files changed, 98 insertions(+), 61 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d2477a5058ac..fef937ea44f4 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3209,42 +3209,103 @@ static int __clk_core_init(struct clk_core *core) return ret; } -struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, +/** + * clk_core_link_consumer - Add a clk consumer to the list of consumers in a clk_core + * @core: clk to add consumer to + * @clk: consumer to link to a clk + */ +static void clk_core_link_consumer(struct clk_core *core, struct clk *clk) +{ + clk_prepare_lock(); + hlist_add_head(&clk->clks_node, &core->clks); + clk_prepare_unlock(); +} + +/** + * clk_core_unlink_consumer - Remove a clk consumer from the list of consumers in a clk_core + * @clk: consumer to unlink + */ +static void clk_core_unlink_consumer(struct clk *clk) +{ + lockdep_assert_held(&prepare_lock); + hlist_del(&clk->clks_node); +} + +/** + * alloc_clk - Allocate a clk consumer, but leave it unlinked to the clk_core + * @core: clk to allocate a consumer for + * @dev_id: string describing device name + * @con_id: connection ID string on device + * + * Returns: clk consumer left unlinked from the consumer list + */ +static struct clk *alloc_clk(struct clk_core *core, const char *dev_id, const char *con_id) { struct clk *clk; - /* This is to allow this function to be chained to others */ - if (IS_ERR_OR_NULL(hw)) - return ERR_CAST(hw); - clk = kzalloc(sizeof(*clk), GFP_KERNEL); if (!clk) return ERR_PTR(-ENOMEM); - clk->core = hw->core; + clk->core = core; clk->dev_id = dev_id; clk->con_id = kstrdup_const(con_id, GFP_KERNEL); clk->max_rate = ULONG_MAX; - clk_prepare_lock(); - hlist_add_head(&clk->clks_node, &hw->core->clks); - clk_prepare_unlock(); - return clk; } -/* keep in sync with __clk_put */ -void __clk_free_clk(struct clk *clk) +/** + * free_clk - Free a clk consumer + * @clk: clk consumer to free + * + * Note, this assumes the clk has been unlinked from the clk_core consumer + * list. + */ +static void free_clk(struct clk *clk) { - clk_prepare_lock(); - hlist_del(&clk->clks_node); - clk_prepare_unlock(); - kfree_const(clk->con_id); kfree(clk); } +/** + * clk_hw_create_clk: Allocate and link a clk consumer to a clk_core given + * a clk_hw + * @hw: clk_hw associated with the clk being consumed + * @dev_id: string describing device name + * @con_id: connection ID string on device + * + * This is the main function used to create a clk pointer for use by clk + * consumers. It connects a consumer to the clk_core and clk_hw structures + * used by the framework and clk provider respectively. + */ +struct clk *clk_hw_create_clk(struct clk_hw *hw, + const char *dev_id, const char *con_id) +{ + struct clk *clk; + struct clk_core *core; + + /* This is to allow this function to be chained to others */ + if (IS_ERR_OR_NULL(hw)) + return ERR_CAST(hw); + + core = hw->core; + clk = alloc_clk(core, dev_id, con_id); + if (IS_ERR(clk)) + return clk; + + if (!try_module_get(core->owner)) { + free_clk(clk); + return ERR_PTR(-ENOENT); + } + + kref_get(&core->ref); + clk_core_link_consumer(core, clk); + + return clk; +} + /** * clk_register - allocate a new clock, register it and return an opaque cookie * @dev: device that is registering this clock @@ -3320,17 +3381,27 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) INIT_HLIST_HEAD(&core->clks); - hw->clk = __clk_create_clk(hw, NULL, NULL); + /* + * Don't call clk_hw_create_clk() here because that would pin the + * provider module to itself and prevent it from ever being removed. + */ + hw->clk = alloc_clk(core, NULL, NULL); if (IS_ERR(hw->clk)) { ret = PTR_ERR(hw->clk); goto fail_parents; } + clk_core_link_consumer(hw->core, hw->clk); + ret = __clk_core_init(core); if (!ret) return hw->clk; - __clk_free_clk(hw->clk); + clk_prepare_lock(); + clk_core_unlink_consumer(hw->clk); + clk_prepare_unlock(); + + free_clk(hw->clk); hw->clk = NULL; fail_parents: @@ -3601,20 +3672,7 @@ EXPORT_SYMBOL_GPL(devm_clk_hw_unregister); /* * clkdev helpers */ -int __clk_get(struct clk *clk) -{ - struct clk_core *core = !clk ? NULL : clk->core; - - if (core) { - if (!try_module_get(core->owner)) - return 0; - - kref_get(&core->ref); - } - return 1; -} -/* keep in sync with __clk_free_clk */ void __clk_put(struct clk *clk) { struct module *owner; @@ -3648,8 +3706,7 @@ void __clk_put(struct clk *clk) module_put(owner); - kfree_const(clk->con_id); - kfree(clk); + free_clk(clk); } /*** clk rate change notifiers ***/ @@ -4025,8 +4082,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, const char *dev_id, const char *con_id) { struct of_clk_provider *provider; - struct clk *clk = ERR_PTR(-EPROBE_DEFER); - struct clk_hw *hw; + struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); if (!clkspec) return ERR_PTR(-EINVAL); @@ -4036,21 +4092,13 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, list_for_each_entry(provider, &of_clk_providers, link) { if (provider->node == clkspec->np) { hw = __of_clk_get_hw_from_provider(provider, clkspec); - clk = __clk_create_clk(hw, dev_id, con_id); - } - - if (!IS_ERR(clk)) { - if (!__clk_get(clk)) { - __clk_free_clk(clk); - clk = ERR_PTR(-ENOENT); - } - - break; + if (!IS_ERR(hw)) + break; } } mutex_unlock(&of_clk_mutex); - return clk; + return clk_hw_create_clk(hw, dev_id, con_id); } /** diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index b02f5e604e69..4cdf30b0008c 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -12,24 +12,20 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, #endif #ifdef CONFIG_COMMON_CLK -struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, - const char *con_id); -void __clk_free_clk(struct clk *clk); -int __clk_get(struct clk *clk); +struct clk *clk_hw_create_clk(struct clk_hw *hw, + const char *dev_id, const char *con_id); void __clk_put(struct clk *clk); #else /* All these casts to avoid ifdefs in clkdev... */ static inline struct clk * -__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id) +clk_hw_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id) { return (struct clk *)hw; } -static inline void __clk_free_clk(struct clk *clk) { } static struct clk_hw *__clk_get_hw(struct clk *clk) { return (struct clk_hw *)clk; } -static inline int __clk_get(struct clk *clk) { return 1; } static inline void __clk_put(struct clk *clk) { } #endif diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 9ab3db8b3988..bdeaffc950ae 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -174,16 +174,9 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id) if (!cl) goto out; - clk = __clk_create_clk(cl->clk_hw, dev_id, con_id); + clk = clk_hw_create_clk(cl->clk_hw, dev_id, con_id); if (IS_ERR(clk)) - goto out; - - if (!__clk_get(clk)) { - __clk_free_clk(clk); cl = NULL; - goto out; - } - out: mutex_unlock(&clocks_mutex); From patchwork Tue Feb 26 22:34:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10830879 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 7A3BA139A for ; Tue, 26 Feb 2019 22:34:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 67D5B2CDC2 for ; Tue, 26 Feb 2019 22:34:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5B6772CDCB; Tue, 26 Feb 2019 22:34: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 EACA62CDCD for ; Tue, 26 Feb 2019 22:34:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729321AbfBZWed (ORCPT ); Tue, 26 Feb 2019 17:34:33 -0500 Received: from mail.kernel.org ([198.145.29.99]:48246 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729187AbfBZWed (ORCPT ); Tue, 26 Feb 2019 17:34:33 -0500 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 54BB5218A1; Tue, 26 Feb 2019 22:34:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551220471; bh=EhSwc8YZXpNLa457hu+6PsYYq1FYt0pMKcWYUIlYCSE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jI+lGYBgVD+nUUzZMkqIsZXvF/TmO56M6kLugzmh06R6b5le6QM2oabRAunMnkJKh zGZ0+tP/ZumBp3raKeqZtnC9V0mGt3a9r6/2/0CwGjGmPcJphER2R2YE3xVXzZvAqf 2tQjuZnEwxjM4BvMI5zxxiepgAHsp2LDUWG1w+KE= From: Stephen Boyd To: Michael Turquette , Stephen Boyd Cc: Miquel Raynal , linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Jerome Brunet , Russell King , Jeffrey Hugo , Chen-Yu Tsai Subject: [PATCH v2 2/8] clk: core: clarify the check for runtime PM Date: Tue, 26 Feb 2019 14:34:23 -0800 Message-Id: <20190226223429.193873-3-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog In-Reply-To: <20190226223429.193873-1-sboyd@kernel.org> References: <20190226223429.193873-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 From: Miquel Raynal Currently, the core->dev entry is populated only if runtime PM is enabled. Doing so prevents accessing the device structure in any case. Keep the same logic but instead of using the presence of core->dev as the only condition, also check the status of pm_runtime_enabled(). Then, we can set the core->dev pointer at any time as long as a device structure is available. This change will help supporting device links in the clock subsystem. Signed-off-by: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai [sboyd@kernel.org: Change to a boolean flag] Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index fef937ea44f4..d46e8b9b9c9f 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -57,6 +57,7 @@ struct clk_core { struct clk_core *new_child; unsigned long flags; bool orphan; + bool rpm_enabled; unsigned int enable_count; unsigned int prepare_count; unsigned int protect_count; @@ -92,9 +93,9 @@ struct clk { /*** runtime pm ***/ static int clk_pm_runtime_get(struct clk_core *core) { - int ret = 0; + int ret; - if (!core->dev) + if (!core->rpm_enabled) return 0; ret = pm_runtime_get_sync(core->dev); @@ -103,7 +104,7 @@ static int clk_pm_runtime_get(struct clk_core *core) static void clk_pm_runtime_put(struct clk_core *core) { - if (!core->dev) + if (!core->rpm_enabled) return; pm_runtime_put_sync(core->dev); @@ -223,7 +224,7 @@ static bool clk_core_is_enabled(struct clk_core *core) * taking enable spinlock, but the below check is needed if one tries * to call it from other places. */ - if (core->dev) { + if (core->rpm_enabled) { pm_runtime_get_noresume(core->dev); if (!pm_runtime_active(core->dev)) { ret = false; @@ -233,7 +234,7 @@ static bool clk_core_is_enabled(struct clk_core *core) ret = core->ops->is_enabled(core->hw); done: - if (core->dev) + if (core->rpm_enabled) pm_runtime_put(core->dev); return ret; @@ -3341,7 +3342,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) core->ops = hw->init->ops; if (dev && pm_runtime_enabled(dev)) - core->dev = dev; + core->rpm_enabled = true; + core->dev = dev; if (dev && dev->driver) core->owner = dev->driver->owner; core->hw = hw; From patchwork Tue Feb 26 22:34:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10830889 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 4DE171390 for ; Tue, 26 Feb 2019 22:35:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A5EC2CDCD for ; Tue, 26 Feb 2019 22:35:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2E57E2CE49; Tue, 26 Feb 2019 22:35:14 +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.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,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 710FA2CE3F for ; Tue, 26 Feb 2019 22:35:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729332AbfBZWee (ORCPT ); Tue, 26 Feb 2019 17:34:34 -0500 Received: from mail.kernel.org ([198.145.29.99]:48262 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729221AbfBZWed (ORCPT ); Tue, 26 Feb 2019 17:34:33 -0500 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 B932D218A2; Tue, 26 Feb 2019 22:34:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551220472; bh=i5K8ds82P8jDMSn4mpHTSqjSpIRmkq6qgYH1C19FKZ0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wkUTwQ5BDElKpjNh2mVXe3kPESMnmT4gi5StgElzhJ1DxyEdDt0GbgNJm0cu5K8OF /DrHEqAJxYHTZleIS9O7n+SLYLv4x9qzFx1++OpTgvXJAUAgC3p8JToO8msl+L+f/z jWo4qB2B0m5FZTNGbZCGLR4to9XbMQgouMWTOizc= 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 v2 3/8] clk: Introduce of_clk_get_hw_from_clkspec() Date: Tue, 26 Feb 2019 14:34:24 -0800 Message-Id: <20190226223429.193873-4-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog In-Reply-To: <20190226223429.193873-1-sboyd@kernel.org> References: <20190226223429.193873-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 want to get struct clk_hw pointers from a DT clk specifier (i.e. a clocks property) so that we can find parent clks without searching for globally unique clk names. This should save time by avoiding the global string search for clks that are external to the clock controller providing the clk and let us move away from string comparisons in general. Introduce of_clk_get_hw_from_clkspec() which is largely the DT parsing part of finding clks implemented in clkdev.c and have that return a clk_hw pointer instead of converting that into a clk pointer. This lets us push up the clk pointer creation to the caller in clk_get() and avoids the need to push the dev_id and con_id throughout the DT parsing code. 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 | 46 +++++++++++++++++++++--- drivers/clk/clk.h | 5 +-- drivers/clk/clkdev.c | 83 +++++++++++++------------------------------- 3 files changed, 69 insertions(+), 65 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d46e8b9b9c9f..04288063847b 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4065,6 +4065,42 @@ void devm_of_clk_del_provider(struct device *dev) } EXPORT_SYMBOL(devm_of_clk_del_provider); +int of_parse_clkspec(const struct device_node *np, int index, const char *name, + struct of_phandle_args *out_args) +{ + int ret = -ENOENT; + + /* Walk up the tree of devices looking for a clock property that matches */ + while (np) { + /* + * For named clocks, first look up the name in the + * "clock-names" property. If it cannot be found, then index + * will be an error code and of_parse_phandle_with_args() will + * return -EINVAL. + */ + if (name) + index = of_property_match_string(np, "clock-names", name); + ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells", + index, out_args); + if (!ret) + break; + if (name && index >= 0) + break; + + /* + * No matching clock found on this node. If the parent node + * has a "clock-ranges" property, then we can try one of its + * clocks. + */ + np = np->parent; + if (np && !of_get_property(np, "clock-ranges", NULL)) + break; + index = 0; + } + + return ret; +} + static struct clk_hw * __of_clk_get_hw_from_provider(struct of_clk_provider *provider, struct of_phandle_args *clkspec) @@ -4080,8 +4116,7 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider, return __clk_get_hw(clk); } -struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, - const char *dev_id, const char *con_id) +struct clk_hw *of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec) { struct of_clk_provider *provider; struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); @@ -4089,7 +4124,6 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, if (!clkspec) return ERR_PTR(-EINVAL); - /* Check if we have such a provider in our array */ mutex_lock(&of_clk_mutex); list_for_each_entry(provider, &of_clk_providers, link) { if (provider->node == clkspec->np) { @@ -4100,7 +4134,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, } mutex_unlock(&of_clk_mutex); - return clk_hw_create_clk(hw, dev_id, con_id); + return hw; } /** @@ -4113,7 +4147,9 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, */ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) { - return __of_clk_get_from_provider(clkspec, NULL, __func__); + struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec); + + return clk_hw_create_clk(hw, NULL, __func__); } EXPORT_SYMBOL_GPL(of_clk_get_from_provider); diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 4cdf30b0008c..5a0ca0e3c1f1 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -7,8 +7,9 @@ struct clk_hw; #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) -struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, - const char *dev_id, const char *con_id); +int of_parse_clkspec(const struct device_node *np, int index, const char *name, + struct of_phandle_args *out_args); +struct clk_hw *of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec); #endif #ifdef CONFIG_COMMON_CLK diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index bdeaffc950ae..5ebb2119c0b9 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -28,69 +28,37 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) -static struct clk *__of_clk_get(struct device_node *np, int index, - const char *dev_id, const char *con_id) +static struct clk_hw *of_clk_get_hw(struct device_node *np, + int index, const char *con_id) { + int ret; + struct clk_hw *hw; struct of_phandle_args clkspec; - struct clk *clk; - int rc; - rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index, - &clkspec); - if (rc) - return ERR_PTR(rc); + ret = of_parse_clkspec(np, index, con_id, &clkspec); + if (ret) + return ERR_PTR(ret); - clk = __of_clk_get_from_provider(&clkspec, dev_id, con_id); + hw = of_clk_get_hw_from_clkspec(&clkspec); of_node_put(clkspec.np); - return clk; + return hw; } -struct clk *of_clk_get(struct device_node *np, int index) +static struct clk *__of_clk_get(struct device_node *np, + int index, const char *dev_id, + const char *con_id) { - return __of_clk_get(np, index, np->full_name, NULL); + struct clk_hw *hw = of_clk_get_hw(np, index, con_id); + + return clk_hw_create_clk(hw, dev_id, con_id); } -EXPORT_SYMBOL(of_clk_get); -static struct clk *__of_clk_get_by_name(struct device_node *np, - const char *dev_id, - const char *name) +struct clk *of_clk_get(struct device_node *np, int index) { - struct clk *clk = ERR_PTR(-ENOENT); - - /* Walk up the tree of devices looking for a clock that matches */ - while (np) { - int index = 0; - - /* - * For named clocks, first look up the name in the - * "clock-names" property. If it cannot be found, then - * index will be an error code, and of_clk_get() will fail. - */ - if (name) - index = of_property_match_string(np, "clock-names", name); - clk = __of_clk_get(np, index, dev_id, name); - if (!IS_ERR(clk)) { - break; - } else if (name && index >= 0) { - if (PTR_ERR(clk) != -EPROBE_DEFER) - pr_err("ERROR: could not get clock %pOF:%s(%i)\n", - np, name ? name : "", index); - return clk; - } - - /* - * No matching clock found on this node. If the parent node - * has a "clock-ranges" property, then we can try one of its - * clocks. - */ - np = np->parent; - if (np && !of_get_property(np, "clock-ranges", NULL)) - break; - } - - return clk; + return __of_clk_get(np, index, np->full_name, NULL); } +EXPORT_SYMBOL(of_clk_get); /** * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node @@ -106,15 +74,14 @@ 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(np, -1, np->full_name, name); } EXPORT_SYMBOL(of_clk_get_by_name); #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) +static struct clk_hw *of_clk_get_hw(struct device_node *np, + int index, const char *con_id) { return ERR_PTR(-ENOENT); } @@ -187,12 +154,12 @@ EXPORT_SYMBOL(clk_get_sys); struct clk *clk_get(struct device *dev, const char *con_id) { const char *dev_id = dev ? dev_name(dev) : NULL; - struct clk *clk; + struct clk_hw *hw; if (dev && dev->of_node) { - clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id); - if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) - return clk; + hw = of_clk_get_hw(dev->of_node, 0, con_id); + if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER) + return clk_hw_create_clk(hw, dev_id, con_id); } return clk_get_sys(dev_id, con_id); From patchwork Tue Feb 26 22:34:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10830893 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 99E931390 for ; Tue, 26 Feb 2019 22:35:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8866C2CEDB for ; Tue, 26 Feb 2019 22:35:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7CD8A2CE53; Tue, 26 Feb 2019 22:35: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 EF4AD2CDCD for ; Tue, 26 Feb 2019 22:35:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729089AbfBZWfE (ORCPT ); Tue, 26 Feb 2019 17:35:04 -0500 Received: from mail.kernel.org ([198.145.29.99]:48264 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729271AbfBZWed (ORCPT ); Tue, 26 Feb 2019 17:34:33 -0500 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 28470218A3; Tue, 26 Feb 2019 22:34:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551220472; bh=CNGc4u8PnghQnh+ikISWqbDu3OKYkonz9V2RmyYaTE4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hNIam5HF71LbkVi/xsPCWYSZm98Q0U3/O5pitnFgl8+W2E1rpQFVbXfuLsAyYS8Rh Pss/IcoIESZ/i9emST83KAhIGv/3zLNjtgpdVcTuZAVTsZNqlEs4qTy00H+vtBBTp7 /m6nzSTCPcMpAX5NVG4rkKX6s8HiYa/meu36CIJo= 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 v2 4/8] clk: Inform the core about consumer devices Date: Tue, 26 Feb 2019 14:34:25 -0800 Message-Id: <20190226223429.193873-5-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog In-Reply-To: <20190226223429.193873-1-sboyd@kernel.org> References: <20190226223429.193873-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 have a pointer to the device that's consuming a particular clk in the clk framework so we can link the consumer to the clk provider with a PM device link. Add a device argument to clk_hw_create_clk() for this so it can be used in subsequent patches to add and remove the link. 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 | 7 +++++-- drivers/clk/clk.h | 7 +++++-- drivers/clk/clkdev.c | 16 +++++++++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 04288063847b..8244ef2ba977 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -82,6 +82,7 @@ struct clk_core { struct clk { struct clk_core *core; + struct device *dev; const char *dev_id; const char *con_id; unsigned long min_rate; @@ -3273,6 +3274,7 @@ static void free_clk(struct clk *clk) /** * clk_hw_create_clk: Allocate and link a clk consumer to a clk_core given * a clk_hw + * @dev: clk consumer device * @hw: clk_hw associated with the clk being consumed * @dev_id: string describing device name * @con_id: connection ID string on device @@ -3281,7 +3283,7 @@ static void free_clk(struct clk *clk) * consumers. It connects a consumer to the clk_core and clk_hw structures * used by the framework and clk provider respectively. */ -struct clk *clk_hw_create_clk(struct clk_hw *hw, +struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id, const char *con_id) { struct clk *clk; @@ -3295,6 +3297,7 @@ struct clk *clk_hw_create_clk(struct clk_hw *hw, clk = alloc_clk(core, dev_id, con_id); if (IS_ERR(clk)) return clk; + clk->dev = dev; if (!try_module_get(core->owner)) { free_clk(clk); @@ -4149,7 +4152,7 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) { struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec); - return clk_hw_create_clk(hw, NULL, __func__); + return clk_hw_create_clk(NULL, hw, NULL, __func__); } EXPORT_SYMBOL_GPL(of_clk_get_from_provider); diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 5a0ca0e3c1f1..5ea2185e57a1 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -5,6 +5,8 @@ */ struct clk_hw; +struct device; +struct of_phandle_args; #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) int of_parse_clkspec(const struct device_node *np, int index, const char *name, @@ -13,13 +15,14 @@ struct clk_hw *of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec); #endif #ifdef CONFIG_COMMON_CLK -struct clk *clk_hw_create_clk(struct clk_hw *hw, +struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id, const char *con_id); void __clk_put(struct clk *clk); #else /* All these casts to avoid ifdefs in clkdev... */ static inline struct clk * -clk_hw_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id) +clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id, + const char *con_id) { return (struct clk *)hw; } diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 5ebb2119c0b9..f2f4f2afd28c 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -51,7 +51,7 @@ static struct clk *__of_clk_get(struct device_node *np, { struct clk_hw *hw = of_clk_get_hw(np, index, con_id); - return clk_hw_create_clk(hw, dev_id, con_id); + return clk_hw_create_clk(NULL, hw, dev_id, con_id); } struct clk *of_clk_get(struct device_node *np, int index) @@ -130,7 +130,8 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) return cl; } -struct clk *clk_get_sys(const char *dev_id, const char *con_id) +static struct clk *__clk_get_sys(struct device *dev, const char *dev_id, + const char *con_id) { struct clk_lookup *cl; struct clk *clk = NULL; @@ -141,7 +142,7 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id) if (!cl) goto out; - clk = clk_hw_create_clk(cl->clk_hw, dev_id, con_id); + clk = clk_hw_create_clk(dev, cl->clk_hw, dev_id, con_id); if (IS_ERR(clk)) cl = NULL; out: @@ -149,6 +150,11 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id) return cl ? clk : ERR_PTR(-ENOENT); } + +struct clk *clk_get_sys(const char *dev_id, const char *con_id) +{ + return __clk_get_sys(NULL, dev_id, con_id); +} EXPORT_SYMBOL(clk_get_sys); struct clk *clk_get(struct device *dev, const char *con_id) @@ -159,10 +165,10 @@ struct clk *clk_get(struct device *dev, const char *con_id) if (dev && dev->of_node) { hw = of_clk_get_hw(dev->of_node, 0, con_id); if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER) - return clk_hw_create_clk(hw, dev_id, con_id); + return clk_hw_create_clk(dev, hw, dev_id, con_id); } - return clk_get_sys(dev_id, con_id); + return __clk_get_sys(dev, dev_id, con_id); } EXPORT_SYMBOL(clk_get); From patchwork Tue Feb 26 22:34:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10830881 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 B233F139A for ; Tue, 26 Feb 2019 22:34:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A065C2CDD3 for ; Tue, 26 Feb 2019 22:34:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 938D22CE3F; Tue, 26 Feb 2019 22:34:48 +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 CBBC12CDCB for ; Tue, 26 Feb 2019 22:34:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729341AbfBZWee (ORCPT ); Tue, 26 Feb 2019 17:34:34 -0500 Received: from mail.kernel.org ([198.145.29.99]:48284 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728766AbfBZWed (ORCPT ); Tue, 26 Feb 2019 17:34:33 -0500 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 8D2B1218A4; Tue, 26 Feb 2019 22:34:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551220472; bh=GTEq64B0JR65qdF7AMCm24b4lAbSGCySNWMdaZXcof4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M4NMJF42xSAALlqO+4AlI33oXaha/AK+ycqMnqT+wjLuKY6xZDZ4Sab7wEMEdCRmo fnkQZfiYVF7sufA/10QivDP3pfVmeeVCyPlPTZjlmtE14DnmLIiWZNnxEVwDwSJry/ M/J4/MXKtdrvx3FtjLwP3msBC84lLw5/16hEuSW0= 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 v2 5/8] clk: Move of_clk_*() APIs into clk.c from clkdev.c Date: Tue, 26 Feb 2019 14:34:26 -0800 Message-Id: <20190226223429.193873-6-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog In-Reply-To: <20190226223429.193873-1-sboyd@kernel.org> References: <20190226223429.193873-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 API between clk.c and clkdev.c is purely getting the clk_hw structure (or the struct clk if it's not CCF) and then turning that struct clk_hw pointer into a struct clk pointer via clk_hw_create_clk(). There's no need to complicate clkdev.c with these DT parsing details that are only relevant to the common clk framework. Move the DT parsing logic into the core framework and just expose the APIs to get a clk_hw pointer and convert it. 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 | 57 ++++++++++++++++++++++++++++++++++++++--- drivers/clk/clk.h | 11 +++++--- drivers/clk/clkdev.c | 60 -------------------------------------------- 3 files changed, 62 insertions(+), 66 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 8244ef2ba977..937b8d092d17 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4068,8 +4068,8 @@ void devm_of_clk_del_provider(struct device *dev) } EXPORT_SYMBOL(devm_of_clk_del_provider); -int of_parse_clkspec(const struct device_node *np, int index, const char *name, - struct of_phandle_args *out_args) +static int of_parse_clkspec(const struct device_node *np, int index, + const char *name, struct of_phandle_args *out_args) { int ret = -ENOENT; @@ -4119,7 +4119,8 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider, return __clk_get_hw(clk); } -struct clk_hw *of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec) +static struct clk_hw * +of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec) { struct of_clk_provider *provider; struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); @@ -4156,6 +4157,56 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) } EXPORT_SYMBOL_GPL(of_clk_get_from_provider); +struct clk_hw *of_clk_get_hw(struct device_node *np, int index, + const char *con_id) +{ + int ret; + struct clk_hw *hw; + struct of_phandle_args clkspec; + + ret = of_parse_clkspec(np, index, con_id, &clkspec); + if (ret) + return ERR_PTR(ret); + + hw = of_clk_get_hw_from_clkspec(&clkspec); + of_node_put(clkspec.np); + + return hw; +} + +static struct clk *__of_clk_get(struct device_node *np, + int index, const char *dev_id, + const char *con_id) +{ + struct clk_hw *hw = of_clk_get_hw(np, index, con_id); + + return clk_hw_create_clk(NULL, hw, dev_id, con_id); +} + +struct clk *of_clk_get(struct device_node *np, int index) +{ + return __of_clk_get(np, index, np->full_name, NULL); +} +EXPORT_SYMBOL(of_clk_get); + +/** + * of_clk_get_by_name() - Parse and lookup a 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. + */ +struct clk *of_clk_get_by_name(struct device_node *np, const char *name) +{ + if (!np) + return ERR_PTR(-ENOENT); + + return __of_clk_get(np, -1, np->full_name, name); +} +EXPORT_SYMBOL(of_clk_get_by_name); + /** * of_clk_get_parent_count() - Count the number of clocks a device node has * @np: device node to count diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 5ea2185e57a1..553f531cc232 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -9,9 +9,14 @@ struct device; struct of_phandle_args; #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) -int of_parse_clkspec(const struct device_node *np, int index, const char *name, - struct of_phandle_args *out_args); -struct clk_hw *of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec); +struct clk_hw *of_clk_get_hw(struct device_node *np, + int index, const char *con_id); +#else /* !CONFIG_COMMON_CLK || !CONFIG_OF */ +static inline struct clk_hw *of_clk_get_hw(struct device_node *np, + int index, const char *con_id) +{ + return ERR_PTR(-ENOENT); +} #endif #ifdef CONFIG_COMMON_CLK diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index f2f4f2afd28c..d3758bf4305c 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -27,66 +27,6 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); -#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) -static struct clk_hw *of_clk_get_hw(struct device_node *np, - int index, const char *con_id) -{ - int ret; - struct clk_hw *hw; - struct of_phandle_args clkspec; - - ret = of_parse_clkspec(np, index, con_id, &clkspec); - if (ret) - return ERR_PTR(ret); - - hw = of_clk_get_hw_from_clkspec(&clkspec); - of_node_put(clkspec.np); - - return hw; -} - -static struct clk *__of_clk_get(struct device_node *np, - int index, const char *dev_id, - const char *con_id) -{ - struct clk_hw *hw = of_clk_get_hw(np, index, con_id); - - return clk_hw_create_clk(NULL, hw, dev_id, con_id); -} - -struct clk *of_clk_get(struct device_node *np, int index) -{ - return __of_clk_get(np, index, np->full_name, NULL); -} -EXPORT_SYMBOL(of_clk_get); - -/** - * of_clk_get_by_name() - Parse and lookup a 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. - */ -struct clk *of_clk_get_by_name(struct device_node *np, const char *name) -{ - if (!np) - return ERR_PTR(-ENOENT); - - return __of_clk_get(np, -1, np->full_name, name); -} -EXPORT_SYMBOL(of_clk_get_by_name); - -#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */ - -static struct clk_hw *of_clk_get_hw(struct device_node *np, - int index, const char *con_id) -{ - return ERR_PTR(-ENOENT); -} -#endif - /* * Find the correct struct clk for the device and connection ID. * We do slightly fuzzy matching here: From patchwork Tue Feb 26 22:34:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10830887 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 E358F1390 for ; Tue, 26 Feb 2019 22:35:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CC8992CDCB for ; Tue, 26 Feb 2019 22:35:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BA2062CE53; Tue, 26 Feb 2019 22:35:03 +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 8AE5C2CDCB for ; Tue, 26 Feb 2019 22:35:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729408AbfBZWer (ORCPT ); Tue, 26 Feb 2019 17:34:47 -0500 Received: from mail.kernel.org ([198.145.29.99]:48296 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729325AbfBZWee (ORCPT ); Tue, 26 Feb 2019 17:34:34 -0500 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 F0E72218A5; Tue, 26 Feb 2019 22:34:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551220473; bh=Z1u7HsaDuq0mWyzNouLmygYzjQDjMMAgUZc/0TqeMGw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ylWHrXb3cSD4kZBEvx48rLqI2he2epV2kmpcQgJ3woKnmR5gaZrwcJQNLJUZ5W2Zc 6uetHnFMBNs4tJERXkwPtas0iRDVlFp/d4ePqa+AdZeA+WrncmHsiSHALbPdFL3coF b1OmiH9zG7F6Hcu1+QWZLLHXmf9nq2Slg6yez8Vw= 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 v2 6/8] clk: Allow parents to be specified without string names Date: Tue, 26 Feb 2019 14:34:27 -0800 Message-Id: <20190226223429.193873-7-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog In-Reply-To: <20190226223429.193873-1-sboyd@kernel.org> References: <20190226223429.193873-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 .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 .fallback 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 Signed-off-by: Stephen Boyd Tested-by: Jerome Brunet --- drivers/clk/clk.c | 260 ++++++++++++++++++++++++++--------- include/linux/clk-provider.h | 19 +++ 2 files changed, 217 insertions(+), 62 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 937b8d092d17..3d01e8c56400 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; @@ -46,8 +53,7 @@ struct clk_core { struct module *owner; struct device *dev; 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; @@ -316,17 +322,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 *dev = core->dev; + + if (!dev) + return ERR_PTR(-ENOENT); + + /* TODO: Support clkdev clk_lookups */ + hw = of_clk_get_hw(dev->of_node, -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 * @@ -1516,15 +1597,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; } } @@ -2290,6 +2371,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) @@ -2302,8 +2384,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); @@ -2886,9 +2971,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; } @@ -3022,7 +3107,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; @@ -3076,12 +3161,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); /* @@ -3310,6 +3389,96 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, return clk; } +static int clk_cpy_name(const char *dst, const char *src, bool must_exist) +{ + if (!src) { + if (must_exist) + return -EINVAL; + return 0; + } + + 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); +} + /** * clk_register - allocate a new clock, register it and return an opaque cookie * @dev: device that is registering this clock @@ -3323,7 +3492,7 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, */ struct clk *clk_register(struct device *dev, struct clk_hw *hw) { - int i, ret; + int ret; struct clk_core *core; core = kzalloc(sizeof(*core), GFP_KERNEL); @@ -3356,33 +3525,9 @@ struct clk *clk_register(struct device *dev, 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); @@ -3393,7 +3538,7 @@ struct clk *clk_register(struct device *dev, 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); @@ -3409,13 +3554,9 @@ struct clk *clk_register(struct device *dev, 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: @@ -3445,15 +3586,10 @@ EXPORT_SYMBOL_GPL(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 e443fa9fa859..f4de52c6764e 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 Tue Feb 26 22:34:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10830885 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 950601390 for ; Tue, 26 Feb 2019 22:34:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 822B22CDC2 for ; Tue, 26 Feb 2019 22:34:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 767DA2CDCD; Tue, 26 Feb 2019 22:34:49 +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 953A02CDC2 for ; Tue, 26 Feb 2019 22:34:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729115AbfBZWer (ORCPT ); Tue, 26 Feb 2019 17:34:47 -0500 Received: from mail.kernel.org ([198.145.29.99]:48264 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729327AbfBZWee (ORCPT ); Tue, 26 Feb 2019 17:34:34 -0500 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 676E6218AC; Tue, 26 Feb 2019 22:34:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551220473; bh=8sEXAxWVtHJRYKfW4ZHIF6XdnIi5LHA1UhBksLy+YK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=xmARyioPkAmgnNjqFNbjDu4tJ3TEdqvj0gzE8RRRSsUnnTpM5scsWPdyuC8LvBVIP L5r64hIaZE93oUuCr3gIVXWYvqRyLY+o0oK13BAOubAxnPETmRRKyDpAMMrt/HEAYC cQ9r3oyocMhDakyVNlu3usZqtOOEoTenB/aGdgwY= 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 v2 7/8] clk: qcom: gcc-sdm845: Migrate to DT parent mapping Date: Tue, 26 Feb 2019 14:34:28 -0800 Message-Id: <20190226223429.193873-8-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog In-Reply-To: <20190226223429.193873-1-sboyd@kernel.org> References: <20190226223429.193873-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 TODO: Fully convert driver 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/qcom/gcc-sdm845.c | 180 +++++++++++++++++----------------- 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index 58fa5c247af1..90ce40e25f59 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -25,6 +25,59 @@ #include "gdsc.h" #include "reset.h" +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x76000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { 0x3, 4 }, + { 0x7, 8 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_even", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + enum { P_BI_TCXO, P_AUD_REF_CLK, @@ -42,11 +95,11 @@ static const struct parent_map gcc_parent_map_0[] = { { P_CORE_BI_PLL_TEST_SE, 7 }, }; -static const char * const gcc_parent_names_0[] = { - "bi_tcxo", - "gpll0", - "gpll0_out_even", - "core_bi_pll_test_se", +static const struct clk_parent_data gcc_parent_data_0[] = { + { .fw_name = "xo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" } }; static const struct parent_map gcc_parent_map_1[] = { @@ -150,59 +203,6 @@ static const char * const gcc_parent_names_10[] = { "core_bi_pll_test_se", }; -static struct clk_alpha_pll gpll0 = { - .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr = { - .enable_reg = 0x52000, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gpll0", - .parent_names = (const char *[]){ "bi_tcxo" }, - .num_parents = 1, - .ops = &clk_alpha_pll_fixed_fabia_ops, - }, - }, -}; - -static struct clk_alpha_pll gpll4 = { - .offset = 0x76000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr = { - .enable_reg = 0x52000, - .enable_mask = BIT(4), - .hw.init = &(struct clk_init_data){ - .name = "gpll4", - .parent_names = (const char *[]){ "bi_tcxo" }, - .num_parents = 1, - .ops = &clk_alpha_pll_fixed_fabia_ops, - }, - }, -}; - -static const struct clk_div_table post_div_table_fabia_even[] = { - { 0x0, 1 }, - { 0x1, 2 }, - { 0x3, 4 }, - { 0x7, 8 }, - { } -}; - -static struct clk_alpha_pll_postdiv gpll0_out_even = { - .offset = 0x0, - .post_div_shift = 8, - .post_div_table = post_div_table_fabia_even, - .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), - .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll0_out_even", - .parent_names = (const char *[]){ "gpll0" }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), { } @@ -340,7 +340,7 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = { .freq_tbl = ftbl_gcc_pcie_phy_refgen_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_pcie_phy_refgen_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_ops, }, @@ -362,7 +362,7 @@ static struct clk_rcg2 gcc_qspi_core_clk_src = { .freq_tbl = ftbl_gcc_qspi_core_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qspi_core_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_floor_ops, }, @@ -383,7 +383,7 @@ static struct clk_rcg2 gcc_pdm2_clk_src = { .freq_tbl = ftbl_gcc_pdm2_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_pdm2_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_ops, }, @@ -410,7 +410,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { static struct clk_init_data gcc_qupv3_wrap0_s0_clk_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -426,7 +426,7 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { static struct clk_init_data gcc_qupv3_wrap0_s1_clk_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -442,7 +442,7 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { static struct clk_init_data gcc_qupv3_wrap0_s2_clk_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -458,7 +458,7 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { static struct clk_init_data gcc_qupv3_wrap0_s3_clk_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -474,7 +474,7 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { static struct clk_init_data gcc_qupv3_wrap0_s4_clk_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -490,7 +490,7 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { static struct clk_init_data gcc_qupv3_wrap0_s5_clk_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -506,7 +506,7 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { static struct clk_init_data gcc_qupv3_wrap0_s6_clk_init = { .name = "gcc_qupv3_wrap0_s6_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -522,7 +522,7 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { static struct clk_init_data gcc_qupv3_wrap0_s7_clk_init = { .name = "gcc_qupv3_wrap0_s7_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -538,7 +538,7 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { static struct clk_init_data gcc_qupv3_wrap1_s0_clk_init = { .name = "gcc_qupv3_wrap1_s0_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -554,7 +554,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { static struct clk_init_data gcc_qupv3_wrap1_s1_clk_init = { .name = "gcc_qupv3_wrap1_s1_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -570,7 +570,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { static struct clk_init_data gcc_qupv3_wrap1_s2_clk_init = { .name = "gcc_qupv3_wrap1_s2_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -586,7 +586,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { static struct clk_init_data gcc_qupv3_wrap1_s3_clk_init = { .name = "gcc_qupv3_wrap1_s3_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -602,7 +602,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { static struct clk_init_data gcc_qupv3_wrap1_s4_clk_init = { .name = "gcc_qupv3_wrap1_s4_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -618,7 +618,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { static struct clk_init_data gcc_qupv3_wrap1_s5_clk_init = { .name = "gcc_qupv3_wrap1_s5_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -634,7 +634,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { static struct clk_init_data gcc_qupv3_wrap1_s6_clk_init = { .name = "gcc_qupv3_wrap1_s6_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -650,7 +650,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { static struct clk_init_data gcc_qupv3_wrap1_s7_clk_init = { .name = "gcc_qupv3_wrap1_s7_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }; @@ -707,7 +707,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_sdcc4_apps_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_ops, }, @@ -749,7 +749,7 @@ static struct clk_rcg2 gcc_ufs_card_axi_clk_src = { .freq_tbl = ftbl_gcc_ufs_card_axi_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_axi_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }, @@ -771,7 +771,7 @@ static struct clk_rcg2 gcc_ufs_card_ice_core_clk_src = { .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_ice_core_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }, @@ -806,7 +806,7 @@ static struct clk_rcg2 gcc_ufs_card_unipro_core_clk_src = { .freq_tbl = ftbl_gcc_ufs_card_unipro_core_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_unipro_core_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }, @@ -829,7 +829,7 @@ static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_axi_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }, @@ -843,7 +843,7 @@ static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_ice_core_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }, @@ -871,7 +871,7 @@ static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { .freq_tbl = ftbl_gcc_ufs_card_unipro_core_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_unipro_core_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }, @@ -894,7 +894,7 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_prim_master_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }, @@ -916,7 +916,7 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_prim_mock_utmi_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_shared_ops, }, @@ -930,7 +930,7 @@ static struct clk_rcg2 gcc_usb30_sec_master_clk_src = { .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_sec_master_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_ops, }, @@ -944,7 +944,7 @@ static struct clk_rcg2 gcc_usb30_sec_mock_utmi_clk_src = { .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_sec_mock_utmi_clk_src", - .parent_names = gcc_parent_names_0, + .parent_data = gcc_parent_data_0, .num_parents = 4, .ops = &clk_rcg2_ops, }, @@ -1036,8 +1036,8 @@ static struct clk_branch gcc_aggre_ufs_card_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_aggre_ufs_card_axi_clk", - .parent_names = (const char *[]){ - "gcc_ufs_card_axi_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_axi_clk_src.clkr.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, From patchwork Tue Feb 26 22:34:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 10830883 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 0D471180E for ; Tue, 26 Feb 2019 22:34:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EFE5D2CDCB for ; Tue, 26 Feb 2019 22:34:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E42B42CE3F; Tue, 26 Feb 2019 22:34:48 +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 ED5862CDCD for ; Tue, 26 Feb 2019 22:34:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729386AbfBZWer (ORCPT ); Tue, 26 Feb 2019 17:34:47 -0500 Received: from mail.kernel.org ([198.145.29.99]:48284 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729335AbfBZWee (ORCPT ); Tue, 26 Feb 2019 17:34:34 -0500 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 CB05D218AE; Tue, 26 Feb 2019 22:34:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551220474; bh=lp9aT8Nx4CezWWs8w8r9pEsH6j2LSLhXkfDtgxl/e4Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gtbza7RskGcHjPjiFncJ0VIsopE9jw37Tk5i9Y1d37JmD/6ickiubgs2PtG291Msb CjlHtqUb0Qagv1GtQfbbOyx48cELAVKHa2mMFecvx9M1PdX1e2HHTI+3R4tBOr/VOk 0YzeM1sIbhwHADcRk/C/i06Bkb+DmChNOkgKcASE= 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 v2 8/8] arm64: dts: qcom: Specify XO clk as input to GCC node Date: Tue, 26 Feb 2019 14:34:29 -0800 Message-Id: <20190226223429.193873-9-sboyd@kernel.org> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog In-Reply-To: <20190226223429.193873-1-sboyd@kernel.org> References: <20190226223429.193873-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 This is an example patch to show how DT nodes are updated to specify the clocks which are external to the clock controller can be specified in DT and then found by the clk core to do parent-child linkage. Cc: Miquel Raynal Cc: Jerome Brunet Cc: Russell King Cc: Michael Turquette Cc: Jeffrey Hugo Cc: Chen-Yu Tsai Signed-off-by: Stephen Boyd --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index c27cbd3bcb0a..2409241ad4ae 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -339,6 +339,8 @@ #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; }; qfprom@784000 {