From patchwork Wed Jan 25 11:53:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 92444 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp2170964qgi; Wed, 25 Jan 2017 03:53:40 -0800 (PST) X-Received: by 10.98.34.82 with SMTP id i79mr46018002pfi.120.1485345220278; Wed, 25 Jan 2017 03:53:40 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a71si23173056pfg.294.2017.01.25.03.53.40; Wed, 25 Jan 2017 03:53:40 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-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-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751827AbdAYLxg (ORCPT + 13 others); Wed, 25 Jan 2017 06:53:36 -0500 Received: from mailout4.w1.samsung.com ([210.118.77.14]:12923 "EHLO mailout4.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751411AbdAYLxd (ORCPT ); Wed, 25 Jan 2017 06:53:33 -0500 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 <0OKC002HM3P65U10@mailout4.w1.samsung.com>; Wed, 25 Jan 2017 11:53:31 +0000 (GMT) Received: from eusmges4.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170125115331eucas1p269d1de7919c63edfd81ef8b0ef680acb~dAZmKwihE1192611926eucas1p2O; Wed, 25 Jan 2017 11:53:31 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges4.samsung.com (EUCPMTA) with SMTP id 94.DB.28517.AB198885; Wed, 25 Jan 2017 11:53:30 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170125115330eucas1p16f9de097e0966bc9d9901bc27caa085c~dAZlfqYZZ2750227502eucas1p1x; Wed, 25 Jan 2017 11:53:30 +0000 (GMT) X-AuditID: cbfec7f4-f79716d000006f65-1d-588891bad65d Received: from eusync4.samsung.com ( [203.254.199.214]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 69.7F.06687.9F198885; Wed, 25 Jan 2017 11:54:33 +0000 (GMT) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync4.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OKC006PE3OZJVA0@eusync4.samsung.com>; Wed, 25 Jan 2017 11:53:30 +0000 (GMT) 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 v5 4/4] clk: samsung: exynos-audss: Use runtime PM Date: Wed, 25 Jan 2017 12:53:14 +0100 Message-id: <1485345194-3196-5-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1485345194-3196-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAAzWSa0hTcRjG9z+X7bg6dZhif8wkB35Ia2UsOGSa3fDoh8i+uISooQe1nMqO k6wPjuV1qalBzgwWlCEzb0udlJjNo9PUppim4CVSK8WhNimlqJzHvv1enue9PPASqMyF+REp aZmsNk2dKhdLsbbeTeeRV+WFqmODb0LpZlMjTn9c/4rTFbNlGO10Nklo69w4Tq8Vz+C0u4QH tMnZidD1/LSEHnl3ge5eLsDpjcF7GO2oj4skmZWJPAkzWlqCMFZLkZiZGu8QMy+f5TClLRbA uK0BlyTx0lOJbGpKFqs9GnFdmrzi6AcZxtO3zJ8WxHpgUxoBQUBKCV9UJRiB1xb6wuGZRrER SAkZVQOgmZ+XCIUbwImaMkxwKWH77/Yd4TmADUu2nRY9AhfrRoHHJaZCodFl3BZ8KAOA5U2N uKdAKQMKH3aWIx6XN3UWdsxPoh7GqCC4PLqGeI4iqSj4yx4trAuA/b0PcA97UQw02eq250Cq QQLn+SpcCHEAWrtQwX8e/njcCgT2hkuOFonA/rCo8C0i8H0ADXkhApsAfO8iBQ6D3Y6R7V0o tQdWtFWiwngSFubLBGTgav1O5xlom+4BQvZqAIcqx/Ay4P8EiCzAh9VxmiSWUyo4tYbTpSUp EtI1VrD1BAN/HOvt4GnvSTugCCDfTX5LLFDJcHUWl62xA0igch8yMrdQJSMT1dm3WW36Na0u leXsYD+ByfeRHU8+xMmoJHUme5NlM1jtfxUhvPz04FDHlZjLX3JtJ77zAeEhk+tIWJDieO0N Q1PU52LNED/J/KzQLJrPrR70DQsfVmiizT2pr2f6MBNvEFUu5B+emNdpi0dEqtiBrKt639UC crW+rHXvRnCs2LIJRDHVu+78rc3xwmfvJo819wW6igIfYbwzIr5LP3dR6h6eyqiRY1yyOjQY 1XLqf4JFf+sAAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnkeLIzCtJLcpLzFFi42I5/e/4Nd2fEzsiDPZtUrLYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHudlkpCampBYppOYl 56dk5qXbKoWGuOlaKCnkJeam2ipF6PqGBCkplCXmlAJ5RgZowME5wD1YSd8uwS3j/fGTjAVd 9hXzHzxla2DcbtLFyMkhIWAisePPDnYIW0ziwr31bF2MXBxCAksYJVacmcQI4TQxSdxe1MsK UsUmYCjR9bYLrEpEoIlR4knfNHYQh1mgjVnif8dXRpAqYQEniT1PbjKD2CwCqhJvLn9k6mLk 4OAVcJf4fcgTYp2cxMljk8GGcgp4SMzYvhrMFgIqubxkIeMERt4FjAyrGEVSS4tz03OLDfWK E3OLS/PS9ZLzczcxAiNj27Gfm3cwXtoYfIhRgINRiYd3QlJ7hBBrYllxZe4hRgkOZiURXoeW jggh3pTEyqrUovz4otKc1OJDjKZAN01klhJNzgdGbV5JvKGJobmloZGxhYW5kZGSOG/Jhyvh QgLpiSWp2ampBalFMH1MHJxSDYzyxbdNr06Kuf05uVI9VU0s5VS/oN+Nxfqxl/5E1k3yWcj5 Y0lAqUl25o4dGgu2zPKLjXKZJ5j0UedwyWWPqrpDxdKBN0r6/jbLd9tdS5kyf7uOgfRSA7uQ P/EhjAJbJlod2nyZ0f38cvGKda3dJ2o3LSjJ0t3l7JF3/Pr0pdqVC122lD78xavEUpyRaKjF XFScCAB952kPogIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170125115330eucas1p16f9de097e0966bc9d9901bc27caa085c X-Msg-Generator: CA X-Sender-IP: 182.198.249.179 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: 20170125115330eucas1p16f9de097e0966bc9d9901bc27caa085c X-RootMTR: 20170125115330eucas1p16f9de097e0966bc9d9901bc27caa085c References: <1485345194-3196-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@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 --- .../devicetree/bindings/clock/clk-exynos-audss.txt | 6 +++ drivers/clk/samsung/clk-exynos-audss.c | 62 +++++++++++++--------- 2 files changed, 43 insertions(+), 25 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-pm" 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 cb7df358a27d..070a82ee15f7 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 @@ -134,6 +135,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in; const struct exynos_audss_clk_drvdata *variant; struct resource *res; + struct device *dev = &pdev->dev; int i, ret = 0; variant = of_device_get_match_data(&pdev->dev); @@ -141,15 +143,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_table = devm_kzalloc(&pdev->dev, + clk_table = devm_kzalloc(dev, sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, GFP_KERNEL); if (!clk_table) @@ -158,8 +160,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) clk_data.clks = clk_table; clk_data.clk_num = variant->num_clks; - 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)) { @@ -170,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_register_mux(NULL, "mout_audss", + + /* + * Enable runtime PM here, so clock core with use runtime PM for all + * registered clocks. + */ + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + clk_table[EXYNOS_MOUT_AUDSS] = clk_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_register_mux(NULL, "mout_i2s", + clk_table[EXYNOS_MOUT_I2S] = clk_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_register_divider(NULL, "dout_srp", + clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(dev, "dout_srp", "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4, 0, &lock); - clk_table[EXYNOS_DOUT_AUD_BUS] = clk_register_divider(NULL, + clk_table[EXYNOS_DOUT_AUD_BUS] = clk_register_divider(dev, "dout_aud_bus", "dout_srp", 0, reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); - clk_table[EXYNOS_DOUT_I2S] = clk_register_divider(NULL, "dout_i2s", + clk_table[EXYNOS_DOUT_I2S] = clk_register_divider(dev, "dout_i2s", "mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0, &lock); - clk_table[EXYNOS_SRP_CLK] = clk_register_gate(NULL, "srp_clk", + clk_table[EXYNOS_SRP_CLK] = clk_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_register_gate(NULL, "i2s_bus", + clk_table[EXYNOS_I2S_BUS] = clk_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_register_gate(NULL, "sclk_i2s", + clk_table[EXYNOS_SCLK_I2S] = clk_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_register_gate(NULL, "pcm_bus", + clk_table[EXYNOS_PCM_BUS] = clk_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_register_gate(NULL, "sclk_pcm", + clk_table[EXYNOS_SCLK_PCM] = clk_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_register_gate(NULL, "adma", + clk_table[EXYNOS_ADMA] = clk_register_gate(dev, "adma", "dout_srp", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 9, 0, &lock); } for (i = 0; i < clk_data.clk_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_provider(pdev->dev.of_node, of_clk_src_onecell_get, + ret = of_clk_add_provider(dev->of_node, of_clk_src_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; } @@ -272,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 = {