From patchwork Mon Aug 21 08:04:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 110500 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp958906qge; Mon, 21 Aug 2017 01:05:48 -0700 (PDT) X-Received: by 10.84.232.5 with SMTP id h5mr10936591plk.433.1503302748285; Mon, 21 Aug 2017 01:05:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503302748; cv=none; d=google.com; s=arc-20160816; b=udtISdRCjkGXQQ7958nA7b9VCDq/J7iGDT+4d7fPSEQduIfEKLw++dL3HJXYSs60W9 9Xjuj+b6WiYlNDGt+t7B3NUvPkn7Qy+mmLBXxBzX160WeTqfwQ2ezXSk055GXJV/6/s4 EKVUhDiJbNdTYmAzuEVoBfRt5Or2ZqdVE/HIE3ItMzbkw1Pn5VkeuLg9Wqi/TL91SV6q EWJdWSrr2ChSpdPM38wCYAL8y+A6pXPyA80yevR8m+Hm/a/sX86RWG751WLw8Gpq9244 pjlJITcq6JIAE3ntiiDBzZbx7NlR7Hed3XDIGzahCY8d14p9rcHg0OPNJbRaaxH9zDz9 rvEA== 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=bd4n04YMY0iPWInd+2qPs1ImU6aWwCvYis9vOY95YbM=; b=yRBYPcT91zTOyJQzDdUOHhw8M+YJmPOiPzb66Sh67odvnerBw4aqmWq6PATphQA9pA BD+TOoxYhSYCtff6SmLE56c4roSfQJb7rRtMHHPkw9BP7twTlm32bW9S+i6vzG1egsTu FQjkXzfT8gm+kTR223/eORweKznPtDN9anko1AAMxSzB5dJiitpJIQlioKZej+sRgKw7 KpuGBqYO7fjHwqrCEfcvLWHAJg4dMW0bg2NSmLR0eWHD/za94aOWyvZpOatlLH5qj8Xo DcJAvkxv9d9xV0XnjjrcKbPTtQgi+XJxXEUGubThNgbuEHr2+IrCgLDnG13wZfzbvbQc 25PQ== ARC-Authentication-Results: i=1; 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; 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 7si6960206pgt.528.2017.08.21.01.05.47; Mon, 21 Aug 2017 01:05:48 -0700 (PDT) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751959AbdHUIFp (ORCPT + 12 others); Mon, 21 Aug 2017 04:05:45 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:46189 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751895AbdHUIFm (ORCPT ); Mon, 21 Aug 2017 04:05:42 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20170821080540euoutp02900565db0a1a2dc64e927fff83fdf25d~czeChuSRD1767817678euoutp027; Mon, 21 Aug 2017 08:05:40 +0000 (GMT) Received: from eusmges5.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170821080539eucas1p2861b64c44004c849a5c614611da93a97~czeB0r_nQ1148811488eucas1p2T; Mon, 21 Aug 2017 08:05:39 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges5.samsung.com (EUCPMTA) with SMTP id 52.58.12743.3549A995; Mon, 21 Aug 2017 09:05:39 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170821080538eucas1p2fc5723914c314e6fe5da19bed55dd5bd~czeA8mB1k1148811488eucas1p2Q; Mon, 21 Aug 2017 08:05:38 +0000 (GMT) X-AuditID: cbfec7f5-f79d06d0000031c7-de-599a94535b93 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id AD.B4.20118.2549A995; Mon, 21 Aug 2017 09:05:38 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OV0009QWZT303A0@eusync1.samsung.com>; Mon, 21 Aug 2017 09:05:38 +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 v9 1/5] clk: Add support for runtime PM Date: Mon, 21 Aug 2017 10:04:59 +0200 Message-id: <1503302703-13801-2-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1503302703-13801-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrDIsWRmVeSWpSXmKPExsWy7djPc7rBU2ZFGsx5wW+xccZ6VovrX56z Wky6P4HF4vz5DewWmx5fY7X42HOP1eJz7xFGixnn9zFZrD1yl93i4ilXi8Nv2lktfpzpZrE4 vjbcgdfj/Y1Wdo/Lfb1MHptWdbJ53Lm2h81j85J6j74tqxg9Pm+SC2CP4rJJSc3JLEst0rdL 4Mr4+LKFpeCWb8X7O1OZGhhn2XUxcnJICJhITJw9nQ3CFpO4cG89mC0ksJRR4uTu4C5GLiD7 M6PEpZvT2bsYOcAabl2Gii9jlHj2+D0jhNPAJNH8djIzSDebgKFE19suNpCEiEATo8TEDetZ QRxmgSZmiWn7JjKBVAkLmEus62kD28cioCrxseMhM8gKXgEPiY+NlRAnyUmcPDaZFcTmFPCU 2DdjI9gcCYF17BLffk9nhjhJVmLTAWaIeheJbYuWsUPYwhKvjm+BsmUkLk/uZoGw+xklmlq1 IewZjBLn3vJC2NYSh49fBNvFLMAnMWkbzHheiY42IYgSD4m7/TvYIMKOEnsmSEP8PodRYm3f JfYJjDILGBlWMYqklhbnpqcWm+oVJ+YWl+al6yXn525iBKaB0/+Of93BuPSY1SFGAQ5GJR7e G/mzIoVYE8uKK3MPMUpwMCuJ8PJNmRkpxJuSWFmVWpQfX1Sak1p8iFGag0VJnNc2qi1SSCA9 sSQ1OzW1ILUIJsvEwSnVwBgpLG3cv2u7Vtza2Dbff1610teWLpx59vKZvUe/NEzY0XLN/4GJ 3J8dRd/mbn/2+dsS3Xs8Su8vtmuJObx/Oq38dw67zP27sVHnFrdK7mpaGxh7Ku9g7w/nsD+s qx48mX85ITGR27/ryvQpUT9q899PkQ0X+h2aymJ3kV1A/o2d55qtmvVZRTxKLMUZiYZazEXF iQCHdmqm/wIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42I5/e/4Zd2gKbMiDU5OULbYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHudlkpCampBYppOYl 56dk5qXbKoWGuOlaKCnkJeam2ipF6PqGBCkplCXmlAJ5RgZowME5wD1YSd8uwS3j48sWloJb vhXv70xlamCcZdfFyMEhIWAicetycBcjJ5ApJnHh3nq2LkYuDiGBJYwSuy52MEM4TUwS174+ ZAKpYhMwlOh62wVWJSLQxCjxpG8aO4jDLNDGLPG/4ysjSJWwgLnEup42NhCbRUBV4mPHQ2aQ dbwCHhIfGysh1slJnDw2mRXE5hTwlNg3YyOYLQRUcrvjBuMERt4FjAyrGEVSS4tz03OLjfSK E3OLS/PS9ZLzczcxAuNi27GfW3Ywdr0LPsQowMGoxMN7I39WpBBrYllxZe4hRgkOZiURXr4p MyOFeFMSK6tSi/Lji0pzUosPMZoC3TSRWUo0OR8Ys3kl8YYmhuaWhkbGFhbmRkZK4rzql5si hQTSE0tSs1NTC1KLYPqYODilGhgDWjxrVmrb+tpVG7X4inh/SNz65v9hgYXSz2fHBpmvflL9 R6zWO7vhqPeZu7yXDKVU7mU8K/l6JcmMz9f7rOHPt5923Gqe0nHw9nSeOW+NLy9zvHg0/IG2 EOdFvmYeofbdM5h5NRKdLHxcnpoy/jxz2PnR4Zzf7yQXZjY+r9vDMH9/wDbXLXJKLMUZiYZa zEXFiQB4/5uFoQIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170821080538eucas1p2fc5723914c314e6fe5da19bed55dd5bd 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-CMS-RootMailID: 20170821080538eucas1p2fc5723914c314e6fe5da19bed55dd5bd X-RootMTR: 20170821080538eucas1p2fc5723914c314e6fe5da19bed55dd5bd References: <1503302703-13801-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 Registers for some clocks might be located in the SOC area, which are under the power domain. To enable access to those registers respective domain has to be turned on. Additionally, registers for such clocks will usually loose its contents when power domain is turned off, so additional saving and restoring of them might be needed in the clock controller driver. This patch adds basic infrastructure in the clocks core to allow implementing driver for such clocks under power domains. Clock provider can supply a struct device pointer, which is the used by clock core for tracking and managing clock's controller runtime pm state. Each clk_prepare() operation will first call pm_runtime_get_sync() on the supplied device, while clk_unprepare() will do pm_runtime_put_sync() at the end. Additional calls to pm_runtime_get/put functions are required to ensure that any register access (like calculating/changing clock rates and unpreparing/disabling unused clocks on boot) will be done with clock controller in runtime resumend state. When one wants to register clock controller, which make use of this feature, he has to: 1. Provide a struct device to the core when registering the provider. 2. Ensure to enable runtime PM for that device before registering clocks. 3. Make sure that the runtime PM status of the controller device reflects the HW state. Signed-off-by: Marek Szyprowski Reviewed-by: Ulf Hansson Acked-by: Krzysztof Kozlowski --- drivers/clk/clk.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 112 insertions(+), 14 deletions(-) -- 1.9.1 diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index fc58c52a26b4..c5a4fb2687ab 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ struct clk_core { const struct clk_ops *ops; struct clk_hw *hw; struct module *owner; + struct device *dev; struct clk_core *parent; const char **parent_names; struct clk_core **parents; @@ -87,6 +89,26 @@ struct clk { struct hlist_node clks_node; }; +/*** runtime pm ***/ +static int clk_pm_runtime_get(struct clk_core *core) +{ + int ret = 0; + + if (!core->dev) + return 0; + + ret = pm_runtime_get_sync(core->dev); + return ret < 0 ? ret : 0; +} + +static void clk_pm_runtime_put(struct clk_core *core) +{ + if (!core->dev) + return; + + pm_runtime_put_sync(core->dev); +} + /*** locking ***/ static void clk_prepare_lock(void) { @@ -150,6 +172,8 @@ static void clk_enable_unlock(unsigned long flags) static bool clk_core_is_prepared(struct clk_core *core) { + bool ret = false; + /* * .is_prepared is optional for clocks that can prepare * fall back to software usage counter if it is missing @@ -157,11 +181,18 @@ static bool clk_core_is_prepared(struct clk_core *core) if (!core->ops->is_prepared) return core->prepare_count; - return core->ops->is_prepared(core->hw); + if (!clk_pm_runtime_get(core)) { + ret = core->ops->is_prepared(core->hw); + clk_pm_runtime_put(core); + } + + return ret; } static bool clk_core_is_enabled(struct clk_core *core) { + bool ret = false; + /* * .is_enabled is only mandatory for clocks that gate * fall back to software usage counter if .is_enabled is missing @@ -169,7 +200,29 @@ static bool clk_core_is_enabled(struct clk_core *core) if (!core->ops->is_enabled) return core->enable_count; - return core->ops->is_enabled(core->hw); + /* + * Check if clock controller's device is runtime active before + * calling .is_enabled callback. If not, assume that clock is + * disabled, because we might be called from atomic context, from + * which pm_runtime_get() is not allowed. + * This function is called mainly from clk_disable_unused_subtree, + * which ensures proper runtime pm activation of controller before + * taking enable spinlock, but the below check is needed if one tries + * to call it from other places. + */ + if (core->dev) { + pm_runtime_get_noresume(core->dev); + if (!pm_runtime_active(core->dev)) { + ret = false; + goto done; + } + } + + ret = core->ops->is_enabled(core->hw); +done: + clk_pm_runtime_put(core); + + return ret; } /*** helper functions ***/ @@ -489,6 +542,8 @@ static void clk_core_unprepare(struct clk_core *core) if (core->ops->unprepare) core->ops->unprepare(core->hw); + clk_pm_runtime_put(core); + trace_clk_unprepare_complete(core); clk_core_unprepare(core->parent); } @@ -530,10 +585,14 @@ static int clk_core_prepare(struct clk_core *core) return 0; if (core->prepare_count == 0) { - ret = clk_core_prepare(core->parent); + ret = clk_pm_runtime_get(core); if (ret) return ret; + ret = clk_core_prepare(core->parent); + if (ret) + goto runtime_put; + trace_clk_prepare(core); if (core->ops->prepare) @@ -541,15 +600,18 @@ static int clk_core_prepare(struct clk_core *core) trace_clk_prepare_complete(core); - if (ret) { - clk_core_unprepare(core->parent); - return ret; - } + if (ret) + goto unprepare; } core->prepare_count++; return 0; +unprepare: + clk_core_unprepare(core->parent); +runtime_put: + clk_pm_runtime_put(core); + return ret; } static int clk_core_prepare_lock(struct clk_core *core) @@ -745,6 +807,9 @@ static void clk_unprepare_unused_subtree(struct clk_core *core) if (core->flags & CLK_IGNORE_UNUSED) return; + if (clk_pm_runtime_get(core)) + return; + if (clk_core_is_prepared(core)) { trace_clk_unprepare(core); if (core->ops->unprepare_unused) @@ -753,6 +818,8 @@ static void clk_unprepare_unused_subtree(struct clk_core *core) core->ops->unprepare(core->hw); trace_clk_unprepare_complete(core); } + + clk_pm_runtime_put(core); } static void clk_disable_unused_subtree(struct clk_core *core) @@ -768,6 +835,9 @@ static void clk_disable_unused_subtree(struct clk_core *core) if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_prepare_enable(core->parent); + if (clk_pm_runtime_get(core)) + goto unprepare_out; + flags = clk_enable_lock(); if (core->enable_count) @@ -792,6 +862,8 @@ static void clk_disable_unused_subtree(struct clk_core *core) unlock_out: clk_enable_unlock(flags); + clk_pm_runtime_put(core); +unprepare_out: if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_disable_unprepare(core->parent); } @@ -1038,9 +1110,13 @@ long clk_get_accuracy(struct clk *clk) static unsigned long clk_recalc(struct clk_core *core, unsigned long parent_rate) { - if (core->ops->recalc_rate) - return core->ops->recalc_rate(core->hw, parent_rate); - return parent_rate; + unsigned long rate = parent_rate; + + if (core->ops->recalc_rate && !clk_pm_runtime_get(core)) { + rate = core->ops->recalc_rate(core->hw, parent_rate); + clk_pm_runtime_put(core); + } + return rate; } /** @@ -1565,6 +1641,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core, { struct clk_core *top, *fail_clk; unsigned long rate = req_rate; + int ret = 0; if (!core) return 0; @@ -1581,21 +1658,28 @@ static int clk_core_set_rate_nolock(struct clk_core *core, if (!top) return -EINVAL; + ret = clk_pm_runtime_get(core); + if (ret) + return ret; + /* notify that we are about to change rates */ fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE); if (fail_clk) { pr_debug("%s: failed to set %s rate\n", __func__, fail_clk->name); clk_propagate_rate_change(top, ABORT_RATE_CHANGE); - return -EBUSY; + ret = -EBUSY; + goto err; } /* change the rates */ clk_change_rate(top); core->req_rate = req_rate; +err: + clk_pm_runtime_put(core); - return 0; + return ret; } /** @@ -1826,12 +1910,16 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) p_rate = parent->rate; } + ret = clk_pm_runtime_get(core); + if (ret) + goto out; + /* propagate PRE_RATE_CHANGE notifications */ ret = __clk_speculate_rates(core, p_rate); /* abort if a driver objects */ if (ret & NOTIFY_STOP_MASK) - goto out; + goto runtime_put; /* do the re-parent */ ret = __clk_set_parent(core, parent, p_index); @@ -1844,6 +1932,8 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) __clk_recalc_accuracies(core); } +runtime_put: + clk_pm_runtime_put(core); out: clk_prepare_unlock(); @@ -2350,7 +2440,7 @@ static inline void clk_debug_unregister(struct clk_core *core) */ static int __clk_core_init(struct clk_core *core) { - int i, ret = 0; + int i, ret; struct clk_core *orphan; struct hlist_node *tmp2; unsigned long rate; @@ -2360,6 +2450,10 @@ static int __clk_core_init(struct clk_core *core) clk_prepare_lock(); + ret = clk_pm_runtime_get(core); + if (ret) + goto unlock; + /* check to see if a clock with this name is already registered */ if (clk_core_lookup(core->name)) { pr_debug("%s: clk %s already initialized\n", @@ -2512,6 +2606,8 @@ static int __clk_core_init(struct clk_core *core) kref_init(&core->ref); out: + clk_pm_runtime_put(core); +unlock: clk_prepare_unlock(); if (!ret) @@ -2583,6 +2679,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) goto fail_name; } core->ops = hw->init->ops; + if (dev && pm_runtime_enabled(dev)) + core->dev = dev; if (dev && dev->driver) core->owner = dev->driver->owner; core->hw = hw; From patchwork Mon Aug 21 08:05:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 110502 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp958955qge; Mon, 21 Aug 2017 01:05:52 -0700 (PDT) X-Received: by 10.99.127.7 with SMTP id a7mr15812517pgd.56.1503302752683; Mon, 21 Aug 2017 01:05:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503302752; cv=none; d=google.com; s=arc-20160816; b=L+NRwQeB40FkY/YsZh7xVE3MKrNZMpUrXNZXaKaqBH8UPGShkcfsvD16X1WIR/wW/X nCvao9eSUylqr2ojfz3TVNbVDWCGY77y+wbGn40Sy33D8g00SjWS7QPBIHvc7VnAs7ED qKgBaZ7PiSOZYH/IXAUmrLgWTfKAehTGgkXSyVqRhVLJPNRLMukDWFmx7JrD6xuadboH 2DJOxAmbNI0lUu/miZyjSRrBll7RzK6FlrR8ENVjz1rniBKmRTZU5q9JjCa/bVqzu4J+ 3g7yzGmhostojPctT7Q9v53qVzrSu0G6XgBUagQNgAtE3PT/7vpNfUG2Q0lC1tJ0COYF PJ8w== 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=ci6yVz4R+LvedGHjiSGZ6I2P6B37oaEGtzq/QlYHwoU=; b=qsfEueaaV6HUMhI9BWxuIMbsRLO3F8/syDKqR32jM9SM+a/6TmgWxZgRpXJXJkWgyV 5vfqcvVcZEmEWtEM18qYzvK2gw4gcnC3S5XGxkGS3VbXKF8G7K2q4JN5NZY+CGoY4aCZ mjUbcDzvoTm1M42WbsOcx51OAAySYS225AC1YMe5funBI+6pTDDECN2NhctyyGbK6mG1 DgirOYekkJQx19fN0toKSzlZYQaIifjWCcAM3F/GZPvhVk59Y8HM61iKugA5r4fk499C BXkyz6QAQu0YISNa7MvN2L2JiS3uIbwQkxyjdAIZidS2cdQaj1l6aiQB1iRth42+RcXl f5NQ== ARC-Authentication-Results: i=1; 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; 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 7si6960206pgt.528.2017.08.21.01.05.52; Mon, 21 Aug 2017 01:05:52 -0700 (PDT) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752116AbdHUIFu (ORCPT + 12 others); Mon, 21 Aug 2017 04:05:50 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:56935 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751897AbdHUIFn (ORCPT ); Mon, 21 Aug 2017 04:05:43 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20170821080540euoutp01ff22c4dff065be398a3eefa31e429acb~czeDGSSkr2331623316euoutp01m; Mon, 21 Aug 2017 08:05:40 +0000 (GMT) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170821080540eucas1p118e7064f97b984a01ed6be05ad964a32~czeCUD5vm0787107871eucas1p1I; Mon, 21 Aug 2017 08:05:40 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 1C.B9.12907.3549A995; Mon, 21 Aug 2017 09:05:39 +0100 (BST) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170821080539eucas1p282557b6f1885f1714b08096ab3724c25~czeBeGOJW1240012400eucas1p2J; Mon, 21 Aug 2017 08:05:39 +0000 (GMT) X-AuditID: cbfec7f1-f793a6d00000326b-d8-599a94538838 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 70.D4.18832.3549A995; Mon, 21 Aug 2017 09:05:39 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OV0009QWZT303A0@eusync1.samsung.com>; Mon, 21 Aug 2017 09:05:39 +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 v9 2/5] clk: samsung: Add support for runtime PM Date: Mon, 21 Aug 2017 10:05:00 +0200 Message-id: <1503302703-13801-3-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1503302703-13801-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrPIsWRmVeSWpSXmKPExsWy7djP87rBU2ZFGmz7ZGCxccZ6VovrX56z Wky6P4HF4vz5DewWmx5fY7X42HOP1eJz7xFGixnn9zFZrD1yl93i4ilXi8Nv2lktfpzpZrE4 vjbcgdfj/Y1Wdo/Lfb1MHptWdbJ53Lm2h81j85J6j74tqxg9Pm+SC2CP4rJJSc3JLEst0rdL 4Mo4um8WS8FqxYpXX9UaGL9JdzFyckgImEjsvbuSCcIWk7hwbz1bFyMXh5DAUkaJ7Z/a2CGc z4wSc88vZIXp2LL5O1RiGaPEyrtbWCGcBiaJTf9XMoJUsQkYSnS97QKbJSLQxCgxccN6sCpm gSZmiWn7JoJtFBZwkFjQ+psNxGYRUJV4N3UtWDevgIfEtLUHoK6Skzh5bDLYbk4BT4l9MzaC DZIQWMUu8fTlFqBDOIAcWYlNB5gh6l0kjv35D3WrsMSr4yAlILaMRGfHQaiZ/YwSTa3aEPYM Rolzb3khbGuJw8cvgvUyC/BJTNo2nRliPK9ER5sQRImHxNp3TVAjHSX233sDDYo5jBJTnl5l mcAos4CRYRWjSGppcW56arGRXnFibnFpXrpecn7uJkZgMjj97/jHHYzvT1gdYhTgYFTi4TUo mhUpxJpYVlyZe4hRgoNZSYSXb8rMSCHelMTKqtSi/Pii0pzU4kOM0hwsSuK8tlFtkUIC6Ykl qdmpqQWpRTBZJg5OqQZGx6C2oHmN0ryb/+40tXdsf9K4WC//h2hCzjUe7kIZrwlB1TZrJxmL PfswRdMgNm/W5r8WSfOX5hxdultsftihHQ6TnzIYJBRKTKy53dRnFm9XtSvbXFo1Pl/dlctf v/u8kND5eXL+V85G30zUED2wdV23j1fySZ8JDTqFmYVPmXIaPQsW3VZiKc5INNRiLipOBAA7 i/6BAgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42I5/e/4Zd3gKbMiDa7d4LDYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHudlkpCampBYppOYl 56dk5qXbKoWGuOlaKCnkJeam2ipF6PqGBCkplCXmlAJ5RgZowME5wD1YSd8uwS3j6L5ZLAWr FStefVVrYPwm3cXIySEhYCKxZfN3dghbTOLCvfVsXYxcHEICSxgl5jz4xwSSEBJoYpK4dE8S xGYTMJToetsFViQi0MQo8aRvGjuIwyzQxizxv+MrI0iVsICDxILW32wgNouAqsS7qWvB4rwC HhLT1h5gglgnJ3Hy2GRWEJtTwFNi34yNrBDbPCRud9xgnMDIu4CRYRWjSGppcW56brGhXnFi bnFpXrpecn7uJkZgXGw79nPzDsZLG4MPMQpwMCrx8BoUzYoUYk0sK67MPcQowcGsJMLLN2Vm pBBvSmJlVWpRfnxRaU5q8SFGU6CjJjJLiSbnA2M2ryTe0MTQ3NLQyNjCwtzISEmcV/1yU6SQ QHpiSWp2ampBahFMHxMHp1QDY/8hxdXif49fsg72PromMowt5O2mngP7M8JfXxZy/6eWsj/d 2ZHHlH/lRM4D/2JTzDY29PycbX657tNEM4E7f5c8ePij3PeCgY9uX2Vhhm2IMc+CV7MFmPkP Xn26Xq+erV968+nO+//LFzotqo266J3Q5JF0sXPCb529fL4Bj7ildh1VDcv8p8RSnJFoqMVc VJwIAIRz6U6hAgAA X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170821080539eucas1p282557b6f1885f1714b08096ab3724c25 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-CMS-RootMailID: 20170821080539eucas1p282557b6f1885f1714b08096ab3724c25 X-RootMTR: 20170821080539eucas1p282557b6f1885f1714b08096ab3724c25 References: <1503302703-13801-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 struct device pointer to samsung_clk_provider and forwarding it to clk_register_* functions, so drivers can register clocks, which use runtime pm feature. Signed-off-by: Marek Szyprowski Reviewed-by: Ulf Hansson Reviewed-by: Chanwoo Choi Tested-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-pll.c | 2 +- drivers/clk/samsung/clk.c | 12 ++++++------ drivers/clk/samsung/clk.h | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) -- 1.9.1 diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 037c61484098..41ebb94d2855 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -1388,7 +1388,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, pll->lock_reg = base + pll_clk->lock_offset; pll->con_reg = base + pll_clk->con_offset; - ret = clk_hw_register(NULL, &pll->hw); + ret = clk_hw_register(ctx->dev, &pll->hw); if (ret) { pr_err("%s: failed to register pll clock %s : %d\n", __func__, pll_clk->name, ret); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 7ce0fa86c5ff..aef97b091b50 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -134,7 +134,7 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { - clk_hw = clk_hw_register_fixed_rate(NULL, list->name, + clk_hw = clk_hw_register_fixed_rate(ctx->dev, list->name, list->parent_name, list->flags, list->fixed_rate); if (IS_ERR(clk_hw)) { pr_err("%s: failed to register clock %s\n", __func__, @@ -163,7 +163,7 @@ void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx, unsigned int idx; for (idx = 0; idx < nr_clk; idx++, list++) { - clk_hw = clk_hw_register_fixed_factor(NULL, list->name, + clk_hw = clk_hw_register_fixed_factor(ctx->dev, list->name, list->parent_name, list->flags, list->mult, list->div); if (IS_ERR(clk_hw)) { pr_err("%s: failed to register clock %s\n", __func__, @@ -184,7 +184,7 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { - clk_hw = clk_hw_register_mux(NULL, list->name, + clk_hw = clk_hw_register_mux(ctx->dev, list->name, list->parent_names, list->num_parents, list->flags, ctx->reg_base + list->offset, list->shift, list->width, list->mux_flags, &ctx->lock); @@ -217,13 +217,13 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, for (idx = 0; idx < nr_clk; idx++, list++) { if (list->table) - clk_hw = clk_hw_register_divider_table(NULL, + clk_hw = clk_hw_register_divider_table(ctx->dev, list->name, list->parent_name, list->flags, ctx->reg_base + list->offset, list->shift, list->width, list->div_flags, list->table, &ctx->lock); else - clk_hw = clk_hw_register_divider(NULL, list->name, + clk_hw = clk_hw_register_divider(ctx->dev, list->name, list->parent_name, list->flags, ctx->reg_base + list->offset, list->shift, list->width, list->div_flags, &ctx->lock); @@ -255,7 +255,7 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { - clk_hw = clk_hw_register_gate(NULL, list->name, list->parent_name, + clk_hw = clk_hw_register_gate(ctx->dev, list->name, list->parent_name, list->flags, ctx->reg_base + list->offset, list->bit_idx, list->gate_flags, &ctx->lock); if (IS_ERR(clk_hw)) { diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index b8ca0dd3a38b..f0acae4f5d1b 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -24,6 +24,7 @@ */ struct samsung_clk_provider { void __iomem *reg_base; + struct device *dev; spinlock_t lock; /* clk_data must be the last entry due to variable lenght 'hws' array */ struct clk_hw_onecell_data clk_data; From patchwork Mon Aug 21 08:05:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 110503 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp959017qge; Mon, 21 Aug 2017 01:05:56 -0700 (PDT) X-Received: by 10.98.3.3 with SMTP id 3mr16256854pfd.31.1503302755931; Mon, 21 Aug 2017 01:05:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503302755; cv=none; d=google.com; s=arc-20160816; b=kFdGhCYWi+iFTJRDlYZ5npxzibYshc37KYZxV3S5GYjUG+nBv3h7oHQd56+5KsLtT2 6+2rjZ/F9kVck4RYQEUwh/DlkzQGO9BNT+tmG90Ee5Se8fD6JLy3rBujV0S7Pn5nI67Z aaQE8T2p+fLQ6440V14O5sWN+lmGY0sAuZ2jnj8pT6FGrqDOvvT6hsjwnlQkbqHFWJWu f6eAZln19dQNceKOBin3ShXXWEDP0EVDMAlU5ZJNX1WhfL2Ahh6KLYUwxQYaS+PMd4Zj QL77q1RpWb3+fmdC+6KH2GfI7a7d2tI5BrvlYgT66XGpvSXnqNXmWdn0fNZXRi5KdHRq rXJg== 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=NDvo+32t243fpnPoj7r2v3+mrARalB05S/pg8jM1jSY=; b=N544CzWiWHqzfzESxpHK2Ud5pdJ3LW+LV6i6RgrPXw3JydNbcTII4ksjtkQGehR0dR hXzH4DoU8XBXBUEW6yVKlMURKeHn7FHHh9c+op49fqI3Jbn+7RBl8dtS0PfseQDi5D8l ccNWAN3v0GqVzIsu8Oz7G7v1HGGwXSbIauprB1Xb8Ys9hIvQtIsBKXl0s7nGTQ8jda9u GHm/KVXK2knS7PB8Ofl3bhxWLBdxVkFMiiYwQqeQBIq7V3pub2AUPec78KHwtM3c/uXY EyZ6CrfBlkbA9wV9XUQcjxwe9PIOjpmTGepwqSr3NPTJcABhDVUkyW0bJIP8UK57Pw49 r5tA== ARC-Authentication-Results: i=1; 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; 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 38si8019515plc.179.2017.08.21.01.05.55; Mon, 21 Aug 2017 01:05:55 -0700 (PDT) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752139AbdHUIFv (ORCPT + 12 others); Mon, 21 Aug 2017 04:05:51 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:56939 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751916AbdHUIFn (ORCPT ); Mon, 21 Aug 2017 04:05:43 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20170821080541euoutp01586d765e320c7439cb980991976d41bf~czeDg9YLY2309423094euoutp01L; Mon, 21 Aug 2017 08:05:41 +0000 (GMT) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170821080540eucas1p11b20199ad152717d7a396f80bb1f14c6~czeC1lSVb0068500685eucas1p1h; Mon, 21 Aug 2017 08:05:40 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 3D.B9.12907.4549A995; Mon, 21 Aug 2017 09:05:40 +0100 (BST) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170821080539eucas1p2ff5addf7ece8ad54c0c885a938f97880~czeCGTOh50164601646eucas1p2q; Mon, 21 Aug 2017 08:05:39 +0000 (GMT) X-AuditID: cbfec7f1-f793a6d00000326b-db-599a94543261 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 91.D4.18832.3549A995; Mon, 21 Aug 2017 09:05:39 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OV0009QWZT303A0@eusync1.samsung.com>; Mon, 21 Aug 2017 09:05:39 +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 v9 3/5] clk: samsung: exynos5433: Add support for runtime PM Date: Mon, 21 Aug 2017 10:05:01 +0200 Message-id: <1503302703-13801-4-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1503302703-13801-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrEIsWRmVeSWpSXmKPExsWy7djP87ohU2ZFGpz+ImqxccZ6VovrX56z Wky6P4HF4vz5DewWmx5fY7X42HOP1eJz7xFGixnn9zFZrD1yl93i4ilXi8Nv2lktfpzpZrE4 vjbcgdfj/Y1Wdo/Lfb1MHptWdbJ53Lm2h81j85J6j74tqxg9Pm+SC2CP4rJJSc3JLEst0rdL 4Mp4cmcJW8Hxw4wVT9sPsjQwXlvI2MXIySEhYCLx/+RrZghbTOLCvfVsXYxcHEICSxklnq1b zwThfGaUeLFgMztMx6y2U4wQiWWMEns2HYOqamCS2PR/JdhcNgFDia63XWCzRASaGCUmbljP CuIwCzQxS0zbN5EJpEpYwEdiRUcDWAeLgKrE0hVTwWxeAQ+JIxNaWCD2yUmcPDaZFcTmFPCU 2DdjI9ggCYFV7BIvf54DcjiAHFmJTQegvnCRmNfwhg3CFpZ4dXwL1N0yEp0dB5kg7H5GiaZW bQh7BqPEube8ELa1xOHjF8F2MQvwSUzaNp0ZYjyvREebEESJh0T36busELajxJ/9H6EBNodR Yv/Ec8wTGGUWMDKsYhRJLS3OTU8tNtIrTswtLs1L10vOz93ECEwJp/8d/7iD8f0Jq0OMAhyM Sjy8BkWzIoVYE8uKK3MPMUpwMCuJ8PJNmRkpxJuSWFmVWpQfX1Sak1p8iFGag0VJnNc2qi1S SCA9sSQ1OzW1ILUIJsvEwSnVwOhReD1aZ4d8cWhArbiyl3bK4nTvz78inNNyj696ODNmYVCN QePfcgHbmXd3KIjpXl/M3rRaSC7VujR0ldV5xt8CTp3FD1X+bOm582QBs3PL0zMzaiPfyUz1 77d+f/Nj8f10qfWt9mINkUkSs9lbKv8ITmKfecPzr5/NvK/BHuJKN1ODJ144osRSnJFoqMVc VJwIACxNbK0FAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprIIsWRmVeSWpSXmKPExsVy+t/xy7rBU2ZFGry/bGixccZ6VovrX56z Wky6P4HF4vz5DewWmx5fY7X42HOP1eJz7xFGixnn9zFZrD1yl93i4ilXi8Nv2lktfpzpZrE4 vjbcgdfj/Y1Wdo/Lfb1MHptWdbJ53Lm2h81j85J6j74tqxg9Pm+SC2CPcrPJSE1MSS1SSM1L zk/JzEu3VQoNcdO1UFLIS8xNtVWK0PUNCVJSKEvMKQXyjAzQgINzgHuwkr5dglvGkztL2AqO H2aseNp+kKWB8dpCxi5GTg4JAROJWW2noGwxiQv31rN1MXJxCAksYZS4/fQrWEJIoIlJ4tI9 SRCbTcBQouttF1iRiEATo8STvmnsIA6zQBuzxP8OiA5hAR+JFR0NYDaLgKrE0hVTwWxeAQ+J IxNaWCDWyUmcPDaZFcTmFPCU2DdjIyvENg+J2x03GCcw8i5gZFjFKJJaWpybnltsqFecmFtc mpeul5yfu4kRGB3bjv3cvIPx0sbgQ4wCHIxKPLwGRbMihVgTy4orcw8xSnAwK4nw8k2ZGSnE m5JYWZValB9fVJqTWnyI0RToqInMUqLJ+cDIzSuJNzQxNLc0NDK2sDA3MlIS51W/3BQpJJCe WJKanZpakFoE08fEwSnVwDjngkZz0M1rO9s1ZLTTDNMiy1LfSLAEtqjPWrrX+MSigNYd6Su1 r7+ZJtxwYetl9UNSjdtur5s2/WN58T7dwJcpL6/5z5rL7BcU0pJqvFeKP2n60/crLPdfW2k0 c6/fgYLbj4tORtffupzB47NLe8Ftl/g2cSMjpt/Xdc7Wn7gRNCM4+fPNmdeUWIozEg21mIuK EwHvdNzOpAIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170821080539eucas1p2ff5addf7ece8ad54c0c885a938f97880 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-CMS-RootMailID: 20170821080539eucas1p2ff5addf7ece8ad54c0c885a938f97880 X-RootMTR: 20170821080539eucas1p2ff5addf7ece8ad54c0c885a938f97880 References: <1503302703-13801-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 Add runtime pm support for all clock controller units (CMU), which belong to power domains and require special handling during on/off operations. Typically special values has to be written to MUX registers to change internal clocks parents to OSC clock before turning power off. During such operation all clocks, which enter CMU has to be enabled to let MUX to stabilize. Also for each CMU there is one special parent clock, which has to be enabled all the time when any access to CMU registers is being done. This patch solves most of the mysterious external abort and freeze issues caused by a lack of proper parent CMU clock enabled or incorrect turn off procedure. Signed-off-by: Marek Szyprowski Reviewed-by: Ulf Hansson Reviewed-by: Chanwoo Choi Tested-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- .../devicetree/bindings/clock/exynos5433-clock.txt | 16 + drivers/clk/samsung/clk-exynos5433.c | 409 ++++++++++++++++----- drivers/clk/samsung/clk.h | 6 + 3 files changed, 346 insertions(+), 85 deletions(-) -- 1.9.1 diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 1dc80f8811fe..5c7dd12e667a 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -168,6 +168,11 @@ Required Properties: - aclk_cam1_400 - aclk_cam1_552 +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). + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -270,6 +275,7 @@ Example 2: Examples of clock controller nodes are listed below. clocks = <&xxti>, <&cmu_top CLK_ACLK_G2D_266>, <&cmu_top CLK_ACLK_G2D_400>; + power-domains = <&pd_g2d>; }; cmu_disp: clock-controller@13b90000 { @@ -295,6 +301,7 @@ Example 2: Examples of clock controller nodes are listed below. <&cmu_mif CLK_SCLK_DECON_ECLK_DISP>, <&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>, <&cmu_mif CLK_ACLK_DISP_333>; + power-domains = <&pd_disp>; }; cmu_aud: clock-controller@114c0000 { @@ -304,6 +311,7 @@ Example 2: Examples of clock controller nodes are listed below. clock-names = "oscclk", "fout_aud_pll"; clocks = <&xxti>, <&cmu_top CLK_FOUT_AUD_PLL>; + power-domains = <&pd_aud>; }; cmu_bus0: clock-controller@13600000 { @@ -340,6 +348,7 @@ Example 2: Examples of clock controller nodes are listed below. clock-names = "oscclk", "aclk_g3d_400"; clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>; + power-domains = <&pd_g3d>; }; cmu_gscl: clock-controller@13cf0000 { @@ -353,6 +362,7 @@ Example 2: Examples of clock controller nodes are listed below. clocks = <&xxti>, <&cmu_top CLK_ACLK_GSCL_111>, <&cmu_top CLK_ACLK_GSCL_333>; + power-domains = <&pd_gscl>; }; cmu_apollo: clock-controller@11900000 { @@ -384,6 +394,7 @@ Example 2: Examples of clock controller nodes are listed below. clocks = <&xxti>, <&cmu_top CLK_SCLK_JPEG_MSCL>, <&cmu_top CLK_ACLK_MSCL_400>; + power-domains = <&pd_mscl>; }; cmu_mfc: clock-controller@15280000 { @@ -393,6 +404,7 @@ Example 2: Examples of clock controller nodes are listed below. clock-names = "oscclk", "aclk_mfc_400"; clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>; + power-domains = <&pd_mfc>; }; cmu_hevc: clock-controller@14f80000 { @@ -402,6 +414,7 @@ Example 2: Examples of clock controller nodes are listed below. clock-names = "oscclk", "aclk_hevc_400"; clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>; + power-domains = <&pd_hevc>; }; cmu_isp: clock-controller@146d0000 { @@ -415,6 +428,7 @@ Example 2: Examples of clock controller nodes are listed below. clocks = <&xxti>, <&cmu_top CLK_ACLK_ISP_DIS_400>, <&cmu_top CLK_ACLK_ISP_400>; + power-domains = <&pd_isp>; }; cmu_cam0: clock-controller@120d0000 { @@ -430,6 +444,7 @@ Example 2: Examples of clock controller nodes are listed below. <&cmu_top CLK_ACLK_CAM0_333>, <&cmu_top CLK_ACLK_CAM0_400>, <&cmu_top CLK_ACLK_CAM0_552>; + power-domains = <&pd_cam0>; }; cmu_cam1: clock-controller@145d0000 { @@ -451,6 +466,7 @@ Example 2: Examples of clock controller nodes are listed below. <&cmu_top CLK_ACLK_CAM1_333>, <&cmu_top CLK_ACLK_CAM1_400>, <&cmu_top CLK_ACLK_CAM1_552>; + power-domains = <&pd_cam1>; }; Example 3: UART controller node that consumes the clock generated by the clock diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 11343a597093..cd9337613dd8 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -9,9 +9,13 @@ * Common Clock Framework support for Exynos5433 SoC. */ +#include #include #include #include +#include +#include +#include #include @@ -1991,6 +1995,14 @@ static void __init exynos5433_cmu_peris_init(struct device_node *np) ENABLE_IP_FSYS1, }; +static const struct samsung_clk_reg_dump fsys_suspend_regs[] = { + { MUX_SEL_FSYS0, 0 }, + { MUX_SEL_FSYS1, 0 }, + { MUX_SEL_FSYS2, 0 }, + { MUX_SEL_FSYS3, 0 }, + { MUX_SEL_FSYS4, 0 }, +}; + static const struct samsung_fixed_rate_clock fsys_fixed_clks[] __initconst = { /* PHY clocks from USBDRD30_PHY */ FRATE(CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY, @@ -2296,16 +2308,11 @@ static void __init exynos5433_cmu_peris_init(struct device_node *np) .nr_clk_ids = FSYS_NR_CLK, .clk_regs = fsys_clk_regs, .nr_clk_regs = ARRAY_SIZE(fsys_clk_regs), + .suspend_regs = fsys_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(fsys_suspend_regs), + .clk_name = "aclk_fsys_200", }; -static void __init exynos5433_cmu_fsys_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &fsys_cmu_info); -} - -CLK_OF_DECLARE(exynos5433_cmu_fsys, "samsung,exynos5433-cmu-fsys", - exynos5433_cmu_fsys_init); - /* * Register offset definitions for CMU_G2D */ @@ -2335,6 +2342,10 @@ static void __init exynos5433_cmu_fsys_init(struct device_node *np) DIV_ENABLE_IP_G2D_SECURE_SMMU_G2D, }; +static const struct samsung_clk_reg_dump g2d_suspend_regs[] = { + { MUX_SEL_G2D0, 0 }, +}; + /* list of all parent clock list */ PNAME(mout_aclk_g2d_266_user_p) = { "oscclk", "aclk_g2d_266", }; PNAME(mout_aclk_g2d_400_user_p) = { "oscclk", "aclk_g2d_400", }; @@ -2420,16 +2431,11 @@ static void __init exynos5433_cmu_fsys_init(struct device_node *np) .nr_clk_ids = G2D_NR_CLK, .clk_regs = g2d_clk_regs, .nr_clk_regs = ARRAY_SIZE(g2d_clk_regs), + .suspend_regs = g2d_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(g2d_suspend_regs), + .clk_name = "aclk_g2d_400", }; -static void __init exynos5433_cmu_g2d_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &g2d_cmu_info); -} - -CLK_OF_DECLARE(exynos5433_cmu_g2d, "samsung,exynos5433-cmu-g2d", - exynos5433_cmu_g2d_init); - /* * Register offset definitions for CMU_DISP */ @@ -2494,6 +2500,18 @@ static void __init exynos5433_cmu_g2d_init(struct device_node *np) CLKOUT_CMU_DISP_DIV_STAT, }; +static const struct samsung_clk_reg_dump disp_suspend_regs[] = { + /* PLL has to be enabled for suspend */ + { DISP_PLL_CON0, 0x85f40502 }, + /* ignore status of external PHY muxes during suspend to avoid hangs */ + { MUX_IGNORE_DISP2, 0x00111111 }, + { MUX_SEL_DISP0, 0 }, + { MUX_SEL_DISP1, 0 }, + { MUX_SEL_DISP2, 0 }, + { MUX_SEL_DISP3, 0 }, + { MUX_SEL_DISP4, 0 }, +}; + /* list of all parent clock list */ PNAME(mout_disp_pll_p) = { "oscclk", "fout_disp_pll", }; PNAME(mout_sclk_dsim1_user_p) = { "oscclk", "sclk_dsim1_disp", }; @@ -2841,16 +2859,11 @@ static void __init exynos5433_cmu_g2d_init(struct device_node *np) .nr_clk_ids = DISP_NR_CLK, .clk_regs = disp_clk_regs, .nr_clk_regs = ARRAY_SIZE(disp_clk_regs), + .suspend_regs = disp_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(disp_suspend_regs), + .clk_name = "aclk_disp_333", }; -static void __init exynos5433_cmu_disp_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &disp_cmu_info); -} - -CLK_OF_DECLARE(exynos5433_cmu_disp, "samsung,exynos5433-cmu-disp", - exynos5433_cmu_disp_init); - /* * Register offset definitions for CMU_AUD */ @@ -2885,6 +2898,11 @@ static void __init exynos5433_cmu_disp_init(struct device_node *np) ENABLE_IP_AUD1, }; +static const struct samsung_clk_reg_dump aud_suspend_regs[] = { + { MUX_SEL_AUD0, 0 }, + { MUX_SEL_AUD1, 0 }, +}; + /* list of all parent clock list */ PNAME(mout_aud_pll_user_aud_p) = { "oscclk", "fout_aud_pll", }; PNAME(mout_sclk_aud_pcm_p) = { "mout_aud_pll_user", "ioclk_audiocdclk0",}; @@ -3011,16 +3029,11 @@ static void __init exynos5433_cmu_disp_init(struct device_node *np) .nr_clk_ids = AUD_NR_CLK, .clk_regs = aud_clk_regs, .nr_clk_regs = ARRAY_SIZE(aud_clk_regs), + .suspend_regs = aud_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(aud_suspend_regs), + .clk_name = "fout_aud_pll", }; -static void __init exynos5433_cmu_aud_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &aud_cmu_info); -} -CLK_OF_DECLARE(exynos5433_cmu_aud, "samsung,exynos5433-cmu-aud", - exynos5433_cmu_aud_init); - - /* * Register offset definitions for CMU_BUS{0|1|2} */ @@ -3222,6 +3235,10 @@ static void __init exynos5433_cmu_aud_init(struct device_node *np) CLK_STOPCTRL, }; +static const struct samsung_clk_reg_dump g3d_suspend_regs[] = { + { MUX_SEL_G3D, 0 }, +}; + /* list of all parent clock list */ PNAME(mout_aclk_g3d_400_p) = { "mout_g3d_pll", "aclk_g3d_400", }; PNAME(mout_g3d_pll_p) = { "oscclk", "fout_g3d_pll", }; @@ -3295,15 +3312,11 @@ static void __init exynos5433_cmu_aud_init(struct device_node *np) .nr_clk_ids = G3D_NR_CLK, .clk_regs = g3d_clk_regs, .nr_clk_regs = ARRAY_SIZE(g3d_clk_regs), + .suspend_regs = g3d_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(g3d_suspend_regs), + .clk_name = "aclk_g3d_400", }; -static void __init exynos5433_cmu_g3d_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &g3d_cmu_info); -} -CLK_OF_DECLARE(exynos5433_cmu_g3d, "samsung,exynos5433-cmu-g3d", - exynos5433_cmu_g3d_init); - /* * Register offset definitions for CMU_GSCL */ @@ -3342,6 +3355,12 @@ static void __init exynos5433_cmu_g3d_init(struct device_node *np) ENABLE_IP_GSCL_SECURE_SMMU_GSCL2, }; +static const struct samsung_clk_reg_dump gscl_suspend_regs[] = { + { MUX_SEL_GSCL, 0 }, + { ENABLE_ACLK_GSCL, 0xfff }, + { ENABLE_PCLK_GSCL, 0xff }, +}; + /* list of all parent clock list */ PNAME(aclk_gscl_111_user_p) = { "oscclk", "aclk_gscl_111", }; PNAME(aclk_gscl_333_user_p) = { "oscclk", "aclk_gscl_333", }; @@ -3436,15 +3455,11 @@ static void __init exynos5433_cmu_g3d_init(struct device_node *np) .nr_clk_ids = GSCL_NR_CLK, .clk_regs = gscl_clk_regs, .nr_clk_regs = ARRAY_SIZE(gscl_clk_regs), + .suspend_regs = gscl_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(gscl_suspend_regs), + .clk_name = "aclk_gscl_111", }; -static void __init exynos5433_cmu_gscl_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &gscl_cmu_info); -} -CLK_OF_DECLARE(exynos5433_cmu_gscl, "samsung,exynos5433-cmu-gscl", - exynos5433_cmu_gscl_init); - /* * Register offset definitions for CMU_APOLLO */ @@ -3970,6 +3985,11 @@ static void __init exynos5433_cmu_atlas_init(struct device_node *np) ENABLE_IP_MSCL_SECURE_SMMU_JPEG, }; +static const struct samsung_clk_reg_dump mscl_suspend_regs[] = { + { MUX_SEL_MSCL0, 0 }, + { MUX_SEL_MSCL1, 0 }, +}; + /* list of all parent clock list */ PNAME(mout_sclk_jpeg_user_p) = { "oscclk", "sclk_jpeg_mscl", }; PNAME(mout_aclk_mscl_400_user_p) = { "oscclk", "aclk_mscl_400", }; @@ -4082,15 +4102,11 @@ static void __init exynos5433_cmu_atlas_init(struct device_node *np) .nr_clk_ids = MSCL_NR_CLK, .clk_regs = mscl_clk_regs, .nr_clk_regs = ARRAY_SIZE(mscl_clk_regs), + .suspend_regs = mscl_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(mscl_suspend_regs), + .clk_name = "aclk_mscl_400", }; -static void __init exynos5433_cmu_mscl_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &mscl_cmu_info); -} -CLK_OF_DECLARE(exynos5433_cmu_mscl, "samsung,exynos5433-cmu-mscl", - exynos5433_cmu_mscl_init); - /* * Register offset definitions for CMU_MFC */ @@ -4120,6 +4136,10 @@ static void __init exynos5433_cmu_mscl_init(struct device_node *np) ENABLE_IP_MFC_SECURE_SMMU_MFC, }; +static const struct samsung_clk_reg_dump mfc_suspend_regs[] = { + { MUX_SEL_MFC, 0 }, +}; + PNAME(mout_aclk_mfc_400_user_p) = { "oscclk", "aclk_mfc_400", }; static const struct samsung_mux_clock mfc_mux_clks[] __initconst = { @@ -4190,15 +4210,11 @@ static void __init exynos5433_cmu_mscl_init(struct device_node *np) .nr_clk_ids = MFC_NR_CLK, .clk_regs = mfc_clk_regs, .nr_clk_regs = ARRAY_SIZE(mfc_clk_regs), + .suspend_regs = mfc_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(mfc_suspend_regs), + .clk_name = "aclk_mfc_400", }; -static void __init exynos5433_cmu_mfc_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &mfc_cmu_info); -} -CLK_OF_DECLARE(exynos5433_cmu_mfc, "samsung,exynos5433-cmu-mfc", - exynos5433_cmu_mfc_init); - /* * Register offset definitions for CMU_HEVC */ @@ -4228,6 +4244,10 @@ static void __init exynos5433_cmu_mfc_init(struct device_node *np) ENABLE_IP_HEVC_SECURE_SMMU_HEVC, }; +static const struct samsung_clk_reg_dump hevc_suspend_regs[] = { + { MUX_SEL_HEVC, 0 }, +}; + PNAME(mout_aclk_hevc_400_user_p) = { "oscclk", "aclk_hevc_400", }; static const struct samsung_mux_clock hevc_mux_clks[] __initconst = { @@ -4300,15 +4320,11 @@ static void __init exynos5433_cmu_mfc_init(struct device_node *np) .nr_clk_ids = HEVC_NR_CLK, .clk_regs = hevc_clk_regs, .nr_clk_regs = ARRAY_SIZE(hevc_clk_regs), + .suspend_regs = hevc_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(hevc_suspend_regs), + .clk_name = "aclk_hevc_400", }; -static void __init exynos5433_cmu_hevc_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &hevc_cmu_info); -} -CLK_OF_DECLARE(exynos5433_cmu_hevc, "samsung,exynos5433-cmu-hevc", - exynos5433_cmu_hevc_init); - /* * Register offset definitions for CMU_ISP */ @@ -4342,6 +4358,10 @@ static void __init exynos5433_cmu_hevc_init(struct device_node *np) ENABLE_IP_ISP3, }; +static const struct samsung_clk_reg_dump isp_suspend_regs[] = { + { MUX_SEL_ISP, 0 }, +}; + PNAME(mout_aclk_isp_dis_400_user_p) = { "oscclk", "aclk_isp_dis_400", }; PNAME(mout_aclk_isp_400_user_p) = { "oscclk", "aclk_isp_400", }; @@ -4553,15 +4573,11 @@ static void __init exynos5433_cmu_hevc_init(struct device_node *np) .nr_clk_ids = ISP_NR_CLK, .clk_regs = isp_clk_regs, .nr_clk_regs = ARRAY_SIZE(isp_clk_regs), + .suspend_regs = isp_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(isp_suspend_regs), + .clk_name = "aclk_isp_400", }; -static void __init exynos5433_cmu_isp_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &isp_cmu_info); -} -CLK_OF_DECLARE(exynos5433_cmu_isp, "samsung,exynos5433-cmu-isp", - exynos5433_cmu_isp_init); - /* * Register offset definitions for CMU_CAM0 */ @@ -4625,6 +4641,15 @@ static void __init exynos5433_cmu_isp_init(struct device_node *np) ENABLE_IP_CAM02, ENABLE_IP_CAM03, }; + +static const struct samsung_clk_reg_dump cam0_suspend_regs[] = { + { MUX_SEL_CAM00, 0 }, + { MUX_SEL_CAM01, 0 }, + { MUX_SEL_CAM02, 0 }, + { MUX_SEL_CAM03, 0 }, + { MUX_SEL_CAM04, 0 }, +}; + PNAME(mout_aclk_cam0_333_user_p) = { "oscclk", "aclk_cam0_333", }; PNAME(mout_aclk_cam0_400_user_p) = { "oscclk", "aclk_cam0_400", }; PNAME(mout_aclk_cam0_552_user_p) = { "oscclk", "aclk_cam0_552", }; @@ -5030,15 +5055,11 @@ static void __init exynos5433_cmu_isp_init(struct device_node *np) .nr_clk_ids = CAM0_NR_CLK, .clk_regs = cam0_clk_regs, .nr_clk_regs = ARRAY_SIZE(cam0_clk_regs), + .suspend_regs = cam0_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(cam0_suspend_regs), + .clk_name = "aclk_cam0_400", }; -static void __init exynos5433_cmu_cam0_init(struct device_node *np) -{ - samsung_cmu_register_one(np, &cam0_cmu_info); -} -CLK_OF_DECLARE(exynos5433_cmu_cam0, "samsung,exynos5433-cmu-cam0", - exynos5433_cmu_cam0_init); - /* * Register offset definitions for CMU_CAM1 */ @@ -5085,6 +5106,12 @@ static void __init exynos5433_cmu_cam0_init(struct device_node *np) ENABLE_IP_CAM12, }; +static const struct samsung_clk_reg_dump cam1_suspend_regs[] = { + { MUX_SEL_CAM10, 0 }, + { MUX_SEL_CAM11, 0 }, + { MUX_SEL_CAM12, 0 }, +}; + PNAME(mout_sclk_isp_uart_user_p) = { "oscclk", "sclk_isp_uart_cam1", }; PNAME(mout_sclk_isp_spi1_user_p) = { "oscclk", "sclk_isp_spi1_cam1", }; PNAME(mout_sclk_isp_spi0_user_p) = { "oscclk", "sclk_isp_spi0_cam1", }; @@ -5403,11 +5430,223 @@ static void __init exynos5433_cmu_cam0_init(struct device_node *np) .nr_clk_ids = CAM1_NR_CLK, .clk_regs = cam1_clk_regs, .nr_clk_regs = ARRAY_SIZE(cam1_clk_regs), + .suspend_regs = cam1_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(cam1_suspend_regs), + .clk_name = "aclk_cam1_400", +}; + + +struct exynos5433_cmu_data { + struct samsung_clk_reg_dump *clk_save; + unsigned int nr_clk_save; + const struct samsung_clk_reg_dump *clk_suspend; + unsigned int nr_clk_suspend; + + struct clk *clk; + struct clk **pclks; + int nr_pclks; + + /* must be the last entry */ + struct samsung_clk_provider ctx; +}; + +static int exynos5433_cmu_suspend(struct device *dev) +{ + struct exynos5433_cmu_data *data = dev_get_drvdata(dev); + int i; + + samsung_clk_save(data->ctx.reg_base, data->clk_save, + data->nr_clk_save); + + for (i = 0; i < data->nr_pclks; i++) + clk_prepare_enable(data->pclks[i]); + + /* for suspend some registers have to be set to certain values */ + samsung_clk_restore(data->ctx.reg_base, data->clk_suspend, + data->nr_clk_suspend); + + for (i = 0; i < data->nr_pclks; i++) + clk_disable_unprepare(data->pclks[i]); + + clk_disable_unprepare(data->clk); + + return 0; +} + +static int exynos5433_cmu_resume(struct device *dev) +{ + struct exynos5433_cmu_data *data = dev_get_drvdata(dev); + int i; + + clk_prepare_enable(data->clk); + + for (i = 0; i < data->nr_pclks; i++) + clk_prepare_enable(data->pclks[i]); + + samsung_clk_restore(data->ctx.reg_base, data->clk_save, + data->nr_clk_save); + + for (i = 0; i < data->nr_pclks; i++) + clk_disable_unprepare(data->pclks[i]); + + return 0; +} + +static int __init exynos5433_cmu_probe(struct platform_device *pdev) +{ + const struct samsung_cmu_info *info; + struct exynos5433_cmu_data *data; + struct samsung_clk_provider *ctx; + struct device *dev = &pdev->dev; + struct resource *res; + void __iomem *reg_base; + int i; + + info = of_device_get_match_data(dev); + + data = devm_kzalloc(dev, sizeof(*data) + + sizeof(*data->ctx.clk_data.hws) * info->nr_clk_ids, + GFP_KERNEL); + if (!data) + return -ENOMEM; + ctx = &data->ctx; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_base = devm_ioremap_resource(dev, res); + if (IS_ERR(reg_base)) { + dev_err(dev, "failed to map registers\n"); + return PTR_ERR(reg_base); + } + + for (i = 0; i < info->nr_clk_ids; ++i) + ctx->clk_data.hws[i] = ERR_PTR(-ENOENT); + + ctx->clk_data.num = info->nr_clk_ids; + ctx->reg_base = reg_base; + ctx->dev = dev; + spin_lock_init(&ctx->lock); + + data->clk_save = samsung_clk_alloc_reg_dump(info->clk_regs, + info->nr_clk_regs); + data->nr_clk_save = info->nr_clk_regs; + data->clk_suspend = info->suspend_regs; + data->nr_clk_suspend = info->nr_suspend_regs; + data->nr_pclks = of_count_phandle_with_args(dev->of_node, "clocks", + "#clock-cells"); + if (data->nr_pclks > 0) { + data->pclks = devm_kcalloc(dev, sizeof(struct clk *), + data->nr_pclks, GFP_KERNEL); + + for (i = 0; i < data->nr_pclks; i++) { + struct clk *clk = of_clk_get(dev->of_node, i); + + if (IS_ERR(clk)) + return PTR_ERR(clk); + data->pclks[i] = clk; + } + } + + if (info->clk_name) + data->clk = clk_get(dev, info->clk_name); + clk_prepare_enable(data->clk); + + platform_set_drvdata(pdev, data); + + /* + * 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); + + if (info->pll_clks) + samsung_clk_register_pll(ctx, info->pll_clks, info->nr_pll_clks, + reg_base); + if (info->mux_clks) + samsung_clk_register_mux(ctx, info->mux_clks, + info->nr_mux_clks); + if (info->div_clks) + samsung_clk_register_div(ctx, info->div_clks, + info->nr_div_clks); + if (info->gate_clks) + samsung_clk_register_gate(ctx, info->gate_clks, + info->nr_gate_clks); + if (info->fixed_clks) + samsung_clk_register_fixed_rate(ctx, info->fixed_clks, + info->nr_fixed_clks); + if (info->fixed_factor_clks) + samsung_clk_register_fixed_factor(ctx, info->fixed_factor_clks, + info->nr_fixed_factor_clks); + + samsung_clk_of_add_provider(dev->of_node, ctx); + pm_runtime_put_sync(dev); + + return 0; +} + +static const struct of_device_id exynos5433_cmu_of_match[] = { + { + .compatible = "samsung,exynos5433-cmu-aud", + .data = &aud_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-cam0", + .data = &cam0_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-cam1", + .data = &cam1_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-disp", + .data = &disp_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-g2d", + .data = &g2d_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-g3d", + .data = &g3d_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-fsys", + .data = &fsys_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-gscl", + .data = &gscl_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-mfc", + .data = &mfc_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-hevc", + .data = &hevc_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-isp", + .data = &isp_cmu_info, + }, { + .compatible = "samsung,exynos5433-cmu-mscl", + .data = &mscl_cmu_info, + }, { + }, +}; + +static const struct dev_pm_ops exynos5433_cmu_pm_ops = { + SET_RUNTIME_PM_OPS(exynos5433_cmu_suspend, exynos5433_cmu_resume, + NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +static struct platform_driver exynos5433_cmu_driver __refdata = { + .driver = { + .name = "exynos5433-cmu", + .of_match_table = exynos5433_cmu_of_match, + .suppress_bind_attrs = true, + .pm = &exynos5433_cmu_pm_ops, + }, + .probe = exynos5433_cmu_probe, }; -static void __init exynos5433_cmu_cam1_init(struct device_node *np) +static int __init exynos5433_cmu_init(void) { - samsung_cmu_register_one(np, &cam1_cmu_info); + return platform_driver_register(&exynos5433_cmu_driver); } -CLK_OF_DECLARE(exynos5433_cmu_cam1, "samsung,exynos5433-cmu-cam1", - exynos5433_cmu_cam1_init); +core_initcall(exynos5433_cmu_init); diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index f0acae4f5d1b..d93031e94387 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -353,6 +353,12 @@ struct samsung_cmu_info { /* list and number of clocks registers */ const unsigned long *clk_regs; unsigned int nr_clk_regs; + + /* list and number of clocks registers to set before suspend */ + const struct samsung_clk_reg_dump *suspend_regs; + unsigned int nr_suspend_regs; + /* name of the parent clock needed for CMU register access */ + const char *clk_name; }; extern struct samsung_clk_provider *__init samsung_clk_init( From patchwork Mon Aug 21 08:05:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 110504 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp959034qge; Mon, 21 Aug 2017 01:05:56 -0700 (PDT) X-Received: by 10.84.151.3 with SMTP id i3mr18201998pli.377.1503302756763; Mon, 21 Aug 2017 01:05:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503302756; cv=none; d=google.com; s=arc-20160816; b=Yf4885+vLQVXcJ8GpetqkQZ0JK2lsVKO7k9ky3uE9OMPy3jnXChOjQsSL8zJ3iEkDz YkRoyndrtNonHb+ysJqCwszo/kbbWv5kQXzoeUD292c94FjchzH3SbAiM8doy+qslZyL Op7ALxUuKEoWwvmiuWVyf+iQpf7yw7M0T8BYRFohB65bH62F3vOE1CsBTxGJO/1rQn7X 1cV5wifs6KrkuLdbExOFDXfyZ11Xl6nx6y55GUgzuqLmCRFT43sfLSkY3fANIzlecMeN qGewOCroSc0lemUUIi61nMVHPRtMqKsSYCDRTpcx8c3YR/AhN+s91VFjQdF8f3lp2UIx PqGQ== 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=Qh1K3442/kWCuAFWUj2rMHR1lDpQeloV1Uatnaj8uTk=; b=BCNxWG4pNiJYhsTyFmYNr3xZYj53Y3mTZ9CtdoxZP1qH/ONE+daXHD/XCKVd9FVXDj 01M8/HmEBYrQCy++NXnjyetsPHVoDPFNcz94IRObxkOpTqQMr9bFFHFTM8fXo9LNf9D/ 3RrWvJ/6NdaRl7qmQeQCuiM8EUSPmSwvp7FlPL17RY1hqpV3fyjKRUeoBvLr4XNLml72 LCQ2v7fIcXpY4ZpzY42lBwb8coRmswjIhSNUAOMiw8JLP61l58zc8DP586WgxKE+F9WG 9jiufpHRdADCt65C3HOeW208/kHWDoSqDHCtk+DUfVCGMH9PbF/4o5DQxJV624Vu2uQh i2bA== ARC-Authentication-Results: i=1; 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; 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 38si8019515plc.179.2017.08.21.01.05.56; Mon, 21 Aug 2017 01:05:56 -0700 (PDT) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752141AbdHUIFy (ORCPT + 12 others); Mon, 21 Aug 2017 04:05:54 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:56945 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751923AbdHUIFn (ORCPT ); Mon, 21 Aug 2017 04:05:43 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20170821080541euoutp01ce7937b931fcc3af08d75bf223535c48~czeD6r3Bv2331623316euoutp01o; Mon, 21 Aug 2017 08:05:41 +0000 (GMT) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170821080541eucas1p1625d7fd5b2f6abd53cfed573aa8d5eaf~czeDNiica0789107891eucas1p1k; Mon, 21 Aug 2017 08:05:41 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 3E.B9.12907.4549A995; Mon, 21 Aug 2017 09:05:40 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170821080540eucas1p25bd0c482fdb581bca68bc875bdfedc87~czeClqWC81148811488eucas1p2X; Mon, 21 Aug 2017 08:05:40 +0000 (GMT) X-AuditID: cbfec7f1-f793a6d00000326b-dd-599a9454c4a9 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id BF.B4.20118.4549A995; Mon, 21 Aug 2017 09:05:40 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OV0009QWZT303A0@eusync1.samsung.com>; Mon, 21 Aug 2017 09:05:40 +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 v9 4/5] clk: samsung: exynos-audss: Use local variable for controller's device Date: Mon, 21 Aug 2017 10:05:02 +0200 Message-id: <1503302703-13801-5-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1503302703-13801-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrAIsWRmVeSWpSXmKPExsWy7djP87ohU2ZFGhyZrW+xccZ6VovrX56z Wky6P4HF4vz5DewWmx5fY7X42HOP1eJz7xFGixnn9zFZrD1yl93i4ilXi8Nv2lktfpzpZrE4 vjbcgdfj/Y1Wdo/Lfb1MHptWdbJ53Lm2h81j85J6j74tqxg9Pm+SC2CP4rJJSc3JLEst0rdL 4Mp4dP08U8FluYrZny4zNTCulOxi5OSQEDCRmDjlICOELSZx4d56ti5GLg4hgaWMEjMWHGOB cD4zSjT/2MYM0zFv6l12iMQyRomzJ55AVTUwSdx7tZUFpIpNwFCi620X2CwRgSZGiYkb1rOC OMwCTcwS0/ZNZAKpEhZIkPi0dB0biM0ioCrx5/MJdhCbV8BD4sCEqSwQ++QkTh6bzApicwp4 SuybsRFskITAKnaJr58XAJ3OAeTISmw6AHWfi8SENTegPhKWeHV8CzuELSNxeXI31Mx+Romm Vm0IewajxLm3vBC2tcTh4xfBdjEL8ElM2jadGWI8r0RHmxBEiYdE54HLUCMdJSZ+P8gM8f0c YBitfs86gVFmASPDKkaR1NLi3PTUYiO94sTc4tK8dL3k/NxNjMB0cPrf8Y87GN+fsDrEKMDB qMTDa1A0K1KINbGsuDL3EKMEB7OSCC/flJmRQrwpiZVVqUX58UWlOanFhxilOViUxHlto9oi hQTSE0tSs1NTC1KLYLJMHJxSDYwKXbInfrBFlj3im5kR+dYi+G3IYo1J/uuZ54pK/VWcEnhe 8ZPs852XFjQKsc/pTYlmmFGp0fdrTfnvR4ebuMJzlE9u7tco22PQdNa77h7nj4/bdGs6bCZz HLjXH7c5V6f0WRrzVRZx2S9XVos2BXFnT/RcLMVWechyyvYLvFs2X3qwJLBItFyJpTgj0VCL uag4EQAOigpxAwMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprAIsWRmVeSWpSXmKPExsVy+t/xy7ohU2ZFGhz5LGKxccZ6VovrX56z Wky6P4HF4vz5DewWmx5fY7X42HOP1eJz7xFGixnn9zFZrD1yl93i4ilXi8Nv2lktfpzpZrE4 vjbcgdfj/Y1Wdo/Lfb1MHptWdbJ53Lm2h81j85J6j74tqxg9Pm+SC2CPcrPJSE1MSS1SSM1L zk/JzEu3VQoNcdO1UFLIS8xNtVWK0PUNCVJSKEvMKQXyjAzQgINzgHuwkr5dglvGo+vnmQou y1XM/nSZqYFxpWQXIyeHhICJxLypd9khbDGJC/fWs3UxcnEICSxhlJjePYsVwmlikjh55Qob SBWbgKFE19susCoRgSZGiSd909hBHGaBNmaJ/x1fGUGqhAUSJD4tXQfWwSKgKvHn8wmwHbwC HhIHJkxlgdgnJ3Hy2GRWEJtTwFNi34yNYLYQUM3tjhuMExh5FzAyrGIUSS0tzk3PLTbSK07M LS7NS9dLzs/dxAiMjW3Hfm7Zwdj1LvgQowAHoxIP7438WZFCrIllxZW5hxglOJiVRHj5psyM FOJNSaysSi3Kjy8qzUktPsRoCnTURGYp0eR8YNzmlcQbmhiaWxoaGVtYmBsZKYnzql9uihQS SE8sSc1OTS1ILYLpY+LglGpgPCLDvrSj2nZ57ZFQjceCNSYW/KJTzaYGX8n6wH3kgEFIx6mc pWGlEj639X5vaWjv1+04tGoJz8TK/RXrp2+QF7vj6Ph6e0nN33/XRcKnNoRO5XucJ7V2X2mh 49fF6RH1vZtCMtqUN7junysnE7/QQKpPWrtSt85/ruNGv9Unjlz4qbl1g/ctJZbijERDLeai 4kQAiC863qMCAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170821080540eucas1p25bd0c482fdb581bca68bc875bdfedc87 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-CMS-RootMailID: 20170821080540eucas1p25bd0c482fdb581bca68bc875bdfedc87 X-RootMTR: 20170821080540eucas1p25bd0c482fdb581bca68bc875bdfedc87 References: <1503302703-13801-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 Store pointer to the controller's device in local variable to avoid extracting it from platform device in each call. This will also simplify code in the future, when runtime PM support is added. Signed-off-by: Marek Szyprowski Reviewed-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi --- drivers/clk/samsung/clk-exynos-audss.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) -- 1.9.1 diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index 1fab56f396d4..6be52fb46ff3 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -135,6 +135,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 +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_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 +161,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,7 +173,7 @@ 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; } @@ -183,8 +184,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) 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)) @@ -222,7 +223,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) "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", @@ -237,16 +238,16 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) 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; } From patchwork Mon Aug 21 08:05:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 110505 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp959076qge; Mon, 21 Aug 2017 01:05:59 -0700 (PDT) X-Received: by 10.98.80.69 with SMTP id e66mr16103470pfb.60.1503302759266; Mon, 21 Aug 2017 01:05:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503302759; cv=none; d=google.com; s=arc-20160816; b=nFyDSScmKscarqb16XrjFXbULLg9OtoL+EDYmfv+vyBEoPxTYmfH/FewuONlv69nCA CN/WdsZWU8rHv/at7bNVtp5sg5gkgGVO3+cgqxLozR6FVPubxQKUSvu7H4HZ6WKANY0u 6cqJd7gb1ZoXmb5uY5SHdCIFGgGDecxiQfV++gjBtT6vLLXvu4B0adETS23DVr3MUtvZ F3OjjYxiLtz4zW6P2+E0C47WJtjGf9kYXeKv/RWKQwpz2n1Qbhl+fBdvIJ0k0DoHp/7x NET9X9+fdHZEOjTvV85ben4isVBJc1Gcdb5tp6zC4gv8drCNOeo2s1+IKGn8Fw9N1eJA 5aLw== 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=i6iKoorA2Hg1m8YDqwVv6/p8b4j7Py/pfp+xuz1eIqI=; b=D1tSlB9/J/ZUjorL/7PgDh9BfrN5fDLXRynUFaX6d/Mgpm4PsvuMx8UzOoursGa9U2 2Fq2hyDWOd49QLBm9O3FavSI8fbmpPVWhNx6Hi6Cf37pSEe59lPcpmAFWj/d0Qy9ZVA0 m+K7uzg+tIvBJP8DzXH9Ip9K0YFSfHxTQeu3sMKldF00BgwdMkrT3rzjBW7n1zR8XspA hmrkejP2qeGpC1hpb15VwBXE+jFQib1/Dg2R3uclIREwB4a95K9eh0dXad3npvL7NzNC 3yilQK5OtvCO5zWpSdkdr+TA7Oe9FZWTpTtnP0OLel38crtBR4M2RMWgzzHuK42bta44 v/9A== ARC-Authentication-Results: i=1; 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; 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 38si8019515plc.179.2017.08.21.01.05.58; Mon, 21 Aug 2017 01:05:59 -0700 (PDT) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752234AbdHUIF4 (ORCPT + 12 others); Mon, 21 Aug 2017 04:05:56 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:46197 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751941AbdHUIFn (ORCPT ); Mon, 21 Aug 2017 04:05:43 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20170821080542euoutp02da5c113ddd6587d7b8be94432c45c306~czeEI2Z5p1767817678euoutp02_; Mon, 21 Aug 2017 08:05:42 +0000 (GMT) Received: from eusmges1.samsung.com (unknown [203.254.199.239]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170821080541eucas1p2be473130c3b7412cba0ab625d057e567~czeDvZKdb1431914319eucas1p2K; Mon, 21 Aug 2017 08:05:41 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges1.samsung.com (EUCPMTA) with SMTP id C9.05.12576.5549A995; Mon, 21 Aug 2017 09:05:41 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170821080540eucas1p2e07bb23e15027aca9563316a5fbf1597~czeDGbVNF0170501705eucas1p2r; Mon, 21 Aug 2017 08:05:40 +0000 (GMT) X-AuditID: cbfec7ef-f79ee6d000003120-c9-599a9455621d Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 90.C4.20118.4549A995; Mon, 21 Aug 2017 09:05:40 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OV0009QWZT303A0@eusync1.samsung.com>; Mon, 21 Aug 2017 09:05:40 +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 v9 5/5] clk: samsung: exynos-audss: Add support for runtime PM Date: Mon, 21 Aug 2017 10:05:03 +0200 Message-id: <1503302703-13801-6-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1503302703-13801-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrHIsWRmVeSWpSXmKPExsWy7djP87qhU2ZFGuyZIGKxccZ6VovrX56z Wky6P4HF4vz5DewWmx5fY7X42HOP1eJz7xFGixnn9zFZrD1yl93i4ilXi8Nv2lktfpzpZrE4 vjbcgdfj/Y1Wdo/Lfb1MHptWdbJ53Lm2h81j85J6j74tqxg9Pm+SC2CP4rJJSc3JLEst0rdL 4MrY07+eseCtVUXP9TtMDYwLDLsYOTkkBEwkJq2YyQ5hi0lcuLeerYuRi0NIYBmjxMS3Dxgh nM+MEqcmfGXuYuQA6ziyMQiu6Pj5fSwQTgOTxL1XW1lARrEJGEp0ve0CGyUi0AQ0asN6VhCH WaCJWWLavolMIFXCAgES21bdZwOxWQRUJebNvcsIYvMKeEicubqCCeIoOYmTxyazgticAp4S +2ZsZIWIr2KX+HmpGuIkWYlNB5ghwi4SG65/gfpHWOLV8S1QtozE5cndLBB2P6NEU6s2hD2D UeLcW14I21ri8PGLYOOZBfgkJm2bDvUxr0RHmxBEiYfEj69TGSFsR4lZXUeZIJ6fwyixbO98 xgmMMgsYGVYxiqSWFuempxYb6hUn5haX5qXrJefnbmIEpoLT/46/38H4tDnkEKMAB6MSD++N /FmRQqyJZcWVuYcYJTiYlUR4+abMjBTiTUmsrEotyo8vKs1JLT7EKM3BoiTOaxvVFikkkJ5Y kpqdmlqQWgSTZeLglGpgbONSLA3v11h9TFt2wd6DDxYpGN4wCzc//uvTjmNSWyNcSrYcTNu6 bot96YXXW74Ue/3XreiUXbbEPueZruHR1JKHuzZbmv6wmslorui3yy//5uYHnLealKfpyATU Lj+3J2Nhxusv2rKf358ISzdf+pZzYpPcF17304pTTqUycpRVbbD+zdH9XYmlOCPRUIu5qDgR AIx5C84BAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnkeLIzCtJLcpLzFFi42I5/e/4Zd2QKbMiDbYfNLPYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHudlkpCampBYppOYl 56dk5qXbKoWGuOlaKCnkJeam2ipF6PqGBCkplCXmlAJ5RgZowME5wD1YSd8uwS1jT/96xoK3 VhU91+8wNTAuMOxi5OCQEDCROLIxqIuRE8gUk7hwbz1bFyMXh5DAEkaJvkmboZwmJomTV66w gVSxCRhKdL3tAkuICDQxSjzpm8YO4jALtDFL/O/4yghSJSzgJ7Fi2gxWEJtFQFVi3ty7YHFe AQ+JM1dXMEHsk5M4eWwyWA2ngKfEvhkbwWwhoJrbHTcYJzDyLmBkWMUoklpanJueW2ykV5yY W1yal66XnJ+7iREYGduO/dyyg7HrXfAhRgEORiUe3hv5syKFWBPLiitzDzFKcDArifDyTZkZ KcSbklhZlVqUH19UmpNafIjRFOioicxSosn5wKjNK4k3NDE0tzQ0MrawMDcyUhLnVb/cFCkk kJ5YkpqdmlqQWgTTx8TBKQUMuWDTSWaHHqRdY/pxRP6o49GsqpQH17l/Nh8XXGkdcSSI+3vx u4r57w1quA+es57Vu2enjh5//fpXkoIV217NzLOU7GR/klt1Kn5a9BsllyC3ZYYqyldfPGDq cWDJnMo9c073sosBq+JPnM9701Q87cdvZyV+rn/u8w8tz1wqHym41z76cCyDEktxRqKhFnNR cSIA3gn64qICAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170821080540eucas1p2e07bb23e15027aca9563316a5fbf1597 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-CMS-RootMailID: 20170821080540eucas1p2e07bb23e15027aca9563316a5fbf1597 X-RootMTR: 20170821080540eucas1p2e07bb23e15027aca9563316a5fbf1597 References: <1503302703-13801-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 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(-) -- 1.9.1 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 = {