From patchwork Wed Aug 9 10:35:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 9890279 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8EE4E60363 for ; Wed, 9 Aug 2017 10:35:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9E9E7289BB for ; Wed, 9 Aug 2017 10:35:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 932FF28A57; Wed, 9 Aug 2017 10:35:32 +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=-6.9 required=2.0 tests=BAYES_00,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 E6D8B289BB for ; Wed, 9 Aug 2017 10:35:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752415AbdHIKf3 (ORCPT ); Wed, 9 Aug 2017 06:35:29 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:20461 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751948AbdHIKfV (ORCPT ); Wed, 9 Aug 2017 06:35:21 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OUE00K2KYQSHF40@mailout3.w1.samsung.com>; Wed, 09 Aug 2017 11:35:16 +0100 (BST) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170809103516eucas1p2587b61481feb0085338f9ddb8a4de403~ZJxOsseJ21922219222eucas1p2h; Wed, 9 Aug 2017 10:35:16 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 8C.87.12907.365EA895; Wed, 9 Aug 2017 11:35:15 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170809103515eucas1p19fcbdd113e191cc02f9e5aaa469376d3~ZJxOES7_n2580025800eucas1p1S; Wed, 9 Aug 2017 10:35:15 +0000 (GMT) X-AuditID: cbfec7f1-f793a6d00000326b-9f-598ae5635869 Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 50.85.20118.365EA895; Wed, 9 Aug 2017 11:35:15 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OUE00IH6YQKHB00@eusync2.samsung.com>; Wed, 09 Aug 2017 11:35:15 +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 v8 5/5] clk: samsung: exynos-audss: Add support for runtime PM Date: Wed, 09 Aug 2017 12:35:07 +0200 Message-id: <1502274907-11931-6-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAAzWSXUhTcRjG/Z9ztp2NVoc57d80L0ZepGQqEQe/SCo4BZEiEbMLXXpQa36w qbS6aFpO3dJ0frTMi5I+ZCjTJZKgJs5c6twcgtnKaX5kyJbMSSSE5jzz7vfwPu/z8sCLo4JN TIQXFJXS8iKpTMzmYf3jO7YzOWsaSezXgfNkr97IIr9sr7NI3WIDRtrtPRzStDLHIr1PXCzS VzcGSL19GCG7xxY4pGPyMml2V7PIv1YtRlq6b17gU5vzVRxqtr4OoUyGWjb1fW6QTb1//ZCq 7zMAymeKSONk8pJyaVlBOS0/m5LNy1f3WpESdcI9r6MLUwFzrAZwcUicg/rOjyjDoXDGZWRr AA8XEG8AtG9YMEb4AJx5N4AdbuxZpwODtwAuuLQII1QIdNprgN/FJuKgxqM5yBISlQA29hhZ foESlShsHW5E/K5gIg0uGXxsP2NEJLRtDe2bcJxPUPBRxzXmXAScGG9i+ZlLXIHGdifqz4GE gQPdHjvm90PiJDSNBEpcgjP/mhGGg+GGpY/DcDicbdIGKjwFsLIqmmE9gDYPn+FEaLY4Dm6h xFGo63+GMvF8WKMWMBYKrjltbIZT4aeBikD5dgDblldBAwh/CYIMQEiXKQrzaEV8jEJaqCgr yovJKS40gf03mNq1eD+Azc8Jo4DAgfgIf36wViJgScsVysJRAHFULORfXdVIBPxcqfI+LS/O kpfJaMUoCMMx8XF+cqZaIiDypKX0XZouoeWHUwTnilQgXn9im4YjnW7H865267iHWrF7fw+m LCmTQ1JvJXbcyADpSaTOKWqLfiUPdel/Rcn+OB5vsId0e0E76Fqr6Gf6ncnd2+aFaW1vgzjk gbC1PwOhsiK9p5U/XMs0lZWW2zKhreB2LF5s3uIeq15Pn3KDbBn64pQqJyyh5fo3MabIl8ZF oXKF9D+2F+tCAgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42I5/e/4Fd3kp12RBl1tnBYbZ6xntbj+5Tmr xaT7E1gszp/fwG6x6fE1VouPPfdYLT73HmG0mHF+H5PF2iN32S0unnK1OPymndXix5luFovj a8MdeD3e32hl97jc18vksWlVJ5vHnWt72Dw2L6n36NuyitHj8ya5APYoN5uM1MSU1CKF1Lzk /JTMvHRbpdAQN10LJYW8xNxUW6UIXd+QICWFssScUiDPyAANODgHuAcr6dsluGW0bTzDVNBm VfHx4hqWBsbDBl2MnBwSAiYS/8+cZYGwxSQu3FvPBmILCSxhlNhyIriLkQvIbmKSuPV/NVgR m4ChRNfbLjaQhIhAE6PEk75p7CAOs0Abs8T/jq+MIFXCAn4SBy+9YgWxWQRUJc592gtkc3Dw CnhINC/yhdgmJ3Hy2GSwEk4BT4n1c24xQ2z2kLh3bBPLBEbeBYwMqxhFUkuLc9Nzi430ihNz i0vz0vWS83M3MQLjYtuxn1t2MHa9Cz7EKMDBqMTDe2NPZ6QQa2JZcWXuIUYJDmYlEV4xYFQJ 8aYkVlalFuXHF5XmpBYfYjQFumkis5Rocj4wZvNK4g1NDM0tDY2MLSzMjYyUxHnVLzdFCgmk J5akZqemFqQWwfQxcXBKNTBK7c7jz9p73MX9dMOJ86Jb7z159KKEJapz32nmqsg3ngEzOxdw 6G585dJ0tVL3y5YsgfPn5Lo5E97/tnU7XVEwvW9Wy4GME/27KpVv8JbGvpe6z/z2R2ze+Yln hb/rJDfGi2h8mFv1uTbr1AnRz6Jdps4G7gzRd7aXbPq2V7b5XsC5lV4C13YosRRnJBpqMRcV JwIAfzSdA6ECAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170809103515eucas1p19fcbdd113e191cc02f9e5aaa469376d3 X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?TWFyZWsgU3p5cHJvd3NraRtTUlBPTC1LZXJuZWwgKFRQKRs=?= =?UTF-8?B?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?TWFyZWsgU3p5cHJvd3NraRtTUlBPTC1LZXJuZWwgKFRQKRtT?= =?UTF-8?B?YW1zdW5nIEVsZWN0cm9uaWNzG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170809103515eucas1p19fcbdd113e191cc02f9e5aaa469376d3 X-RootMTR: 20170809103515eucas1p19fcbdd113e191cc02f9e5aaa469376d3 References: <1502274907-11931-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 X-Virus-Scanned: ClamAV using ClamSMTP 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 Reviewed-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi --- .../devicetree/bindings/clock/clk-exynos-audss.txt | 6 +++ drivers/clk/samsung/clk-exynos-audss.c | 51 ++++++++++++++-------- 2 files changed, 40 insertions(+), 17 deletions(-) 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 6be52fb46ff3..ab494c104ce6 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; @@ -179,7 +178,18 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) } } } - 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. Additionally, we increase the runtime + * PM usage count before registering the clocks, to prevent the + * clock core from runtime suspending the device. + */ + pm_runtime_get_noresume(dev); + 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); @@ -190,48 +200,48 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) 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(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); } @@ -251,10 +261,14 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) goto unregister; } + pm_runtime_put_sync(dev); + return 0; unregister: exynos_audss_clk_teardown(); + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); if (!IS_ERR(epll)) clk_disable_unprepare(epll); @@ -267,6 +281,7 @@ static int exynos_audss_clk_remove(struct platform_device *pdev) of_clk_del_provider(pdev->dev.of_node); exynos_audss_clk_teardown(); + pm_runtime_disable(&pdev->dev); if (!IS_ERR(epll)) clk_disable_unprepare(epll); @@ -275,8 +290,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 = {