From patchwork Fri Aug 4 09:34:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 109388 Delivered-To: patch@linaro.org Received: by 10.182.109.195 with SMTP id hu3csp1121196obb; Fri, 4 Aug 2017 02:35:25 -0700 (PDT) X-Received: by 10.98.160.146 with SMTP id p18mr1776322pfl.322.1501839325157; Fri, 04 Aug 2017 02:35:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501839325; cv=none; d=google.com; s=arc-20160816; b=ex9KDibMGRscCcXyR0P0cG04TqC0OiSVfYeMHUa89v8W7aRuJsX9D4CqWRaAQS5Qmk heIeI6aryzx+tAMnj88Qc4MkJgUV9aK8ZDMJNGIwpJMi3RdSuQI9vdHbEBnXXJp54eNE gpeXOEdM1sEm9+RY2GQTdXFc6JSk9cur24H2ro4FUfl5x3dQAENE9hL8tjlhlpLS5i66 T8rTndcNCNsWy2SSOcjh0fO94czmugwrEt4gWldQdQ6JQdHsI+/q/LMbG4ZJq4axnzmJ povtciSo1sGJqc8Ui6VFHYvAwqQEGv7q0Ql4L7NZ13Qe5tsQpy9H7e/ZVDlRrYGZb7XL oN0Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:cms-type:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=qMCkEtIEelc9As1IILBdgPw6Gsa6r86v2y7KJSlwggI=; b=0yv/a7re6xsM8rMjdjgW6F5VcIqXHYKvT+hpSskH9bi/VerJScCyiNYkvhEOd8Wg5J 3kRjxXMHmhHYJD4HGi1C+jZBIs8PEq37RpMv1vMrUMzU8Uc/1hyknPVqw3wz0nB6opRY n1wddqQ3EaehOgi6QIdAbe7a+x7AV1SrlXKnU0gZjXdXXelqOjY7d7i2iy+RfA0QDK1l ggcxEguKgKQGU0eAWnCGm/G3rQBAcsSJFMstUfcMy0ibuRprw2Q5dZm1VMIzvhXYxShB iqcETLXsvoO8F6xj/7dHggOgRNx0E/3dTHBByXDshHo4JUT66zoYfbzNqBuUYQXLdtW+ s+gA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-samsung-soc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-samsung-soc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=samsung.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k2si735480pgs.179.2017.08.04.02.35.24; Fri, 04 Aug 2017 02:35:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-samsung-soc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-samsung-soc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-samsung-soc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752093AbdHDJfX (ORCPT + 4 others); Fri, 4 Aug 2017 05:35:23 -0400 Received: from mailout4.w1.samsung.com ([210.118.77.14]:37709 "EHLO mailout4.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751319AbdHDJfV (ORCPT ); Fri, 4 Aug 2017 05:35:21 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OU50014HMMUNA80@mailout4.w1.samsung.com>; Fri, 04 Aug 2017 10:35:18 +0100 (BST) Received: from eusmges5.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170804093517eucas1p26762b7d811d79e5ebe43b36327ae3d9f~XmucKjMUp0093700937eucas1p2S; Fri, 4 Aug 2017 09:35:17 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges5.samsung.com (EUCPMTA) with SMTP id E7.0A.25577.5DF34895; Fri, 4 Aug 2017 10:35:17 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170804093517eucas1p2387158f22f90a2a124d6a87d2076267c~XmubZYd8D2223522235eucas1p2T; Fri, 4 Aug 2017 09:35:17 +0000 (GMT) X-AuditID: cbfec7f5-f792f6d0000063e9-d9-59843fd584f9 Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id AA.3B.20206.4DF34895; Fri, 4 Aug 2017 10:35:16 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OU50004IMMJTPA0@eusync3.samsung.com>; Fri, 04 Aug 2017 10:35:16 +0100 (BST) From: Marek Szyprowski To: linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Marek Szyprowski , Stephen Boyd , Michael Turquette , Ulf Hansson , Sylwester Nawrocki , Chanwoo Choi , Inki Dae , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [PATCH v7 4/4] clk: samsung: exynos-audss: Use runtime PM Date: Fri, 04 Aug 2017 11:34:54 +0200 Message-id: <1501839294-478-5-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1501839294-478-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrHIsWRmVeSWpSXmKPExsWy7djP87pX7VsiDV4tVbbYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHcdmkpOZklqUW6dsl cGW07LrHVtDnVnHyAlcDY69VFyMHh4SAicSTR2JdjJxAppjEhXvr2boYuTiEBJYySjT3LYVy PjNKHJg/gwmiCqjh+BR2iMQyRol3hx6wQjgNTBLt3fcYQarYBAwlut52gbWLCDQxSkzcsB6s ilmgiVli2r6JYLOEBZwk1t2dwQxiswioStya/g2sm1fATeLI2iMsEPvkJE4em8wKYnMKuEvM /NUINlVCYBW7xPev11khvpCV2HSAGaLeRWLf8bmsELawxKvjW9ghbBmJy5O7oWb2M0o0tWpD 2DMYJc695YWwrSUOH78I1ssswCcxadt0ZojxvBIdbUIQJR4SXY/fs0HYjhIb1txkgvh+FqPE p4UHWCcwyixgZFjFKJJaWpybnlpsqlecmFtcmpeul5yfu4kRmApO/zv+dQfj0mNWhxgFOBiV eHgNZjRHCrEmlhVX5h5ilOBgVhLhZVRpiRTiTUmsrEotyo8vKs1JLT7EKM3BoiTOy3XqWoSQ QHpiSWp2ampBahFMlomDU6qBMVv6/CaRqyvTdRbLbZ67e7aibfTkxB3KUkW5AvGGr2pzzoX8 S3C7ZrAnV2mz/BemZlXtSqeNh97qVPcUTp6ml/DdYpVfypNl+6NCfHY3rzusb7nDYFnMjAkP e2pP7NrZfa9DYPWN7N/Rdat6r9UfeLNic69dqvvZOtaJt1L4VR5cn5j/tsPsghJLcUaioRZz UXEiAL3cjVYBAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42I5/e/4Vd0r9i2RBh3X9Cw2zljPanH9y3NW i0n3J7BYnD+/gd1i0+NrrBYfe+6xWnzuPcJoMeP8PiaLtUfusltcPOVqcfhNO6vFjzPdLBbH 14Y78Hq8v9HK7nG5r5fJY9OqTjaPO9f2sHlsXlLv0bdlFaPH501yAexRbjYZqYkpqUUKqXnJ +SmZeem2SqEhbroWSgp5ibmptkoRur4hQUoKZYk5pUCekQEacHAOcA9W0rdLcMto2XWPraDP reLkBa4Gxl6rLkZODgkBE4knx6ewQ9hiEhfurWfrYuTiEBJYwihx+kgfI0hCSKCJSeLnTGMQ m03AUKLrbRdYkYhAE6PEk75p7CAOs0Abs8T/jq9gHcICThLr7s5gBrFZBFQlbk3/BhbnFXCT OLL2CAvEOjmJk8cms4LYnALuEjN/NbJBbHOT2HThAeMERt4FjAyrGEVSS4tz03OLjfSKE3OL S/PS9ZLzczcxAuNi27GfW3Ywdr0LPsQowMGoxMNrMKM5Uog1say4MvcQowQHs5IIL6NKS6QQ b0piZVVqUX58UWlOavEhRlOgoyYyS4km5wNjNq8k3tDE0NzS0MjYwsLcyEhJnFf9clOkkEB6 YklqdmpqQWoRTB8TB6dUA+O1Cd9ua+6ZoK4/7T2XqJaowo/nzt3lexnOLz+Qus4+ZJvBMqm9 hUu43xjd8D3q9WWBl5mbqGrS3Nqd8j8t1NbyT56y4pjDnomnF0/sbEh5e3l/7yT5GT98nm4L 9Pp8O2WJ3EtGu9051Wme1xm5xaO+/c/dXhlS+NHO6rErs+QW8dSLG35MOVypxFKckWioxVxU nAgA/7PzcaECAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170804093517eucas1p2387158f22f90a2a124d6a87d2076267c X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?utf-8?q?Marek_Szyprowski=1BSRPOL-Kernel_=28TP=29=1B?= =?utf-8?b?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?utf-8?q?Marek_Szyprowski=1BSRPOL-Kernel_=28TP=29=1BSam?= =?utf-8?q?sung_Electronics=1BSenior_Software_Engineer?= X-Sender-Code: =?utf-8?q?C10=1BEHQ=1BC10CD02CD027392?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170804093517eucas1p2387158f22f90a2a124d6a87d2076267c X-RootMTR: 20170804093517eucas1p2387158f22f90a2a124d6a87d2076267c References: <1501839294-478-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org This patch adds support for runtime PM to Exynos Audio SubSystem driver to enable full support for audio power domain on Exynos5 SoCs. The main change is moving register saving and restoring code from system sleep PM ops to runtime PM ops and implementing system sleep PM ops with generic pm_runtime_force_suspend/resume helpers. Runtime PM of the Exynos AudSS device is managed from clock core depending on the preparation status of the provided clocks. Signed-off-by: Marek Szyprowski Reviewed-by: Ulf Hansson --- .../devicetree/bindings/clock/clk-exynos-audss.txt | 6 ++ drivers/clk/samsung/clk-exynos-audss.c | 68 +++++++++++++--------- 2 files changed, 45 insertions(+), 29 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt index 0c3d6015868d..f3635d5aeba4 100644 --- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt +++ b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt @@ -33,6 +33,12 @@ Required Properties: - clock-names: Aliases for the above clocks. They should be "pll_ref", "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively. +Optional Properties: + + - power-domains: a phandle to respective power domain node as described by + generic PM domain bindings (see power/power_domain.txt for more + information). + The following is the list of clocks generated by the controller. Each clock is assigned an identifier and client nodes use this identifier to specify the clock which they consume. Some of the clocks are available only on a particular diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index 1fab56f396d4..a754c91d6ef3 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -36,14 +37,13 @@ #define ASS_CLK_DIV 0x4 #define ASS_CLK_GATE 0x8 -#ifdef CONFIG_PM_SLEEP static unsigned long reg_save[][2] = { { ASS_CLK_SRC, 0 }, { ASS_CLK_DIV, 0 }, { ASS_CLK_GATE, 0 }, }; -static int exynos_audss_clk_suspend(struct device *dev) +static int __maybe_unused exynos_audss_clk_suspend(struct device *dev) { int i; @@ -53,7 +53,7 @@ static int exynos_audss_clk_suspend(struct device *dev) return 0; } -static int exynos_audss_clk_resume(struct device *dev) +static int __maybe_unused exynos_audss_clk_resume(struct device *dev) { int i; @@ -62,7 +62,6 @@ static int exynos_audss_clk_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM_SLEEP */ struct exynos_audss_clk_drvdata { unsigned int has_adma_clk:1; @@ -135,6 +134,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) const struct exynos_audss_clk_drvdata *variant; struct clk_hw **clk_table; struct resource *res; + struct device *dev = &pdev->dev; int i, ret = 0; variant = of_device_get_match_data(&pdev->dev); @@ -142,15 +142,15 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) return -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - reg_base = devm_ioremap_resource(&pdev->dev, res); + reg_base = devm_ioremap_resource(dev, res); if (IS_ERR(reg_base)) { - dev_err(&pdev->dev, "failed to map audss registers\n"); + dev_err(dev, "failed to map audss registers\n"); return PTR_ERR(reg_base); } epll = ERR_PTR(-ENODEV); - clk_data = devm_kzalloc(&pdev->dev, + clk_data = devm_kzalloc(dev, sizeof(*clk_data) + sizeof(*clk_data->hws) * EXYNOS_AUDSS_MAX_CLKS, GFP_KERNEL); @@ -160,8 +160,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) clk_data->num = variant->num_clks; clk_table = clk_data->hws; - pll_ref = devm_clk_get(&pdev->dev, "pll_ref"); - pll_in = devm_clk_get(&pdev->dev, "pll_in"); + pll_ref = devm_clk_get(dev, "pll_ref"); + pll_in = devm_clk_get(dev, "pll_in"); if (!IS_ERR(pll_ref)) mout_audss_p[0] = __clk_get_name(pll_ref); if (!IS_ERR(pll_in)) { @@ -172,81 +172,89 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) ret = clk_prepare_enable(epll); if (ret) { - dev_err(&pdev->dev, + dev_err(dev, "failed to prepare the epll clock\n"); return ret; } } } - clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss", + + /* + * Enable runtime PM here to allow the clock core using runtime PM + * for the registered clocks. + */ + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(dev, "mout_audss", mout_audss_p, ARRAY_SIZE(mout_audss_p), CLK_SET_RATE_NO_REPARENT, reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); - cdclk = devm_clk_get(&pdev->dev, "cdclk"); - sclk_audio = devm_clk_get(&pdev->dev, "sclk_audio"); + cdclk = devm_clk_get(dev, "cdclk"); + sclk_audio = devm_clk_get(dev, "sclk_audio"); if (!IS_ERR(cdclk)) mout_i2s_p[1] = __clk_get_name(cdclk); if (!IS_ERR(sclk_audio)) mout_i2s_p[2] = __clk_get_name(sclk_audio); - clk_table[EXYNOS_MOUT_I2S] = clk_hw_register_mux(NULL, "mout_i2s", + clk_table[EXYNOS_MOUT_I2S] = clk_hw_register_mux(dev, "mout_i2s", mout_i2s_p, ARRAY_SIZE(mout_i2s_p), CLK_SET_RATE_NO_REPARENT, reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); - clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp", + clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(dev, "dout_srp", "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4, 0, &lock); - clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL, + clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(dev, "dout_aud_bus", "dout_srp", 0, reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); - clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s", + clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(dev, "dout_i2s", "mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0, &lock); - clk_table[EXYNOS_SRP_CLK] = clk_hw_register_gate(NULL, "srp_clk", + clk_table[EXYNOS_SRP_CLK] = clk_hw_register_gate(dev, "srp_clk", "dout_srp", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 0, 0, &lock); - clk_table[EXYNOS_I2S_BUS] = clk_hw_register_gate(NULL, "i2s_bus", + clk_table[EXYNOS_I2S_BUS] = clk_hw_register_gate(dev, "i2s_bus", "dout_aud_bus", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 2, 0, &lock); - clk_table[EXYNOS_SCLK_I2S] = clk_hw_register_gate(NULL, "sclk_i2s", + clk_table[EXYNOS_SCLK_I2S] = clk_hw_register_gate(dev, "sclk_i2s", "dout_i2s", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 3, 0, &lock); - clk_table[EXYNOS_PCM_BUS] = clk_hw_register_gate(NULL, "pcm_bus", + clk_table[EXYNOS_PCM_BUS] = clk_hw_register_gate(dev, "pcm_bus", "sclk_pcm", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 4, 0, &lock); - sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in"); + sclk_pcm_in = devm_clk_get(dev, "sclk_pcm_in"); if (!IS_ERR(sclk_pcm_in)) sclk_pcm_p = __clk_get_name(sclk_pcm_in); - clk_table[EXYNOS_SCLK_PCM] = clk_hw_register_gate(NULL, "sclk_pcm", + clk_table[EXYNOS_SCLK_PCM] = clk_hw_register_gate(dev, "sclk_pcm", sclk_pcm_p, CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 5, 0, &lock); if (variant->has_adma_clk) { - clk_table[EXYNOS_ADMA] = clk_hw_register_gate(NULL, "adma", + clk_table[EXYNOS_ADMA] = clk_hw_register_gate(dev, "adma", "dout_srp", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 9, 0, &lock); } for (i = 0; i < clk_data->num; i++) { if (IS_ERR(clk_table[i])) { - dev_err(&pdev->dev, "failed to register clock %d\n", i); + dev_err(dev, "failed to register clock %d\n", i); ret = PTR_ERR(clk_table[i]); goto unregister; } } - ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get, + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, clk_data); if (ret) { - dev_err(&pdev->dev, "failed to add clock provider\n"); + dev_err(dev, "failed to add clock provider\n"); goto unregister; } @@ -274,8 +282,10 @@ static int exynos_audss_clk_remove(struct platform_device *pdev) } static const struct dev_pm_ops exynos_audss_clk_pm_ops = { - SET_LATE_SYSTEM_SLEEP_PM_OPS(exynos_audss_clk_suspend, - exynos_audss_clk_resume) + SET_RUNTIME_PM_OPS(exynos_audss_clk_suspend, exynos_audss_clk_resume, + NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) }; static struct platform_driver exynos_audss_clk_driver = {