From patchwork Fri Sep 21 15:20:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Brandt X-Patchwork-Id: 10610473 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 BEEF65A4 for ; Fri, 21 Sep 2018 15:21:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF5962E4A6 for ; Fri, 21 Sep 2018 15:21:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A2CB02E4CA; Fri, 21 Sep 2018 15:21: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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EE6112E4AB for ; Fri, 21 Sep 2018 15:21:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390387AbeIUVKf (ORCPT ); Fri, 21 Sep 2018 17:10:35 -0400 Received: from relmlor3.renesas.com ([210.160.252.173]:54388 "EHLO relmlie2.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2390267AbeIUVKf (ORCPT ); Fri, 21 Sep 2018 17:10:35 -0400 Received: from unknown (HELO relmlir1.idc.renesas.com) ([10.200.68.151]) by relmlie2.idc.renesas.com with ESMTP; 22 Sep 2018 00:21:11 +0900 Received: from relmlii2.idc.renesas.com (relmlii2.idc.renesas.com [10.200.68.66]) by relmlir1.idc.renesas.com (Postfix) with ESMTP id C604F854D9; Sat, 22 Sep 2018 00:21:11 +0900 (JST) X-IronPort-AV: E=Sophos;i="5.54,285,1534777200"; d="scan'208";a="293152790" Received: from unknown (HELO rtamta01.rta.renesas.com) ([143.103.48.75]) by relmlii2.idc.renesas.com with ESMTP; 22 Sep 2018 00:21:10 +0900 Received: from ubuntu.localdomain (unknown [143.103.58.47]) by rtamta01.rta.renesas.com (Postfix) with ESMTP id 0668E1FF; Fri, 21 Sep 2018 15:21:06 +0000 (UTC) From: Chris Brandt To: Geert Uytterhoeven , Michael Turquette , Stephen Boyd Cc: linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Simon Horman , Chris Brandt Subject: [PATCH 1/2] clk: renesas: cpg-mssr: Add early clock support Date: Fri, 21 Sep 2018 10:20:53 -0500 Message-Id: <20180921152054.117774-2-chris.brandt@renesas.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180921152054.117774-1-chris.brandt@renesas.com> References: <20180921152054.117774-1-chris.brandt@renesas.com> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support for SoCs that need to register core and module clocks early in order to use OF drivers that exclusively use macros such as TIMER_OF_DECLARE. Signed-off-by: Chris Brandt --- drivers/clk/renesas/renesas-cpg-mssr.c | 106 ++++++++++++++++++++++++++------- drivers/clk/renesas/renesas-cpg-mssr.h | 6 ++ 2 files changed, 91 insertions(+), 21 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 3df764d3ab20..b4be3cc18505 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -127,6 +127,7 @@ struct cpg_mssr_priv { struct device *dev; void __iomem *base; spinlock_t rmw_lock; + struct device_node *np; struct clk **clks; unsigned int num_core_clks; @@ -141,6 +142,7 @@ struct cpg_mssr_priv { } smstpcr_saved[ARRAY_SIZE(smstpcr)]; }; +struct cpg_mssr_priv *early_priv; /** * struct mstp_clock - MSTP gating clock @@ -316,7 +318,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, switch (core->type) { case CLK_TYPE_IN: - clk = of_clk_get_by_name(priv->dev->of_node, core->name); + clk = of_clk_get_by_name(priv->np, core->name); break; case CLK_TYPE_FF: @@ -877,42 +879,49 @@ static const struct dev_pm_ops cpg_mssr_pm = { #define DEV_PM_OPS NULL #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */ -static int __init cpg_mssr_probe(struct platform_device *pdev) +static int cpg_mssr_common_init(struct device *dev, struct device_node *np, + const struct cpg_mssr_info *info) { - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - const struct cpg_mssr_info *info; struct cpg_mssr_priv *priv; unsigned int nclks, i; - struct resource *res; - struct clk **clks; + struct clk **clks = NULL; int error; + bool early_init = dev ? false : true; - info = of_device_get_match_data(dev); if (info->init) { error = info->init(dev); if (error) return error; } - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + /* np is saved because dev->of_node doesn't exists during early init */ + priv->np = np; + priv->dev = dev; spin_lock_init(&priv->rmw_lock); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); + priv->base = of_iomap(np, 0); + if (IS_ERR(priv->base)) { + error = PTR_ERR(priv->base); + goto out_err; + } nclks = info->num_total_core_clks + info->num_hw_mod_clks; - clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); - if (!clks) - return -ENOMEM; + clks = kmalloc_array(nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) { + error = -ENOMEM; + goto out_err; + } + + if (early_init) + early_priv = priv; + else + dev_set_drvdata(dev, priv); - dev_set_drvdata(dev, priv); priv->clks = clks; priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; @@ -923,16 +932,71 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) for (i = 0; i < nclks; i++) clks[i] = ERR_PTR(-ENOENT); + error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); + if (error) + goto out_err; + + return 0; + +out_err: + kfree(clks); + if (priv->base) + iounmap(priv->base); + kfree(priv); + + return error; +} + +void __init cpg_mssr_early_init(struct device_node *np, + const struct cpg_mssr_info *info) +{ + int error; + int i; + + error = cpg_mssr_common_init(NULL, np, info); + if (error) + return; + + for (i = 0; i < info->num_early_core_clks; i++) + cpg_mssr_register_core_clk(&info->early_core_clks[i], info, + early_priv); + + for (i = 0; i < info->num_early_mod_clks; i++) + cpg_mssr_register_mod_clk(&info->early_mod_clks[i], info, + early_priv); + +} + +static int __init cpg_mssr_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct cpg_mssr_info *info; + struct cpg_mssr_priv *priv; + unsigned int i; + int error; + + info = of_device_get_match_data(dev); + + if (early_priv) { + priv = early_priv; + priv->dev = &pdev->dev; + } else { + error = cpg_mssr_common_init(dev, dev->of_node, info); + } + + if (error) + return error; + + if (!early_priv) + dev_set_drvdata(dev, priv); + for (i = 0; i < info->num_core_clks; i++) cpg_mssr_register_core_clk(&info->core_clks[i], info, priv); for (i = 0; i < info->num_mod_clks; i++) cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv); - error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); - if (error) - return error; - error = devm_add_action_or_reset(dev, cpg_mssr_del_clk_provider, np); diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index ae0ab0f164f3..cfce0627b5b8 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -119,12 +119,16 @@ struct cpg_mssr_info { unsigned int num_core_clks; unsigned int last_dt_core_clk; unsigned int num_total_core_clks; + const struct cpg_core_clk *early_core_clks; + unsigned int num_early_core_clks; bool stbyctrl; /* Module Clocks */ const struct mssr_mod_clk *mod_clks; unsigned int num_mod_clks; unsigned int num_hw_mod_clks; + const struct mssr_mod_clk *early_mod_clks; + unsigned int num_early_mod_clks; /* Critical Module Clocks that should not be disabled */ const unsigned int *crit_mod_clks; @@ -160,6 +164,8 @@ extern const struct cpg_mssr_info r8a77980_cpg_mssr_info; extern const struct cpg_mssr_info r8a77990_cpg_mssr_info; extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; +void __init cpg_mssr_early_init(struct device_node *np, + const struct cpg_mssr_info *info); /* * Helpers for fixing up clock tables depending on SoC revision