From patchwork Thu Feb 9 03:41:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 93666 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp65777qgi; Wed, 8 Feb 2017 19:48:51 -0800 (PST) X-Received: by 10.98.19.12 with SMTP id b12mr1242289pfj.150.1486612131773; Wed, 08 Feb 2017 19:48:51 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h91si8925459pld.68.2017.02.08.19.48.51; Wed, 08 Feb 2017 19:48:51 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; 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=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751572AbdBIDsl (ORCPT + 13 others); Wed, 8 Feb 2017 22:48:41 -0500 Received: from mail-pg0-f53.google.com ([74.125.83.53]:35703 "EHLO mail-pg0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751800AbdBIDsk (ORCPT ); Wed, 8 Feb 2017 22:48:40 -0500 Received: by mail-pg0-f53.google.com with SMTP id 194so53779044pgd.2 for ; Wed, 08 Feb 2017 19:48:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=5XHv8owGhsDspPgUycalTQS6TYEVut84ePLvI0gsKCQ=; b=ZkhLynFRJQMfTJ/kVyi7izWtBWn0xhXeF6b7FYl8LLYb5nHbvHuJOw0g5Indoak36r CdQOgMTFG/2/Km+CMDX2MW/mJydau8mK+PSVjwPsYpBWAtr4D0rIICUeU2WTYs3Q2OC5 iBc83xVp8hE1DoqXMxK6+qTTeWWeV+lTQjVfk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=5XHv8owGhsDspPgUycalTQS6TYEVut84ePLvI0gsKCQ=; b=cWWm8Fo9eMgutcBnppDdh+sCralD23Zxt1KZEWVlFYWNU6ibqulaUWdcb03skk7gpt 6WFSOR57EvAZprgXXGdhVt460Aj+H4rV0WD9uVdLuP/V2htt6oyYQkvVyUHXOF04Y9uX 2nt0croCU0glyR1Unz9TzqqpCrq2zf1Ic/fn/W3bHDEhRv66wqcGNaQ5kxiGS+PcA2iU r1DRrJL5Ko+2sQ7IaGYwPOQ6v3yLPYJkTvpA480g/I4WUf503VNEdixHIgdDM5k6B6SU pRSQb3AihUCQ21f75tgcw/dzyF2PEght9xI3FysaOgvXrGnSojE3CY87O/YBJ1BNLFdd kJsw== X-Gm-Message-State: AMke39mHS5bXzXq4Mfz6pdXdrvMJapR4SxMXQKqGqixBQj/z6pdN6fFVttevG3uEslBwfWHY X-Received: by 10.84.232.198 with SMTP id x6mr1368712plm.27.1486611729240; Wed, 08 Feb 2017 19:42:09 -0800 (PST) Received: from localhost ([122.172.165.189]) by smtp.gmail.com with ESMTPSA id 18sm23934039pgf.28.2017.02.08.19.42.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Feb 2017 19:42:08 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki , khilman@baylibre.com, ulf.hansson@linaro.org, Len Brown , Pavel Machek , Kevin Hilman Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , sboyd@codeaurora.org, nm@ti.com, robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V2 2/6] PM / QOS: Pass request type to dev_pm_qos_{add|remove}_notifier() Date: Thu, 9 Feb 2017 09:11:48 +0530 Message-Id: <65e83681e62f9e00a321f9b32b42211fd7f4071f.1486611268.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.1.410.g6faf27b In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org In order to use the same set of routines to register notifiers for different request types, update the existing dev_pm_qos_{add|remove}_notifier() routines with an additional parameter: request-type. For now, it only supports resume-latency request type. Signed-off-by: Viresh Kumar --- Documentation/power/pm_qos_interface.txt | 11 +++++++---- drivers/base/power/domain.c | 8 +++++--- drivers/base/power/qos.c | 14 ++++++++++++-- include/linux/pm_qos.h | 12 ++++++++---- 4 files changed, 32 insertions(+), 13 deletions(-) -- 2.7.1.410.g6faf27b -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index 129f7c0e1483..c7989d140428 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -166,12 +166,15 @@ under the device's power directory. The per-device PM QoS framework has 2 different and distinct notification trees: a per-device notification tree and a global notification tree. -int dev_pm_qos_add_notifier(device, notifier): -Adds a notification callback function for the device. +int dev_pm_qos_add_notifier(device, notifier, type): +Adds a notification callback function for the device for a particular request +type. + The callback is called when the aggregated value of the device constraints list -is changed (for resume latency device PM QoS only). +is changed. Currently it only supports the notifier to be registered for resume +latency device PM QoS. -int dev_pm_qos_remove_notifier(device, notifier): +int dev_pm_qos_remove_notifier(device, notifier, type): Removes the notification callback function for the device. int dev_pm_qos_add_global_notifier(notifier): diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 3a75fb1b4126..a73d79670a64 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1213,7 +1213,8 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, if (ret) genpd_free_dev_data(dev, gpd_data); else - dev_pm_qos_add_notifier(dev, &gpd_data->nb); + dev_pm_qos_add_notifier(dev, &gpd_data->nb, + DEV_PM_QOS_RESUME_LATENCY); return ret; } @@ -1248,7 +1249,8 @@ static int genpd_remove_device(struct generic_pm_domain *genpd, pdd = dev->power.subsys_data->domain_data; gpd_data = to_gpd_data(pdd); - dev_pm_qos_remove_notifier(dev, &gpd_data->nb); + dev_pm_qos_remove_notifier(dev, &gpd_data->nb, + DEV_PM_QOS_RESUME_LATENCY); genpd_lock(genpd); @@ -1273,7 +1275,7 @@ static int genpd_remove_device(struct generic_pm_domain *genpd, out: genpd_unlock(genpd); - dev_pm_qos_add_notifier(dev, &gpd_data->nb); + dev_pm_qos_add_notifier(dev, &gpd_data->nb, DEV_PM_QOS_RESUME_LATENCY); return ret; } diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 01f615b18055..9adc208cf1fc 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -481,6 +481,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_remove_request); * * @dev: target device for the constraint * @notifier: notifier block managed by caller. + * @type: request type. * * Will register the notifier into a notification chain that gets called * upon changes to the target value for the device. @@ -488,10 +489,14 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_remove_request); * If the device's constraints object doesn't exist when this routine is called, * it will be created (or error code will be returned if that fails). */ -int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) +int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier, + enum dev_pm_qos_req_type type) { int ret = 0; + if (WARN_ON(type != DEV_PM_QOS_RESUME_LATENCY)) + return -EINVAL; + mutex_lock(&dev_pm_qos_mtx); if (IS_ERR(dev->power.qos)) @@ -514,15 +519,20 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_notifier); * * @dev: target device for the constraint * @notifier: notifier block to be removed. + * @type: request type. * * Will remove the notifier from the notification chain that gets called * upon changes to the target value. */ int dev_pm_qos_remove_notifier(struct device *dev, - struct notifier_block *notifier) + struct notifier_block *notifier, + enum dev_pm_qos_req_type type) { int retval = 0; + if (WARN_ON(type != DEV_PM_QOS_RESUME_LATENCY)) + return -EINVAL; + mutex_lock(&dev_pm_qos_mtx); /* Silently return if the constraints object is not present. */ diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index d4d34791e463..08cfaeb6c178 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -143,9 +143,11 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value); int dev_pm_qos_remove_request(struct dev_pm_qos_request *req); int dev_pm_qos_add_notifier(struct device *dev, - struct notifier_block *notifier); + struct notifier_block *notifier, + enum dev_pm_qos_req_type type); int dev_pm_qos_remove_notifier(struct device *dev, - struct notifier_block *notifier); + struct notifier_block *notifier, + enum dev_pm_qos_req_type type); int dev_pm_qos_add_global_notifier(struct notifier_block *notifier); int dev_pm_qos_remove_global_notifier(struct notifier_block *notifier); void dev_pm_qos_constraints_init(struct device *dev); @@ -194,10 +196,12 @@ static inline int dev_pm_qos_update_request(struct dev_pm_qos_request *req, static inline int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) { return 0; } static inline int dev_pm_qos_add_notifier(struct device *dev, - struct notifier_block *notifier) + struct notifier_block *notifier, + enum dev_pm_qos_req_type type) { return 0; } static inline int dev_pm_qos_remove_notifier(struct device *dev, - struct notifier_block *notifier) + struct notifier_block *notifier, + enum dev_pm_qos_req_type type) { return 0; } static inline int dev_pm_qos_add_global_notifier( struct notifier_block *notifier) From patchwork Thu Feb 9 03:41:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 93667 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp65781qgi; Wed, 8 Feb 2017 19:48:52 -0800 (PST) X-Received: by 10.84.225.150 with SMTP id u22mr1361104plj.157.1486612132091; Wed, 08 Feb 2017 19:48:52 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h91si8925459pld.68.2017.02.08.19.48.51; Wed, 08 Feb 2017 19:48:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; 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=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751813AbdBIDso (ORCPT + 13 others); Wed, 8 Feb 2017 22:48:44 -0500 Received: from mail-pf0-f180.google.com ([209.85.192.180]:32850 "EHLO mail-pf0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751808AbdBIDsm (ORCPT ); Wed, 8 Feb 2017 22:48:42 -0500 Received: by mail-pf0-f180.google.com with SMTP id y143so46722754pfb.0 for ; Wed, 08 Feb 2017 19:48:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=kRlJeBgR5AiIepvZgRTxZ1oFmJ4OTF6okWaOIAvYZEE=; b=ctE6C2XyiXXjWbT/A4yvybE72fEXpuo9Wu568BeBid2fMlbOc2WYYLihhnCXX3H2sH hEhpHolOT9FWnIcJBOSU/ZxlbYSkVYgOqPWDpVeOUAXYJVW8cYI0dzmN98l5DIIH3mng f6mobY0ghRFUKWaPFEHHeizHHdmFssCkIRd8o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=kRlJeBgR5AiIepvZgRTxZ1oFmJ4OTF6okWaOIAvYZEE=; b=b1TH2x+BtZrOpVWes0dG1tK2WdV5Lh3a8wSqoZZsUOFQAnZLreaD4tq1sJLcfIwvPF Mw3cTbz2JsoqVLKTtaF5fQkc7MtK4Rc3TrXuPfWARqpgQcstp4bSLfdrICikghs/KIMk wAuOZx0PJgXtuanq3H9mK6PMK8adPa+iwFdMhNHbhq7Ax8LnWi/DP8pGPRBR/aCOsQmw Y5X1aP5jDm7lp7Qs8hqT0qpDvC2G1YY4PTbHH+SsWYs4w/Omu5VEBogKpGlXeHIEw/Qo rNhuHoV3QVj1ZvlKx3XCz1QRTKNerAb8FmH/GqNpFxIAoolthF6XL+QsvNmJm0RbVXV+ RW7Q== X-Gm-Message-State: AMke39nWZZGImTnwjWBitbRrrkhqyxhLVMFwCevdtK81EUEkFmjNOeZMfNfWQ1+5CfuQvnWq X-Received: by 10.84.194.37 with SMTP id g34mr1342922pld.105.1486611739584; Wed, 08 Feb 2017 19:42:19 -0800 (PST) Received: from localhost ([122.172.165.189]) by smtp.gmail.com with ESMTPSA id w123sm15874842pfb.44.2017.02.08.19.42.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Feb 2017 19:42:19 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki , khilman@baylibre.com, ulf.hansson@linaro.org, Kevin Hilman , Pavel Machek , Len Brown Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , sboyd@codeaurora.org, nm@ti.com, robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V2 5/6] PM / domain: Save/restore performance state at runtime suspend/resume Date: Thu, 9 Feb 2017 09:11:51 +0530 Message-Id: <21383233a44afe5e5144fadb82867a0a890db46f.1486611268.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.1.410.g6faf27b In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org With runtime PM, the devices get suspended while the system is up and running in order to save power. At such times, it is important to re-evaluate the required performance state of the domain, in order to choose a lower state if possible. This patch updates the genpd suspend/resume callbacks to do that. Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 19 +++++++++++++++++-- include/linux/pm_domain.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) -- 2.7.1.410.g6faf27b -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 1158a07f92de..ce9ab18be243 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -603,7 +603,8 @@ static int genpd_runtime_suspend(struct device *dev) { struct generic_pm_domain *genpd; bool (*suspend_ok)(struct device *__dev); - struct gpd_timing_data *td = &dev_gpd_data(dev)->td; + struct generic_pm_domain_data *pd_data = dev_gpd_data(dev); + struct gpd_timing_data *td = &pd_data->td; bool runtime_pm = pm_runtime_enabled(dev); ktime_t time_start; s64 elapsed_ns; @@ -660,7 +661,14 @@ static int genpd_runtime_suspend(struct device *dev) return 0; genpd_lock(genpd); + + /* Re-evaluate performance state of the domain */ + pd_data->cached_performance_state = pd_data->performance_state; + pd_data->performance_state = 0; + update_domain_performance_state(genpd, 0); + genpd_power_off(genpd, false); + genpd_unlock(genpd); return 0; @@ -677,7 +685,8 @@ static int genpd_runtime_suspend(struct device *dev) static int genpd_runtime_resume(struct device *dev) { struct generic_pm_domain *genpd; - struct gpd_timing_data *td = &dev_gpd_data(dev)->td; + struct generic_pm_domain_data *pd_data = dev_gpd_data(dev); + struct gpd_timing_data *td = &pd_data->td; bool runtime_pm = pm_runtime_enabled(dev); ktime_t time_start; s64 elapsed_ns; @@ -700,7 +709,13 @@ static int genpd_runtime_resume(struct device *dev) } genpd_lock(genpd); + ret = genpd_power_on(genpd, 0); + + /* Re-evaluate performance state of the domain */ + pd_data->performance_state = pd_data->cached_performance_state; + update_domain_performance_state(genpd, 0); + genpd_unlock(genpd); if (ret) diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index d994ad5ba1c0..69b453d44adb 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -122,6 +122,7 @@ struct generic_pm_domain_data { struct notifier_block nb; struct notifier_block perf_nb; unsigned int performance_state; + unsigned int cached_performance_state; }; #ifdef CONFIG_PM_GENERIC_DOMAINS From patchwork Thu Feb 9 03:41:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 93665 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp65729qgi; Wed, 8 Feb 2017 19:48:39 -0800 (PST) X-Received: by 10.98.75.156 with SMTP id d28mr1239985pfj.59.1486612119656; Wed, 08 Feb 2017 19:48:39 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j9si8889746pfc.290.2017.02.08.19.48.39; Wed, 08 Feb 2017 19:48:39 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; 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=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751671AbdBIDsa (ORCPT + 13 others); Wed, 8 Feb 2017 22:48:30 -0500 Received: from mail-pf0-f176.google.com ([209.85.192.176]:36481 "EHLO mail-pf0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751775AbdBIDs2 (ORCPT ); Wed, 8 Feb 2017 22:48:28 -0500 Received: by mail-pf0-f176.google.com with SMTP id 189so46661145pfu.3 for ; Wed, 08 Feb 2017 19:48:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=V44zviAbhFHqvcFuHD06RLLuQGwJRaEivhWQ62QbPv4=; b=XtN/Ysyy2etTBlJGhIpa7dfY3yVHioaokh3YmeNkb+7hTyUyE8gdfQdseKbJhtwePd ZsAQwIGCa6IllhXLvZ/xp5ce+h9rUXgqYGyYTxZQKabuZIrJpQbUDk25+P0UdyBj81Sc DCD2xJJcHPFlLsn4rLxZLTiz8/zSW/3Tba1P4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=V44zviAbhFHqvcFuHD06RLLuQGwJRaEivhWQ62QbPv4=; b=CbOH/0XxnqXr+mG4hQzsvmCFTb1C2r5L9bhbMVG4gAiZBbjnRJOoc8E31RAjlKt9iV BGM2/o2D7YQetJ4DaQzZXQAggxGutO9R0JOBVhB0XWk4dP2mp4rWr/69ioUmfFcVStF4 uUnJ0UZfVF7LbKFSQYe2rwooVGm08Ba6DRetb3MINvkGaoxU57oI6kSndl1/arDoNRrk h0oBF0u1vNsiSDSeayYAdAC/JlnWSTDCywie/NvW+EoJOFSwXnXyWdhMoqhBtq1UqmTk kaBLjK8jEldZ6I5DK8wGJb20XuWHI0jJTcwbWUzNxhNRaNJWdANhmHYhht8FCuCiEl8h 2KDg== X-Gm-Message-State: AMke39neY6velKUDtgk4eCXQB4zqCkAbzYJLkLdOFpoCQy7R0nZDS/6YWNKFR4236P1gQv4R X-Received: by 10.99.102.134 with SMTP id a128mr1273307pgc.215.1486611743044; Wed, 08 Feb 2017 19:42:23 -0800 (PST) Received: from localhost ([122.172.165.189]) by smtp.gmail.com with ESMTPSA id b67sm23746952pfj.81.2017.02.08.19.42.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Feb 2017 19:42:22 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki , khilman@baylibre.com, ulf.hansson@linaro.org, Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V2 6/6] PM / OPP: Add support to parse domain-performance-state Date: Thu, 9 Feb 2017 09:11:52 +0530 Message-Id: X-Mailer: git-send-email 2.7.1.410.g6faf27b In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org PLEASE DO NOT APPLY THIS PATCH It is only sent for completeness. It uses DT bindings which aren't finalized yet. Some platforms have the capability to configure the performance state of their Power Domains. The performance levels are represented by positive integer values, a lower value represents lower performance state. This patch introduces code in the OPP core to parse "domain-performance-state" property from the OPP nodes. Either none or all OPP nodes in an OPP table shall have the property set. NOT-Signed-off-by: Viresh Kumar --- drivers/base/power/opp/core.c | 75 ++++++++++++++++++++++++++++++++++++++++ drivers/base/power/opp/debugfs.c | 4 +++ drivers/base/power/opp/of.c | 44 +++++++++++++++++++++++ drivers/base/power/opp/opp.h | 12 +++++++ 4 files changed, 135 insertions(+) -- 2.7.1.410.g6faf27b -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 91ec3232d630..b5bb5f8775dc 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -542,6 +542,63 @@ _generic_set_opp_clk_only(struct device *dev, struct clk *clk, return ret; } +static int _update_pm_qos_request(struct device *dev, + struct dev_pm_qos_request *req, + unsigned int perf) +{ + int ret; + + if (likely(dev_pm_qos_request_active(req))) + ret = dev_pm_qos_update_request(req, perf); + else + ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_PERFORMANCE, + perf); + + if (ret < 0) + return ret; + + return 0; +} + +static int _generic_set_opp_pd(struct device *dev, struct clk *clk, + struct dev_pm_qos_request *req, + unsigned long old_freq, unsigned long freq, + unsigned int old_perf, unsigned int new_perf) +{ + int ret; + + /* Scaling up? Scale voltage before frequency */ + if (freq > old_freq) { + ret = _update_pm_qos_request(dev, req, new_perf); + if (ret) + return ret; + } + + /* Change frequency */ + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + if (ret) + goto restore_perf; + + /* Scaling down? Scale voltage after frequency */ + if (freq < old_freq) { + ret = _update_pm_qos_request(dev, req, new_perf); + if (ret) + goto restore_freq; + } + + return 0; + +restore_freq: + if (_generic_set_opp_clk_only(dev, clk, freq, old_freq)) + dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", + __func__, old_freq); +restore_perf: + if (old_perf) + _update_pm_qos_request(dev, req, old_perf); + + return ret; +} + static int _generic_set_opp(struct dev_pm_set_opp_data *data) { struct dev_pm_opp_supply *old_supply = data->old_opp.supplies; @@ -662,6 +719,21 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) regulators = opp_table->regulators; + /* Has power domains performance states */ + if (opp_table->has_pd_perf_states) { + unsigned int old_perf = 0, new_perf; + struct dev_pm_qos_request *req = &opp_table->qos_request; + + new_perf = opp->pd_perf_state; + if (!IS_ERR(old_opp)) + old_perf = old_opp->pd_perf_state; + + rcu_read_unlock(); + + return _generic_set_opp_pd(dev, clk, req, old_freq, freq, + old_perf, new_perf); + } + /* Only frequency scaling */ if (!regulators) { ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); @@ -807,6 +879,9 @@ static void _opp_table_kref_release(struct kref *kref) struct opp_table *opp_table = container_of(kref, struct opp_table, kref); struct opp_device *opp_dev; + if (dev_pm_qos_request_active(&opp_table->qos_request)) + dev_pm_qos_remove_request(&opp_table->qos_request); + /* Release clk */ if (!IS_ERR(opp_table->clk)) clk_put(opp_table->clk); diff --git a/drivers/base/power/opp/debugfs.c b/drivers/base/power/opp/debugfs.c index 95f433db4ac7..264958ab3de9 100644 --- a/drivers/base/power/opp/debugfs.c +++ b/drivers/base/power/opp/debugfs.c @@ -104,6 +104,10 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table) if (!debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate)) return -ENOMEM; + if (!debugfs_create_u32("power_domain_perf_state", S_IRUGO, d, + &opp->pd_perf_state)) + return -ENOMEM; + if (!opp_debug_create_supplies(opp, opp_table, d)) return -ENOMEM; diff --git a/drivers/base/power/opp/of.c b/drivers/base/power/opp/of.c index 083b79fa0c62..438a6b59baed 100644 --- a/drivers/base/power/opp/of.c +++ b/drivers/base/power/opp/of.c @@ -310,6 +310,45 @@ static int _opp_add_static_v2(struct opp_table *opp_table, struct device *dev, if (!of_property_read_u32(np, "clock-latency-ns", &val)) new_opp->clock_latency_ns = val; + /* + * Make sure that all information is present around domain power states + * and nothing is left out. + */ + if (!of_property_read_u32(np, "domain-performance-state", + &new_opp->pd_perf_state)) { + if (!opp_table->has_pd) { + ret = -EINVAL; + dev_err(dev, "%s: OPP node can't have performance state as device doesn't have power-domain\n", + __func__); + goto free_opp; + } + + if (!new_opp->pd_perf_state) { + ret = -EINVAL; + dev_err(dev, "%s: OPP node can't have performance state as 0\n", + __func__); + goto free_opp; + } + + if (opp_table->has_pd_perf_states == -1) { + opp_table->has_pd_perf_states = 1; + } else if (!opp_table->has_pd_perf_states) { + ret = -EINVAL; + dev_err(dev, "%s: Not all OPP nodes have performance state\n", + __func__); + goto free_opp; + } + } else { + if (opp_table->has_pd_perf_states == -1) { + opp_table->has_pd_perf_states = 0; + } else if (opp_table->has_pd_perf_states) { + ret = -EINVAL; + dev_err(dev, "%s: Not all OPP nodes have performance state\n", + __func__); + goto free_opp; + } + } + ret = opp_parse_supplies(new_opp, dev, opp_table); if (ret) goto free_opp; @@ -374,6 +413,11 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np) if (!opp_table) return -ENOMEM; + if (of_find_property(dev->of_node, "power-domains", NULL)) { + opp_table->has_pd = true; + opp_table->has_pd_perf_states = -1; + } + /* We have opp-table node now, iterate over it and add OPPs */ for_each_available_child_of_node(opp_np, np) { count++; diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h index 166eef990599..41a2c0a67031 100644 --- a/drivers/base/power/opp/opp.h +++ b/drivers/base/power/opp/opp.h @@ -20,6 +20,7 @@ #include #include #include +#include #include struct clk; @@ -58,6 +59,7 @@ extern struct list_head opp_tables; * @dynamic: not-created from static DT entries. * @turbo: true if turbo (boost) OPP * @suspend: true if suspend OPP + * @pd_perf_state: Performance state of power domain * @rate: Frequency in hertz * @supplies: Power supplies voltage/current values * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's @@ -76,6 +78,7 @@ struct dev_pm_opp { bool dynamic; bool turbo; bool suspend; + unsigned int pd_perf_state; unsigned long rate; struct dev_pm_opp_supply *supplies; @@ -137,6 +140,11 @@ enum opp_table_access { * @regulator_count: Number of power supply regulators * @set_opp: Platform specific set_opp callback * @set_opp_data: Data to be passed to set_opp callback + * @has_pd: True if the device node contains power-domain property + * @has_pd_perf_states: Can have value of 0, 1 or -1. -1 means uninitialized + * state, 0 means that OPP nodes don't have perf states and 1 means that OPP + * nodes have perf states. + * @qos_request: Qos request. * @dentry: debugfs dentry pointer of the real device directory (not links). * @dentry_name: Name of the real dentry. * @@ -174,6 +182,10 @@ struct opp_table { int (*set_opp)(struct dev_pm_set_opp_data *data); struct dev_pm_set_opp_data *set_opp_data; + bool has_pd; + int has_pd_perf_states; + struct dev_pm_qos_request qos_request; + #ifdef CONFIG_DEBUG_FS struct dentry *dentry; char dentry_name[NAME_MAX];