From patchwork Thu May 28 18:53:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 6501421 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2F16AC0433 for ; Thu, 28 May 2015 19:37:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1B1E620767 for ; Thu, 28 May 2015 19:37:48 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3F1F22075F for ; Thu, 28 May 2015 19:37:43 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Yy3Zt-0007KL-Lp; Thu, 28 May 2015 19:34:53 +0000 Received: from merlin.infradead.org ([2001:4978:20e::2]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Yy3Zr-0007K3-N4 for linux-arm-kernel@bombadil.infradead.org; Thu, 28 May 2015 19:34:51 +0000 Received: from winston.telenet-ops.be ([195.130.137.75]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Yy2we-0006Ew-2d for linux-arm-kernel@lists.infradead.org; Thu, 28 May 2015 18:54:22 +0000 Received: from albert.telenet-ops.be (albert.telenet-ops.be [195.130.137.90]) by winston.telenet-ops.be (Postfix) with ESMTP id 3ECD81BDC88 for ; Thu, 28 May 2015 20:53:56 +0200 (CEST) Received: from ayla.of.borg ([84.193.93.87]) by albert.telenet-ops.be with bizsmtp id ZWtj1q00M1t5w8s06WtjmM; Thu, 28 May 2015 20:53:52 +0200 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1Yy2w3-0001hV-EZ; Thu, 28 May 2015 20:53:43 +0200 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1Yy2w9-00008Z-SN; Thu, 28 May 2015 20:53:49 +0200 From: Geert Uytterhoeven To: Mike Turquette , Stephen Boyd , Simon Horman , Magnus Damm , Laurent Pinchart , "Rafael J. Wysocki" , Kevin Hilman , Ulf Hansson Subject: [PATCH v2 01/14] clk: shmobile: Add CPG Clock Domain support Date: Thu, 28 May 2015 20:53:26 +0200 Message-Id: <1432839219-475-2-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1432839219-475-1-git-send-email-geert+renesas@glider.be> References: <1432839219-475-1-git-send-email-geert+renesas@glider.be> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150528_145420_469399_7D6D96AD X-CRM114-Status: GOOD ( 18.57 ) X-Spam-Score: -1.9 (-) Cc: devicetree@vger.kernel.org, Geert Uytterhoeven , linux-sh@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add Clock Domain support to the Clock Pulse Generator (CPG) Module Stop (MSTP) Clocks driver using the generic PM Domain. This allows to power-manage the module clocks of SoC devices that are part of the CPG Clock Domain using Runtime PM, or for system suspend/resume. SoC devices that are part of a CPG Clock Domain and can be power-managed through an MSTP clock should be tagged in DT with a proper "power-domains" property. The CPG Clock Domain code will scan such devices for clocks that are suitable for power-managing the device, by looking for a clock that is compatible with "renesas,cpg-mstp-clocks". Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Reviewed-by: Ulf Hansson Reviewed-by: Kevin Hilman --- v2: - Add Acked-by and Reviewed-by, - Move core CPG Clock Domain code from the R-Car Gen2 driver to the CPG MSTP Clocks driver, as it's generic, and can be used on other Renesas SoCs that have a CPG/MSTP block, - Scan for an MSTP clock instead of using the first clock tied to the device (con_id NULL), - Extract R-Car Gen2 specifics to a separate patch. --- drivers/clk/shmobile/clk-mstp.c | 86 ++++++++++++++++++++++++++++++++++++ drivers/clk/shmobile/clk-rcar-gen2.c | 2 + include/linux/clk/shmobile.h | 12 +++++ 3 files changed, 100 insertions(+) diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c index 2d2fe773ac8168f9..619f3eccefd4884f 100644 --- a/drivers/clk/shmobile/clk-mstp.c +++ b/drivers/clk/shmobile/clk-mstp.c @@ -2,6 +2,7 @@ * R-Car MSTP clocks * * Copyright (C) 2013 Ideas On Board SPRL + * Copyright (C) 2015 Glider bvba * * Contact: Laurent Pinchart * @@ -12,9 +13,13 @@ #include #include +#include +#include #include #include #include +#include +#include #include /* @@ -236,3 +241,84 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, &group->data); } CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init); + + +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF +int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev) +{ + struct device_node *np = dev->of_node; + struct of_phandle_args clkspec; + struct clk *clk; + int i = 0; + int error; + + while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, + &clkspec)) { + if (of_device_is_compatible(clkspec.np, + "renesas,cpg-mstp-clocks")) + goto found; + + of_node_put(clkspec.np); + i++; + } + + return 0; + +found: + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + error = pm_clk_create(dev); + if (error) { + dev_err(dev, "pm_clk_create failed %d\n", error); + goto fail_put; + } + + error = pm_clk_add_clk(dev, clk); + if (error) { + dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); + goto fail_destroy; + } + + return 0; + +fail_destroy: + pm_clk_destroy(dev); +fail_put: + clk_put(clk); + return error; +} + +void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev) +{ + pm_clk_destroy(dev); +} + +void __init cpg_mstp_add_clk_domain(struct device_node *np) +{ + struct generic_pm_domain *pd; + u32 ncells; + + if (of_property_read_u32(np, "#power-domain-cells", &ncells)) { + pr_warn("%s lacks #power-domain-cells. Clocks may fail.\n", + np->full_name); + return; + } + + pd = kzalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) + return; + + pd->name = np->name; + + pd->flags = GENPD_FLAG_PM_CLK; + pm_genpd_init(pd, &simple_qos_governor, false); + pd->attach_dev = cpg_mstp_attach_dev; + pd->detach_dev = cpg_mstp_detach_dev; + + of_genpd_add_provider_simple(np, pd); +} +#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */ diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c index acfb6d7dbd6bc049..c7fde69d455e38c4 100644 --- a/drivers/clk/shmobile/clk-rcar-gen2.c +++ b/drivers/clk/shmobile/clk-rcar-gen2.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include struct rcar_gen2_cpg { diff --git a/include/linux/clk/shmobile.h b/include/linux/clk/shmobile.h index 63a8159c4e64153d..cb19cc1865ca5cfb 100644 --- a/include/linux/clk/shmobile.h +++ b/include/linux/clk/shmobile.h @@ -16,8 +16,20 @@ #include +struct device; +struct device_node; +struct generic_pm_domain; + void r8a7778_clocks_init(u32 mode); void r8a7779_clocks_init(u32 mode); void rcar_gen2_clocks_init(u32 mode); +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF +void cpg_mstp_add_clk_domain(struct device_node *np); +int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev); +void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev); +#else +static inline void cpg_mstp_add_clk_domain(struct device_node *np) {} +#endif + #endif