From patchwork Fri Dec 30 13:33:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 9492137 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 0418362ABB for ; Fri, 30 Dec 2016 13:34:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F00E6203C0 for ; Fri, 30 Dec 2016 13:33:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E4B1F22689; Fri, 30 Dec 2016 13:33:59 +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 46AAD203C0 for ; Fri, 30 Dec 2016 13:33:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754132AbcL3Nd6 (ORCPT ); Fri, 30 Dec 2016 08:33:58 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:20601 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754128AbcL3Ndv (ORCPT ); Fri, 30 Dec 2016 08:33:51 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OJ00051430CDOA0@mailout2.w1.samsung.com>; Fri, 30 Dec 2016 13:33:48 +0000 (GMT) Received: from eusmges5.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20161230133347eucas1p2400ba87a47336e1e741fcabc2b1fadc8~VC-uiSoWg1338613386eucas1p2n; Fri, 30 Dec 2016 13:33:47 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges5.samsung.com (EUCPMTA) with SMTP id AC.D1.10572.B3266685; Fri, 30 Dec 2016 13:33:47 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20161230133346eucas1p1d5ce770573dcd5dcf7ad5ed0bf338f71~VC-twwiBo2281422814eucas1p1w; Fri, 30 Dec 2016 13:33:46 +0000 (GMT) X-AuditID: cbfec7f5-f79676d00000294c-e6-5866623be41f Received: from eusync4.samsung.com ( [203.254.199.214]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 98.6B.06573.E2266685; Fri, 30 Dec 2016 13:33:34 +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 <0OJ00051Q304AG90@eusync4.samsung.com>; Fri, 30 Dec 2016 13:33:46 +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 v4 4/4] clk: samsung: exynos-audss: Use runtime PM Date: Fri, 30 Dec 2016 14:33:36 +0100 Message-id: <1483104816-20885-5-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1483104816-20885-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAAzWSa0hTYRjHe7dztuPo2HFKPpqKDfpQoSWoHDJEJfEUBNEXRxC69HhBnbbj LPfBRPI275d0lolUWk5EPXkDRWXKllYutUwyNagQwlXetTDSHf32e3h+//8DLy8hlv/E3IlE dTqrUauSFRIZ1mPesfoE3YpTni/Wu9Gdhnac/ri+hNOVi+UYbbV2SGn+6wxOrxQv4PRaySii DdZBEd02Oi+lJ8fD6ZHlfJzeflOE0Za2yBCS+TWbK2WmS0tEDG8slDCfZwYkzMtn95jSLiNi 1niva9IbsouxbHJiBqs5FxwtS5ibKsDSJkLubk2OoWz0JUCPHAig/KF7clci8HF4t9C+xzJC TjUh+GD+joRhDcF8by46TAxbW3Bh0YyAXy/DhCFbBHO7udi+JaH8QG/T27tcqBwEFR3t9oiY yhFDzWCFaN9ypsLAVldrZ4w6BXnG1T2JIEiKAWtThHDOC8bMVfg+O1CX4f7Olr0UKKMUhgpa 0L4PlCfww2IBL0Fna7gQdYYfli6pwB4wXVWECVyGICf3rMAGBBM2UuAgGLFM2k+JKUeo7Kk9 qCShIE8uKAz09q+IBA6F7YbigxeqR/C8pkNajjwa0REjcmG1XEo8ywX4cqoUTquO941JTeHR 3i94/c+y0YeazBdMiCKQ4ii5ncEq5bgqg8tMMSEgxAoXsi8qTiknY1WZOlaTGqXRJrOcCZ0g MIUrOdD4PlJOxavS2SSWTWM1h1sR4eCejQbetjo58aW70e0G+nGDehH8+RlPx6cNthUmdXop qGiIMC14ZSsDH1T7nIwJzv+9qcV7dE/GdWF3XhRqu3s3IrLC+hK8b18PXQal7sqf+lm6uv6R 91BWvyvXHez/TdfWUud2+lN9WeTU5sPVJ+JMQ/PVwmN/m28mBRa90ke14QqMS1D5nRFrONV/ PSSvqwEDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnkeLIzCtJLcpLzFFi42I5/e/4NV29pLQIgw075Cw2zljPanH9y3NW i0n3J7BYnD+/gd1i0+NrrBYfe+6xWnzuPcJoMeP8PiaLtUfusltcPOVqcfhNO6vFjzPdLBbH 14Y78Hq8v9HK7nG5r5fJY9OqTjaPO9f2sHlsXlLv0bdlFaPH501yAexRbjYZqYkpqUUKqXnJ +SmZeem2SqEhbroWSgp5ibmptkoRur4hQUoKZYk5pUCekQEacHAOcA9W0rdLcMu4famDpeCc Q8X3iycZGxgfmHYxcnJICJhIHDi/khXCFpO4cG89WxcjF4eQwBJGiYkX10I5TUwS83fcZgOp YhMwlOh62wWWEBFoYpR40jeNHcRhFmhjlvjf8ZURpEpYwEni7czpTCA2i4CqRNuqT0A7ODh4 BTwkzi91h1gnJ3Hy2GSw1ZwCnhItP7+DLRACKpn/5gPjBEbeBYwMqxhFUkuLc9Nzi430ihNz i0vz0vWS83M3MQIjY9uxn1t2MHa9Cz7EKMDBqMTDu6AkNUKINbGsuDL3EKMEB7OSCO+O+LQI Id6UxMqq1KL8+KLSnNTiQ4ymQDdNZJYSTc4HRm1eSbyhiaG5paGRsYWFuZGRkjjv1A9XwoUE 0hNLUrNTUwtSi2D6mDg4pRoYzZ/f6EnQvtuTtzn0tfekvJSrM36+OLhhv/WLhX/U1G+cl9fU +qnvr/DZUD1eSrXK5YpHpv7eM6V6vzWMLQqM4mq7v++RfcI/U/6ZdFWi4TeXhW/1r+338/9j EHV71TcdjiIGjgLzk4uKmtTXlTzzf21dEiMUs+W+x84M5naXls2h8vy31p9SYinOSDTUYi4q TgQAmSjZC6ICAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20161230133346eucas1p1d5ce770573dcd5dcf7ad5ed0bf338f71 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: 20161230133346eucas1p1d5ce770573dcd5dcf7ad5ed0bf338f71 X-RootMTR: 20161230133346eucas1p1d5ce770573dcd5dcf7ad5ed0bf338f71 References: <1483104816-20885-1-git-send-email-m.szyprowski@samsung.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 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 --- This patch depends on "clk/samsung: exynos-audss: Replace syscore PM with platform device PM" patch, which has been already queued for merging: https://patchwork.kernel.org/patch/9447115/ --- .../devicetree/bindings/clock/clk-exynos-audss.txt | 6 +++ drivers/clk/samsung/clk-exynos-audss.c | 62 +++++++++++++--------- 2 files changed, 43 insertions(+), 25 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 cb7df358a27d..25bb569bdd30 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 = {