From patchwork Wed Aug 9 10:35: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: 109704 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp675841qge; Wed, 9 Aug 2017 03:35:26 -0700 (PDT) X-Received: by 10.84.232.133 with SMTP id i5mr8566828plk.240.1502274926041; Wed, 09 Aug 2017 03:35:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502274926; cv=none; d=google.com; s=arc-20160816; b=wtuw8MhGhT8c8CDptPXkyHf8klrIzcL+7EqKaefwHGWZVNiYMKWTX0HJGPsdO1A/hD Z5LUxRRXuLfXTieVgq750eXVG+So9n+reCJ3UKcQkFHFsSU/I6wenzhaRb4u5kqZKQlp 5dWOr+9+kBBp/j4ZnQ7JTQGFLaovlBtwETISH11HPCfZUjCd4A+P6Ixn/Q6MVMFzd0WR Ih42H3gp3cxJwVY/d35aZv0t1vtNorsDqVLBddpSPE+M3Sqr9EWmcmFRYQMMB+SjpX+S u9zjoKDezCTnj7zU7nSlLBFuCdn6H1q05zQJlMxPxLcbgxfCDUUwva0HgdkC8hkGxOIm FnWA== 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=Vu+TysZiwF0oZPCNWqbUTodKUpBQTBOpqI1sD+i78FE=; b=e8B/qd/wGOVmJvutyYrwOw9WkmOKEmXsgnYuiqwsWl1+V83AIC+1wK6S0/QAsjII8g J4Tas2qOXwgxr1RWKSdWBtSQnzT6m/pXG7Bmu9IyC3ceWBbebSfmGUjEMg8jN90bTQJ3 67N/qpcXsLWxuus/5UuXSdJyRT8Wp+eaIxujWM14xs33ShQP3GBHvY9X1r3PnKRVxGnp ZVOMhpYrxJD5/ZQyXXvNKt93alcah2P9A4iXD9HkXjodd18hjJn4383xtPjbZqr5BGhl irIKvR2cn6rwRnnhOqVzsDkCNXtM03TwC9fBMzPOhM8zZOpzvB3rRfsU2aCSebU4xwRp tDgw== 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 s16si2577877plk.305.2017.08.09.03.35.25; Wed, 09 Aug 2017 03:35:26 -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 S1752191AbdHIKfX (ORCPT + 12 others); Wed, 9 Aug 2017 06:35:23 -0400 Received: from mailout4.w1.samsung.com ([210.118.77.14]:42277 "EHLO mailout4.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751890AbdHIKfR (ORCPT ); Wed, 9 Aug 2017 06:35:17 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OUE002Z8YQQM860@mailout4.w1.samsung.com>; Wed, 09 Aug 2017 11:35:14 +0100 (BST) Received: from eusmges5.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170809103513eucas1p268fa00c7a0ce7a1c767932e34bd3a7b8~ZJxMWbsJs2192121921eucas1p2K; Wed, 9 Aug 2017 10:35:13 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges5.samsung.com (EUCPMTA) with SMTP id 65.46.12743.165EA895; Wed, 9 Aug 2017 11:35:13 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170809103512eucas1p2eb66401b357d82bed91182a5a1b1fea9~ZJxLt19EJ2192821928eucas1p2L; Wed, 9 Aug 2017 10:35:12 +0000 (GMT) X-AuditID: cbfec7f5-f79d06d0000031c7-43-598ae561f40f Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id DC.75.20118.065EA895; Wed, 9 Aug 2017 11:35:12 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OUE00IH6YQKHB00@eusync2.samsung.com>; Wed, 09 Aug 2017 11:35:12 +0100 (BST) From: Marek Szyprowski To: linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Marek Szyprowski , Stephen Boyd , Michael Turquette , Ulf Hansson , Sylwester Nawrocki , Chanwoo Choi , Inki Dae , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [PATCH v8 1/5] clk: Add support for runtime PM Date: Wed, 09 Aug 2017 12:35:03 +0200 Message-id: <1502274907-11931-2-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrPIsWRmVeSWpSXmKPExsWy7djPc7qJT7siDRZtFbPYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHcdmkpOZklqUW6dsl cGXMb/zKUvDHp2Jyz3bmBsartl2MnBwSAiYS3afPsUDYYhIX7q1n62Lk4hASWMoosfnGPWYI 5zOjxPf9O4CqOMA6lv5JgIgvY5S4u/M6K4TTwCSxetMJsFFsAoYSXW+7wEaJCDQxSkzcsB6s ilmgiVli2r6JTCBVwgLmEjdvbwHrYBFQlVi+dgFYnFfAQ+LrjsnsEEfJSZw8NpkVxOYU8JRY P+cW2E0SAuvYJfqmNEDdJCux6QAzRL2LxPGF2xghbGGJV8e3QM2Rkbg8uRvq0X5GiaZWbQh7 BqPEube8ELa1xOHjF8F2MQvwSUzaNp0ZYjyvREebEESJh8T295ugxjhKrJ6/ngXi+zmMEge2 HmGfwCizgJFhFaNIamlxbnpqsalecWJucWleul5yfu4mRmAyOP3v+NcdjEuPWR1iFOBgVOLh vbGnM1KINbGsuDL3EKMEB7OSCO/zx12RQrwpiZVVqUX58UWlOanFhxilOViUxHlto9oihQTS E0tSs1NTC1KLYLJMHJxSDYxS57xz0xTs2kJcAntkCiqmbdn8remhyuaVrvq73zCHL1ocV7t1 4e388J+1+67U6cpoV7VeKtWs+v8kcs3jNa8cAratXHrbc1/A3IydiorPZdQvm/1a2/oytrWm UfXN/OnMzNu6DJ8f5FXZnzXfeUJqM8vuk1Uml70trXTe/So347+938PkxQElluKMREMt5qLi RAA6wXAfAgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnkeLIzCtJLcpLzFFi42I5/e/4Fd2Ep12RBvPuW1hsnLGe1eL6l+es FpPuT2CxOH9+A7vFpsfXWC0+9txjtfjce4TRYsb5fUwWa4/cZbe4eMrV4vCbdlaLH2e6WSyO rw134PV4f6OV3eNyXy+Tx6ZVnWwed67tYfPYvKTeo2/LKkaPz5vkAtij3GwyUhNTUosUUvOS 81My89JtlUJD3HQtlBTyEnNTbZUidH1DgpQUyhJzSoE8IwM04OAc4B6spG+X4JYxv/ErS8Ef n4rJPduZGxiv2nYxcnBICJhILP2T0MXICWSKSVy4t56ti5GLQ0hgCaPEu+b5jBBOE5PE7Ltz GUGq2AQMJbredoFViQg0MUo86ZvGDuIwC7QxS/zv+ApWJSxgLnHz9hYWEJtFQFVi+doFTCA2 r4CHxNcdk9kh9slJnDw2mRXE5hTwlFg/5xYziC0EVHPv2CaWCYy8CxgZVjGKpJYW56bnFhvp FSfmFpfmpesl5+duYgRGxrZjP7fsYOx6F3yIUYCDUYmH98aezkgh1sSy4srcQ4wSHMxKIrxi wLgS4k1JrKxKLcqPLyrNSS0+xGgKdNREZinR5Hxg1OaVxBuaGJpbGhoZW1iYGxkpifOqX26K FBJITyxJzU5NLUgtgulj4uCUamAM/iXp/HDruW83ta9UNWw6KHhfWX5d1pzpJ8x6VpmfMqp9 IvHFKmr/zjsyL8X3Mr4Vu1XwuejuN++MY0KmupP/VTj8+xdR5qSgtW7mPveFKxXiyrhTVOYo G715ltI38bGXzlK38ixzN6EtLks9nvefeau8cMcH9QOm3rVXJppuPtErkJL92fmtEktxRqKh FnNRcSIAqRm9KaICAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170809103512eucas1p2eb66401b357d82bed91182a5a1b1fea9 X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?utf-8?q?Marek_Szyprowski=1BSRPOL-Kernel_=28TP=29=1B?= =?utf-8?b?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?utf-8?q?Marek_Szyprowski=1BSRPOL-Kernel_=28TP=29=1BSam?= =?utf-8?q?sung_Electronics=1BSenior_Software_Engineer?= X-Sender-Code: =?utf-8?q?C10=1BEHQ=1BC10CD02CD027392?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170809103512eucas1p2eb66401b357d82bed91182a5a1b1fea9 X-RootMTR: 20170809103512eucas1p2eb66401b357d82bed91182a5a1b1fea9 References: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org 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 | 129 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 15 deletions(-) -- 1.9.1 diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index fc58c52a26b4..eb11a6a0e1d0 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(); @@ -2583,6 +2673,12 @@ 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; + ret = clk_pm_runtime_get(core); + if (ret) + goto fail_pm; + } if (dev && dev->driver) core->owner = dev->driver->owner; core->hw = hw; @@ -2629,12 +2725,13 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) } ret = __clk_core_init(core); - if (!ret) + if (!ret) { + clk_pm_runtime_put(core); return hw->clk; + } __clk_free_clk(hw->clk); hw->clk = NULL; - fail_parents: kfree(core->parents); fail_parent_names_copy: @@ -2642,6 +2739,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) kfree_const(core->parent_names[i]); kfree(core->parent_names); fail_parent_names: + clk_pm_runtime_put(core); +fail_pm: kfree_const(core->name); fail_name: kfree(core); From patchwork Wed Aug 9 10:35:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 109703 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp675804qge; Wed, 9 Aug 2017 03:35:23 -0700 (PDT) X-Received: by 10.99.109.72 with SMTP id i69mr7046565pgc.226.1502274923775; Wed, 09 Aug 2017 03:35:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502274923; cv=none; d=google.com; s=arc-20160816; b=Su+GGjOnFvCAilh7NCFM2d9kXgWOCGWTj6pHNcPac96A5qG38zJdmdnKgNzd2xtSSK ZQO/1YdG6z/id3jU8ifJs1yP2LFOPXnPQYLM6bnAaX3HUKwB3YuF8Ii9D/n1RCi0ECNo O7C0nclA+Zn7KxezAaBqAwrOgbKqCPmn4ahh0btHaMMPCcWq94Q4pdYMNTwGcL/ShBMp Xe3d0+tYKXHZTbe/2X9xAEHepDo/5qCoW02HridJPgW5coc1d30OpiTeTjCN/GVl4mdV 9HKLMi5X7Ezf2OAxnfmR1GsFMmWVVhmC9Oxevjxi0ywKH489VK1kysNzR7FtT3JiyzWz dhBw== 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=MNR8zAFUwMl5mPHJXl1fYNnGbc2Nkf+JW3IBFTwtYg8/dzvFXQqLXYS90ztCjcLm+T U4rK2/FbzpAKQd59tqiyXTVmCrpUQUIdKJ15S/wU/++yBIujBcSQxmtsMvG5sAyTzUna tZoR8sdvbARc/Z+4SGYoI5rgCWh58ALkKqVM3yatZzHUlIr9njN0izjuZNkcbLTxXDpe wDS5Yg7ladHfqaT5FzlgMGpmzokqUv/YKQHm8UuTbJlN6j6YcxmtRsOML/RcXUJSOaCd 6Ernfvr4cFPIg296qYZ9urJz4mDBcDH5QtyFAN/O425H8k5RKRPs2w68iSDem1h60MJ4 QCGg== 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 s16si2577877plk.305.2017.08.09.03.35.23; Wed, 09 Aug 2017 03:35:23 -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 S1752121AbdHIKfV (ORCPT + 12 others); Wed, 9 Aug 2017 06:35:21 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:48739 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752047AbdHIKfR (ORCPT ); Wed, 9 Aug 2017 06:35:17 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20170809103515euoutp023ba34d20e4b56326c6e5f003edfd0766~ZJxNqhffe1734317343euoutp02e; Wed, 9 Aug 2017 10:35:15 +0000 (GMT) Received: from eusmges3.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170809103514eucas1p255a391d96947dcbec65adcb2133d1553~ZJxM5tucp2191321913eucas1p2L; Wed, 9 Aug 2017 10:35:14 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges3.samsung.com (EUCPMTA) with SMTP id EC.66.12867.165EA895; Wed, 9 Aug 2017 11:35:13 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170809103513eucas1p25e142aac911838847e70a036c5d93131~ZJxMOTeQk2450724507eucas1p28; Wed, 9 Aug 2017 10:35:13 +0000 (GMT) X-AuditID: cbfec7f2-f793b6d000003243-3f-598ae5613c36 Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id BD.75.20118.165EA895; Wed, 9 Aug 2017 11:35:13 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OUE00IH6YQKHB00@eusync2.samsung.com>; Wed, 09 Aug 2017 11:35:13 +0100 (BST) From: Marek Szyprowski To: linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Marek Szyprowski , Stephen Boyd , Michael Turquette , Ulf Hansson , Sylwester Nawrocki , Chanwoo Choi , Inki Dae , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [PATCH v8 2/5] clk: samsung: Add support for runtime PM Date: Wed, 09 Aug 2017 12:35:04 +0200 Message-id: <1502274907-11931-3-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrNIsWRmVeSWpSXmKPExsWy7djP87qJT7siDT7/srLYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHcdmkpOZklqUW6dsl cGUc3TeLpWC1YsWrr2oNjN+kuxg5OCQETCTufXPpYuQEMsUkLtxbz9bFyMUhJLCUUWLHkdWs EM5nRolPOz8yQVSZSCza9pgdxBYSWMYocXppAkRRA5PEvP0XwBJsAoYSXW+7wEaJCDQxSkzc sB5sFLNAE7PEtH0TwUYJCzhIzP15ig3EZhFQlZi8fDYziM0r4CHx/EcrI8Q6OYmTxyazgtic Ap4S6+fcYoaIr2KX+La4FuIHWYlNB6DCLhIXp56FahWWeHV8CzuELSNxeXI3C4TdzyjR1KoN Yc9glDj3lhfCtpY4fPwi2CpmAT6JSdumM0OM55XoaBOCKPGQ+HpzLhtE2FGieWIdxO9zGCUu rX7BOIFRZgEjwypGkdTS4tz01GJjveLE3OLSvHS95PzcTYzAJHD63/FPOxi/nrA6xCjAwajE w9u4qzNSiDWxrLgy9xCjBAezkgjv88ddkUK8KYmVValF+fFFpTmpxYcYpTlYlMR5baPaIoUE 0hNLUrNTUwtSi2CyTBycUg2MYccT8oRWPY70LLz4dsYuhduPt/+ueNikvjpNr+dlU82yVcs2 J24o/H1WY6fzlqAjmeF9O+7qzHpaf91PX8AzLXFLw9UfF/lnvOCZnXlL1dNz2atK5R/FJUrK Kvu/vT+iJrhX8JpI7cEGl/j6y+oNctkV34N8Wi0//Pxc1bTp4dLW3KCdBQtPK7EUZyQaajEX FScCAGZ3xtv+AgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42I5/e/4Fd3Ep12RBhcmy1psnLGe1eL6l+es FpPuT2CxOH9+A7vFpsfXWC0+9txjtfjce4TRYsb5fUwWa4/cZbe4eMrV4vCbdlaLH2e6WSyO rw134PV4f6OV3eNyXy+Tx6ZVnWwed67tYfPYvKTeo2/LKkaPz5vkAtij3GwyUhNTUosUUvOS 81My89JtlUJD3HQtlBTyEnNTbZUidH1DgpQUyhJzSoE8IwM04OAc4B6spG+X4JZxdN8sloLV ihWvvqo1MH6T7mLk5JAQMJFYtO0xO4QtJnHh3no2EFtIYAmjxI/3Nl2MXEB2E5PEmv93WUAS bAKGEl1vu9hAEiICTYwST/qmsYM4zAJtzBL/O74yglQJCzhIzP15CmwUi4CqxOTls5lBbF4B D4nnP1oZIdbJSZw8NpkVxOYU8JRYP+cWM8RqD4l7xzaxTGDkXcDIsIpRJLW0ODc9t9hIrzgx t7g0L10vOT93EyMwLrYd+7llB2PXu+BDjAIcjEo8vDf2dEYKsSaWFVfmHmKU4GBWEuEVA0aV EG9KYmVValF+fFFpTmrxIUZToKMmMkuJJucDYzavJN7QxNDc0tDI2MLC3MhISZxX/XJTpJBA emJJanZqakFqEUwfEwenVAMjwytdkd0bDn+J0F3Sef4ra3DwnJ5uQaa0dx1bjj7RPyX+x+lN /K/6pc+eb5X0O9Kvbjf7n4Pv43iFv5Otv3Ww96u98Lv/pj1k/V6e+FMtrqfibD8XMcUua/L0 V/xbIGX1/NOeSbLXfN7dqimx+/ydR/J+s4ptSYos8w4H64Xn976c2HSu/vEPJZbijERDLeai 4kQApOP6SqECAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170809103513eucas1p25e142aac911838847e70a036c5d93131 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: 20170809103513eucas1p25e142aac911838847e70a036c5d93131 X-RootMTR: 20170809103513eucas1p25e142aac911838847e70a036c5d93131 References: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org 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 Wed Aug 9 10:35:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 109705 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp675883qge; Wed, 9 Aug 2017 03:35:28 -0700 (PDT) X-Received: by 10.98.72.137 with SMTP id q9mr7066481pfi.158.1502274928035; Wed, 09 Aug 2017 03:35:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502274928; cv=none; d=google.com; s=arc-20160816; b=sUcki/H5Q5AWDRZn1IGqrreAc5DG3JCkZVTmOl+jv+ICl5fsLqah3H8EYuM7yqM7MI dGLuTVS60qnaVNqFWViufX/xv7zghEncsGXkvogYWanQb+XT7/nGfNuxs+nsalx3P2Bd 7CV192tTPfZ1V5OYKRY+Q9w1PCpiNoUOokmtTe2BvqawXp0Rf89lurEyqOP+m4l03K/i 8vM6TL9S/jU0LRoFsPzWQye2FX+sbTZmpEgtISN73sTcb711KyCt+cs6zlP5le6Py1Dr B+jsPY3/j47N0aLnwLWSzDZp3RUeQsujsBN/iCMNM7kHjLhb3swxqLQkW+gLeGAzle9/ re8w== 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=l6KOn58EyST1jLBoT22A/OMV9rBjWApxeMxNLIwtD2oCmKPVhCpORIzuEHoujNjMT9 W7dDaXgIxeR9E5igKkbfpGV3Ty4Qh581jAN/vPRKlliCmv6BxvGYXT0igrmrdoXTOnDB QMzPT2Z/q1styNXy7DrmgX2cf3NqAujpltRPoJWEBdPCFiZwANL0JctARRZYYOkoIs4d z9AGYLTfoVeXGdiZ1e1L/5XDDV2fPphoIy6Oxrq5y37mF4FsYmd21sk3dGp/ub4dPZZ1 wdM/MeMYXsMiNkX7pjuaQ3JRTT0/YgdPZqZpBzyCSkYSbysOrBb6SfjjYVayUkIxVei4 gamw== 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 s16si2577877plk.305.2017.08.09.03.35.27; Wed, 09 Aug 2017 03:35:28 -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 S1752319AbdHIKfZ (ORCPT + 12 others); Wed, 9 Aug 2017 06:35:25 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:58566 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752049AbdHIKfS (ORCPT ); Wed, 9 Aug 2017 06:35:18 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20170809103515euoutp01d98122f7c654fc48c89167234a62ce37~ZJxOhg-Bw1909419094euoutp01j; Wed, 9 Aug 2017 10:35:15 +0000 (GMT) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170809103514eucas1p22a05fa1f7394ac46b84e91c8cca3e798~ZJxNhTzuw2989429894eucas1p23; Wed, 9 Aug 2017 10:35:14 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 8B.87.12907.265EA895; Wed, 9 Aug 2017 11:35:14 +0100 (BST) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170809103514eucas1p1d09fbd4d6b9954b24fb6280c7d9eaa02~ZJxMxnDd22580825808eucas1p1_; Wed, 9 Aug 2017 10:35:14 +0000 (GMT) X-AuditID: cbfec7f1-f793a6d00000326b-9b-598ae562d371 Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id A8.65.18832.265EA895; Wed, 9 Aug 2017 11:35:14 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OUE00IH6YQKHB00@eusync2.samsung.com>; Wed, 09 Aug 2017 11:35:14 +0100 (BST) From: Marek Szyprowski To: linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Marek Szyprowski , Stephen Boyd , Michael Turquette , Ulf Hansson , Sylwester Nawrocki , Chanwoo Choi , Inki Dae , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [PATCH v8 3/5] clk: samsung: exynos5433: Add support for runtime PM Date: Wed, 09 Aug 2017 12:35:05 +0200 Message-id: <1502274907-11931-4-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrIIsWRmVeSWpSXmKPExsWy7djPc7pJT7siDSbcUbXYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHcdmkpOZklqUW6dsl cGU8ubOEreD4YcaKp+0HWRoYry1k7GLk5JAQMJFY3LmaGcIWk7hwbz1bFyMXh5DAUkaJc82v oJzPjBJbv/cxwXQ8WLWDHSKxjFFiz+MWKKeBSWLJod9gc9kEDCW63naBtYsINDFKTNywnhXE YRZoYpaYtm8i2CxhAR+J/gVNYNtZBFQljs/9xApi8wp4SCyddAnqQjmJk8cmg8U5BTwl1s+5 xQwySEJgHbvE2g0fgYo4gBxZiU0HoL5wkfg4oxOqV1ji1fEt7BC2jERnx0GoH/oZJZpatSHs GUCfvuWFsK0lDh+/CLaLWYBPYtK26cwQ43klOtqEIEo8JE6vewy11VHi3+V4iOfnMEpcbfrN OoFRZgEjwypGkdTS4tz01GIjveLE3OLSvHS95PzcTYzAhHD63/GPOxjfn7A6xCjAwajEw3tj T2ekEGtiWXFl7iFGCQ5mJRFeryddkUK8KYmVValF+fFFpTmpxYcYpTlYlMR5baPaIoUE0hNL UrNTUwtSi2CyTBycUg2MzRMK//KXpv24mzNxN0vkv1dKy1f2ZLU+6xXOvjV3dr+s2L6yO4Kp Xqsa9nza3TPt5GbvnpSyv4IHGf5lNu298vT7LelNuT9+zd+TemfKW0GG64pSAl6z3WTOZ5dY dZ1kucZoaG3L/2qpaXvD7pjWQwwRa+L7L9U/kpkayabzzHbP2UzHRQt+KbEUZyQaajEXFScC AM+jk+YEAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprAIsWRmVeSWpSXmKPExsVy+t/xK7pJT7siDV7dZrbYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHudlkpCampBYppOYl 56dk5qXbKoWGuOlaKCnkJeam2ipF6PqGBCkplCXmlAJ5RgZowME5wD1YSd8uwS3jyZ0lbAXH DzNWPG0/yNLAeG0hYxcjJ4eEgInEg1U72CFsMYkL99azdTFycAgJLGGUmOjZxcgFZDYxSVx/ NBusnk3AUKLrbRcbSEJEoIlR4knfNHYQh1mgjVnif8dXsCphAR+J/gVNzCA2i4CqxPG5n1hB bF4BD4mlky5BbZaTOHlsMlicU8BTYv2cW2D1QkA1945tYpnAyLuAkWEVo0hqaXFuem6xoV5x Ym5xaV66XnJ+7iZGYGxsO/Zz8w7GSxuDDzEKcDAq8fDe2NMZKcSaWFZcmXuIUYKDWUmE9/nj rkgh3pTEyqrUovz4otKc1OJDjKZAR01klhJNzgfGbV5JvKGJobmloZGxhYW5kZGSOK/65aZI IYH0xJLU7NTUgtQimD4mDk6pBkb59F1TFq9vOF4R1Lq93vizrsm1KQ3TN6obvJ1fu10hZtJb xv1c0jbZz9vrtj93X3Mzpj7urerU7UGN/0qP5K7RnZTg5FxU4TMz1ib0jILZAyaWx3yysRcr opskw6sbBD+smr2oZXZX0vTzqyR6GB0Z3y0wvKod8e12QbNapa/85rtHjl2p51RiKc5INNRi LipOBAARV6TsowIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170809103514eucas1p1d09fbd4d6b9954b24fb6280c7d9eaa02 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: 20170809103514eucas1p1d09fbd4d6b9954b24fb6280c7d9eaa02 X-RootMTR: 20170809103514eucas1p1d09fbd4d6b9954b24fb6280c7d9eaa02 References: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org 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 Wed Aug 9 10:35:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 109707 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp675972qge; Wed, 9 Aug 2017 03:35:33 -0700 (PDT) X-Received: by 10.84.141.131 with SMTP id 3mr8582739plv.224.1502274933009; Wed, 09 Aug 2017 03:35:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502274933; cv=none; d=google.com; s=arc-20160816; b=EKsBCQ+XKMSDTcIqUqk0XtegaYuodjQW/JoAY7nb0+G2Cf6yBTioMt9prh99egMl6X PSI7Z8YD/uf7hJv9og1hZc/n6w2IfIdTjYt7vg65B4PqNi+ZnCdvrvb2bqws3UcrmbWI AOoqJ9sj+427sA/J8sXkXmIEMK0L29XoXk6Xd1dv3uGGlHVgZszOUJE96pPHhGfO3JEh 5Ksv1CQWqRlUYq18sXT9fYZKXfifQ6LsbLwFQJquMIYhGvX9B3x6CoMGJF3vmhUJ//ir hTGbQLgyR9qMGoa8cFOf9J4lRC08GN8zQay2NKve4QlqgyQBAKcO8eyNga4jsW3zZz0X Fivg== 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=CvMwJ79qx3Pyrb4qTUD2UzCfqz6Rbh5NdkFTY4KFYU0=; b=qBgTvULXv8zPgHkPdhjwOttNMqe5C1MKA4QVLgLZPKSSOQ+bPhvAYkk00lQoJihLN3 QmI7cYF92DMPoB9D8xvCGjtyBe4SyUF9lAVRhq3tOwYqfIcD2lhtJzVxuHmM1t05unK0 WDl0TDGuTLvmI+SLcSth2ZbIoxFrMsVidBeJE++urnhuKoNTL3hZs/7MAlYiIoOKWrMQ xsv0OaSHRhzp2x+pOKrq3FC2bqvODC57a5Yw//fxY8lGhyYKAwlD0ZC1kAF8i5VlPFWK XskLSoHFkGdXpSUstGwSEVNneUAY5UhFqBd8FjXPwodFLrKCBdnqv7HKBpkFKccLRwhD Y5NQ== 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 s16si2577877plk.305.2017.08.09.03.35.32; Wed, 09 Aug 2017 03:35:32 -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 S1752271AbdHIKf1 (ORCPT + 12 others); Wed, 9 Aug 2017 06:35:27 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:20461 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752069AbdHIKfS (ORCPT ); Wed, 9 Aug 2017 06:35:18 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OUE00J6MYQRJU40@mailout3.w1.samsung.com>; Wed, 09 Aug 2017 11:35:16 +0100 (BST) Received: from eusmges4.samsung.com (unknown [203.254.199.244]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170809103515eucas1p1dc8f77fa6b3027d08f410e22ceca1127~ZJxOEMzy30529605296eucas1p1X; Wed, 9 Aug 2017 10:35:15 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges4.samsung.com (EUCPMTA) with SMTP id 41.39.12944.365EA895; Wed, 9 Aug 2017 11:35:15 +0100 (BST) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170809103514eucas1p11fb5d1af243e882a5d51a25956d24a19~ZJxNSYt2J2580825808eucas1p1-; Wed, 9 Aug 2017 10:35:14 +0000 (GMT) X-AuditID: cbfec7f4-f79ab6d000003290-f1-598ae5637492 Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id F9.65.18832.265EA895; Wed, 9 Aug 2017 11:35:14 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OUE00IH6YQKHB00@eusync2.samsung.com>; Wed, 09 Aug 2017 11:35:14 +0100 (BST) From: Marek Szyprowski To: linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Marek Szyprowski , Stephen Boyd , Michael Turquette , Ulf Hansson , Sylwester Nawrocki , Chanwoo Choi , Inki Dae , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [PATCH v8 4/5] clk: samsung: exynos-audss: Use local variable for controller's device Date: Wed, 09 Aug 2017 12:35:06 +0200 Message-id: <1502274907-11931-5-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAAzWSa0hTYRjHe3fO2Y7LxWlqPZn6YWhQ6UobdLCUJIVTSBewYvYhD3q85Lyw 6cr8oAmazqlzQhklaWnGwKZLJEE0p2w4ZVPyVpgZXSzxgimoCJXbsW+/931+/P888JCYdBn3 JzOy8zh1NquSCcV4l23LGZb8Xac82dogpjvqzQQ9tT5P0MbPBpx2udpFtOXrJEGv6mcJeq1q ENH1rl4B3Tb4SUSPOeLogcUHBL05UonT9rYb5yTMynSpiHlfXSVgLKYKITMz2SNk3jQXMdWd JsSsWYKuiBLFZ1M4VYaWU5+IThKnG8o78NzFwLv6V2asGI2ADpEkUArYMMTpkNcOHoDRWbNQ h8SklGpB8GHTIXAPpNQaggVnMC8pYHrIRfDSSwTd4zW7j2IBNFu3kdsSUuGgW9J5onypEgS1 7WaPhVElGDzsrfXk+lBJYN+cF7kZp0Lgp7OZcLOEYuDX6JyA7wuCIVud59+LugDmpx8xdxBQ JhHUDVeI+CUCwfIO4/1YWGqcFvHsAwv2zl0OgIry/t3MGgQlpcd5rkfgXJLwfAYG7GOeLoza B8auRxgfL4HyMimvMPDF1rBbFQNT4604v/1TBIO9/YQBBTSiPSbky+VrstI4jUKuYbM0+dlp 8uScLAvauYLhP/b1t+iFLdKKKBLJvCXTPRVKKcFqNQVZVgQkJvOVTH7TKaWSFLbgHqfOuaXO V3EaKzpM4rKDkqjEMqWUSmPzuEyOy+XU/6cC0su/GJmo0Pj+I2OlqVq/qqqrF9vZhK6ZBHnL QEy+fDk92vFa+/t2UeHzmz8idKfovY+9J7ZU50e1vs8UTePJ3cFGzACx1X2XQw098X+bNh1H iy9FRN6vDGs0Li23bc9xK3r22oZy1ZiUpofxOxPOVGFfiPS0I/ZJ5vUGv0MD+6MK52W4Jp0N P4apNew/zinSagEDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprAIsWRmVeSWpSXmKPExsVy+t/xK7pJT7siDY49V7XYOGM9q8X1L89Z LSbdn8Bicf78BnaLTY+vsVp87LnHavG59wijxYzz+5gs1h65y25x8ZSrxeE37awWP850s1gc XxvuwOvx/kYru8flvl4mj02rOtk87lzbw+axeUm9R9+WVYwenzfJBbBHudlkpCampBYppOYl 56dk5qXbKoWGuOlaKCnkJeam2ipF6PqGBCkplCXmlAJ5RgZowME5wD1YSd8uwS1jQsdGloI3 shU9K9YzNzCekehi5OSQEDCRuHHyPCuELSZx4d56ti5GLg4hgSWMEq8+vWWHcJqYJK4/ms0I UsUmYCjR9bYLrEpEoIlR4knfNLAqZoE2Zon/HV/BqoQFEiSO/3jODmKzCKhKvDi3BGwHr4CH xMsLD5gg9slJnDw2GSzOKeApsX7OLWYQWwio5t6xTSwTGHkXMDKsYhRJLS3OTc8tNtQrTswt Ls1L10vOz93ECIyNbcd+bt7BeGlj8CFGAQ5GJR7eG3s6I4VYE8uKK3MPMUpwMCuJ8D5/3BUp xJuSWFmVWpQfX1Sak1p8iNEU6KiJzFKiyfnAuM0riTc0MTS3NDQytrAwNzJSEudVv9wUKSSQ nliSmp2aWpBaBNPHxMEp1cCYxmt42E8m9eWmnoqpvbu9vBZEr7nn08gZxzdfZdfBZ1sT+hNP RTUeUmd4csRp28yZHSvOr6lOD5/sE+HHvl9q+/KXAYlNG2qFPeUiBO6pa3nNmzTv5CnbMPeS 5pZV3uc9Ntstk1m58+fC9v9z7RfbZypcvu8w+XZta6++rk+GfJXa7S8P9fqUWIozEg21mIuK EwG+PnMdowIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170809103514eucas1p11fb5d1af243e882a5d51a25956d24a19 X-Msg-Generator: CA X-Sender-IP: 182.198.249.179 X-Local-Sender: =?utf-8?q?Marek_Szyprowski=1BSRPOL-Kernel_=28TP=29=1B?= =?utf-8?b?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?utf-8?q?Marek_Szyprowski=1BSRPOL-Kernel_=28TP=29=1BSam?= =?utf-8?q?sung_Electronics=1BSenior_Software_Engineer?= X-Sender-Code: =?utf-8?q?C10=1BEHQ=1BC10CD02CD027392?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170809103514eucas1p11fb5d1af243e882a5d51a25956d24a19 X-RootMTR: 20170809103514eucas1p11fb5d1af243e882a5d51a25956d24a19 References: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org 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 --- drivers/clk/samsung/clk-exynos-audss.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) -- 1.9.1 Reviewed-by: Chanwoo Choi 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 Wed Aug 9 10:35:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 109706 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp675958qge; Wed, 9 Aug 2017 03:35:32 -0700 (PDT) X-Received: by 10.99.54.201 with SMTP id d192mr7111294pga.310.1502274932340; Wed, 09 Aug 2017 03:35:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502274932; cv=none; d=google.com; s=arc-20160816; b=s5UrDq/oKjDSi2new/jPZkXfz1z1ppuDTaC5zLPRpsPKeldPDIv6uiWu8I080HaZfo 24sZuUo+UepPlfwNJKCudCl/ohbhMu4IW9gn+Cz6Q7ZltOrH7kKP6m1t5QmuQfr+W/OK hwNPyRae/4zWdt6vjsCfv+ScqP2k9x5XwqJ0i3kVj9tMnNgRKNwolMi+0jeS/cxpRsOZ ry0Ly0vwEPAnIu1TUOW3R/S0FD9U2mnS/VBui+9g3HajLPQMrJeD86Ypq+7YSeE5NdCD WDLWGPEHBU/8vrDLmIKyWvzo3lmNGtUCrY9cWOVR/uTmkjsP/yXpdv4IAZwWrz2troOr w91w== 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=TMkoGSx5B56THIk1fm5qr2R0Q7QinTgnsteD5mCjEtE=; b=Dvw2YpqGnEDWm/ByTkWpoZiwk26rY7SN8QQMQwT77pRUkix2ZPNKoQ1jHtCXLLgF59 hLd+iUVoi7f6lm92m+RZFxnhNV8trc7lfJldGqfL3hKOBh/hCBXxsoX7hmhamHnBCsea +FOBQgcCWoMTuiXQXo4FwYJW+HiG0M7v+i7bW60DZ68Ij9uEQOChGGdR+DI6BFBoJ/LO tDrxPZZqxArI8QywapqPgaeUZaodo6ckwClbbO35pQGGSJkmGsMxgaN06pOXXKPEb3ws DvUIjt+ueY0Xid9BwGQCiOargIul4z3d0WF+7YNc6QLC6b0FMk+IqMTjRhKyvBwEa63o 1VBQ== 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 s16si2577877plk.305.2017.08.09.03.35.32; Wed, 09 Aug 2017 03:35:32 -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 S1752415AbdHIKf3 (ORCPT + 12 others); Wed, 9 Aug 2017 06:35:29 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:20461 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751948AbdHIKfV (ORCPT ); Wed, 9 Aug 2017 06:35:21 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OUE00K2KYQSHF40@mailout3.w1.samsung.com>; Wed, 09 Aug 2017 11:35:16 +0100 (BST) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170809103516eucas1p2587b61481feb0085338f9ddb8a4de403~ZJxOsseJ21922219222eucas1p2h; Wed, 9 Aug 2017 10:35:16 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 8C.87.12907.365EA895; Wed, 9 Aug 2017 11:35:15 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170809103515eucas1p19fcbdd113e191cc02f9e5aaa469376d3~ZJxOES7_n2580025800eucas1p1S; Wed, 9 Aug 2017 10:35:15 +0000 (GMT) X-AuditID: cbfec7f1-f793a6d00000326b-9f-598ae5635869 Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 50.85.20118.365EA895; Wed, 9 Aug 2017 11:35:15 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OUE00IH6YQKHB00@eusync2.samsung.com>; Wed, 09 Aug 2017 11:35:15 +0100 (BST) From: Marek Szyprowski To: linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Marek Szyprowski , Stephen Boyd , Michael Turquette , Ulf Hansson , Sylwester Nawrocki , Chanwoo Choi , Inki Dae , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [PATCH v8 5/5] clk: samsung: exynos-audss: Add support for runtime PM Date: Wed, 09 Aug 2017 12:35:07 +0200 Message-id: <1502274907-11931-6-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAAzWSXUhTcRjG/Z9ztp2NVoc57d80L0ZepGQqEQe/SCo4BZEiEbMLXXpQa36w qbS6aFpO3dJ0frTMi5I+ZCjTJZKgJs5c6twcgtnKaX5kyJbMSSSE5jzz7vfwPu/z8sCLo4JN TIQXFJXS8iKpTMzmYf3jO7YzOWsaSezXgfNkr97IIr9sr7NI3WIDRtrtPRzStDLHIr1PXCzS VzcGSL19GCG7xxY4pGPyMml2V7PIv1YtRlq6b17gU5vzVRxqtr4OoUyGWjb1fW6QTb1//ZCq 7zMAymeKSONk8pJyaVlBOS0/m5LNy1f3WpESdcI9r6MLUwFzrAZwcUicg/rOjyjDoXDGZWRr AA8XEG8AtG9YMEb4AJx5N4AdbuxZpwODtwAuuLQII1QIdNprgN/FJuKgxqM5yBISlQA29hhZ foESlShsHW5E/K5gIg0uGXxsP2NEJLRtDe2bcJxPUPBRxzXmXAScGG9i+ZlLXIHGdifqz4GE gQPdHjvm90PiJDSNBEpcgjP/mhGGg+GGpY/DcDicbdIGKjwFsLIqmmE9gDYPn+FEaLY4Dm6h xFGo63+GMvF8WKMWMBYKrjltbIZT4aeBikD5dgDblldBAwh/CYIMQEiXKQrzaEV8jEJaqCgr yovJKS40gf03mNq1eD+Azc8Jo4DAgfgIf36wViJgScsVysJRAHFULORfXdVIBPxcqfI+LS/O kpfJaMUoCMMx8XF+cqZaIiDypKX0XZouoeWHUwTnilQgXn9im4YjnW7H865267iHWrF7fw+m LCmTQ1JvJXbcyADpSaTOKWqLfiUPdel/Rcn+OB5vsId0e0E76Fqr6Gf6ncnd2+aFaW1vgzjk gbC1PwOhsiK9p5U/XMs0lZWW2zKhreB2LF5s3uIeq15Pn3KDbBn64pQqJyyh5fo3MabIl8ZF oXKF9D+2F+tCAgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42I5/e/4Fd3kp12RBl1tnBYbZ6xntbj+5Tmr xaT7E1gszp/fwG6x6fE1VouPPfdYLT73HmG0mHF+H5PF2iN32S0unnK1OPymndXix5luFovj a8MdeD3e32hl97jc18vksWlVJ5vHnWt72Dw2L6n36NuyitHj8ya5APYoN5uM1MSU1CKF1Lzk /JTMvHRbpdAQN10LJYW8xNxUW6UIXd+QICWFssScUiDPyAANODgHuAcr6dsluGW0bTzDVNBm VfHx4hqWBsbDBl2MnBwSAiYS/8+cZYGwxSQu3FvPBmILCSxhlNhyIriLkQvIbmKSuPV/NVgR m4ChRNfbLjaQhIhAE6PEk75p7CAOs0Abs8T/jq+MIFXCAn4SBy+9YgWxWQRUJc592gtkc3Dw CnhINC/yhdgmJ3Hy2GSwEk4BT4n1c24xQ2z2kLh3bBPLBEbeBYwMqxhFUkuLc9Nzi430ihNz i0vz0vWS83M3MQLjYtuxn1t2MHa9Cz7EKMDBqMTDe2NPZ6QQa2JZcWXuIUYJDmYlEV4xYFQJ 8aYkVlalFuXHF5XmpBYfYjQFumkis5Rocj4wZvNK4g1NDM0tDY2MLSzMjYyUxHnVLzdFCgmk J5akZqemFqQWwfQxcXBKNTBK7c7jz9p73MX9dMOJ86Jb7z159KKEJapz32nmqsg3ngEzOxdw 6G585dJ0tVL3y5YsgfPn5Lo5E97/tnU7XVEwvW9Wy4GME/27KpVv8JbGvpe6z/z2R2ze+Yln hb/rJDfGi2h8mFv1uTbr1AnRz6Jdps4G7gzRd7aXbPq2V7b5XsC5lV4C13YosRRnJBpqMRcV JwIAfzSdA6ECAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170809103515eucas1p19fcbdd113e191cc02f9e5aaa469376d3 X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?utf-8?q?Marek_Szyprowski=1BSRPOL-Kernel_=28TP=29=1B?= =?utf-8?b?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?utf-8?q?Marek_Szyprowski=1BSRPOL-Kernel_=28TP=29=1BSam?= =?utf-8?q?sung_Electronics=1BSenior_Software_Engineer?= X-Sender-Code: =?utf-8?q?C10=1BEHQ=1BC10CD02CD027392?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170809103515eucas1p19fcbdd113e191cc02f9e5aaa469376d3 X-RootMTR: 20170809103515eucas1p19fcbdd113e191cc02f9e5aaa469376d3 References: <1502274907-11931-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org This patch adds support for runtime PM to Exynos Audio SubSystem driver to enable full support for audio power domain on Exynos5 SoCs. The main change is moving register saving and restoring code from system sleep PM ops to runtime PM ops and implementing system sleep PM ops with generic pm_runtime_force_suspend/resume helpers. Runtime PM of the Exynos AudSS device is managed from clock core depending on the preparation status of the provided clocks. Signed-off-by: Marek Szyprowski Reviewed-by: Ulf Hansson --- .../devicetree/bindings/clock/clk-exynos-audss.txt | 6 +++ drivers/clk/samsung/clk-exynos-audss.c | 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 = {