From patchwork Mon Mar 20 09:32:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 95520 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp923004qgd; Mon, 20 Mar 2017 05:46:18 -0700 (PDT) X-Received: by 10.98.95.197 with SMTP id t188mr15951650pfb.150.1490013978080; Mon, 20 Mar 2017 05:46:18 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a90si5430046plc.67.2017.03.20.05.46.17; Mon, 20 Mar 2017 05:46:18 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755019AbdCTMqP (ORCPT + 21 others); Mon, 20 Mar 2017 08:46:15 -0400 Received: from mail-pf0-f181.google.com ([209.85.192.181]:34247 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753359AbdCTJcd (ORCPT ); Mon, 20 Mar 2017 05:32:33 -0400 Received: by mail-pf0-f181.google.com with SMTP id p189so40262450pfp.1 for ; Mon, 20 Mar 2017 02:32:32 -0700 (PDT) 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=BdK2H2urZxRoBoixHY0yBnPF6Gu4wHCwJ7UMu2VzES0=; b=M65UiNjK6wf/NQxDWoSlRxxJ4uYNIn01bJtsWb7v0zGNV3zviUzhQ4ge9YO/uwhOHr qmVXULtd358cA9eiCMdEwgRarYDDEwZLYLRfP8p4Xd9Sr1QQ5Og2LgHIeclgliqv/atN rFPQNtmiXJlkAkgNav7kknrpuMV8KytJm60IE= 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=BdK2H2urZxRoBoixHY0yBnPF6Gu4wHCwJ7UMu2VzES0=; b=JJMazEsCLRPwp140exTGQj+OEt/DIVLl/An9eKdrLS/1GHatGRyfH5UwnYUstwz/rw NMB7GycwZBxNSgaoriS59wIH9tj7WZSOyAzb3yhusJAndxnN065GomugJIm7QRSEne95 LupysbYUJU6sIG0o6dLxFiU0JJG8nBDPEOkJwWD7xiZZ7p3BGRafkJmsryfBNBDyeZjN 66g+bIe4SGon+xNaZNl5RFVlihDZnxOMig8fefeBkgTYvhvMY3lkQeXNryMEEOc9SYmt NLzxMtbmgv5ppzuA6cPwlcetcES1t3AbcRZEFl5G+4gISdMdF7Wg0kU0yo6BcJNXpW/e GJ9Q== X-Gm-Message-State: AFeK/H0MV/RlJ2byKSd/42I/i8HDHCO2HcjvoE9sAWv3MouyghBnJBExFzZB8a/E0fM+S7yX X-Received: by 10.84.232.70 with SMTP id f6mr2143518pln.102.1490002351885; Mon, 20 Mar 2017 02:32:31 -0700 (PDT) Received: from localhost ([122.171.239.200]) by smtp.gmail.com with ESMTPSA id u29sm25818833pfa.123.2017.03.20.02.32.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Mar 2017 02:32:31 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar , devicetree@vger.kernel.org Subject: [PATCH V4 2/9] PM / Domains: Use OPP tables for power-domains Date: Mon, 20 Mar 2017 15:02:14 +0530 Message-Id: <5619ac7777689f282f8aafabbde22d71b46a979b.1490001099.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The OPP table bindings contains all the necessary fields to support power-domains now. Update the power-domain bindings to allow "operating-points-v2" to be present within the power-domain node. Also allow consumer devices, that don't use OPP tables, to specify the parent power-domain's performance level using the "domain-performance-state" property. Signed-off-by: Viresh Kumar --- .../devicetree/bindings/power/power_domain.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt index 723e1ad937da..5db112fa5d7c 100644 --- a/Documentation/devicetree/bindings/power/power_domain.txt +++ b/Documentation/devicetree/bindings/power/power_domain.txt @@ -38,6 +38,9 @@ phandle arguments (so called PM domain specifiers) of length specified by the domain's idle states. In the absence of this property, the domain would be considered as capable of being powered-on or powered-off. +- operating-points-v2 : This describes the performance states of a PM domain. + Refer to ../opp/opp.txt for more information. + Example: power: power-controller@12340000 { @@ -118,4 +121,43 @@ The node above defines a typical PM domain consumer device, which is located inside a PM domain with index 0 of a power controller represented by a node with the label "power". +Optional properties: +- domain-performance-state: A positive integer value representing the minimum + power-domain performance level required by the consumer device. The integer + value '0' represents the lowest performance level and the higher values + represent higher performance levels. The value of "domain-performance-state" + field should match the "domain-performance-state" field of one of the OPP + nodes in the parent power-domain's OPP table. + + + +Example: + + domain_opp_table: opp_table { + compatible = "operating-points-v2"; + + opp@1 { + domain-performance-state = <1>; + opp-microvolt = <975000 970000 985000>; + }; + opp@2 { + domain-performance-state = <2>; + opp-microvolt = <1075000 1000000 1085000>; + }; + }; + + parent: power-controller@12340000 { + compatible = "foo,power-controller"; + reg = <0x12340000 0x1000>; + #power-domain-cells = <0>; + operating-points-v2 = <&domain_opp_table>; + }; + + leaky-device@12350000 { + compatible = "foo,i-leak-current"; + reg = <0x12350000 0x1000>; + power-domains = <&power 0>; + domain-performance-state = <2>; + }; + [1]. Documentation/devicetree/bindings/power/domain-idle-state.txt From patchwork Mon Mar 20 09:32:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 95519 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp922955qgd; Mon, 20 Mar 2017 05:46:11 -0700 (PDT) X-Received: by 10.99.0.85 with SMTP id 82mr20800875pga.153.1490013971215; Mon, 20 Mar 2017 05:46:11 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f2si17421978pga.244.2017.03.20.05.46.10; Mon, 20 Mar 2017 05:46:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754940AbdCTMqG (ORCPT + 21 others); Mon, 20 Mar 2017 08:46:06 -0400 Received: from mail-pf0-f182.google.com ([209.85.192.182]:33359 "EHLO mail-pf0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753379AbdCTJcg (ORCPT ); Mon, 20 Mar 2017 05:32:36 -0400 Received: by mail-pf0-f182.google.com with SMTP id e129so24615481pfh.0 for ; Mon, 20 Mar 2017 02:32:35 -0700 (PDT) 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=yZeIzyVkogwxxH76YRdmxMpRzFU6BuMhgoxVYs5A0Y0=; b=E79yeK3G1P1XtPWDYObfZmh0KK7ftqo8/p4N75HFqE8VJ730oks29BVSSxCyXeaTRe u43TCvxCce8xkuwWxPt3d28+hBw9MKszWsNw/kX1Od7HEMkx4p5skB26TdSxgRv1dIZB rojRLbtkQVLb5U4OTzDKxxNPEEhsu2pky6+rA= 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=yZeIzyVkogwxxH76YRdmxMpRzFU6BuMhgoxVYs5A0Y0=; b=SsrZ50MOO75W4tOHQ6n+HRvvv9MjKvhjcbLa/QofnVbHXgUkuiefd4jmUr6ufWcCzY 1Z8OUiFLnDTnwbEGDkBRja1XAStG49WLQS75GVdwficlBY603rgimbhpQeUtLL4qW6bu /HoPJtTsYGrPzZN7Z31gYVwh+a8gEqA6obuHniaYr7KacpfrCpKTeO1MEo5P/vsNazgX xqRw0T8hq0mfd/2/y1Xd2NMgSPwfrWBaYJDbS41uTiFEgnKWFf2v9Ar0NepMP3QeGuGA 2uO4+vHGDHe23S3EiKXEQWG7j4lDOp1V7MTweAkoiquB5WllwpnkcCBPma2b4oj3Q93u s9tg== X-Gm-Message-State: AFeK/H1XYBOasbdjU3oOcS/P1UN04Ndjsb3WwpgRVTIJuFzgi/X+Old2dQ7JiSSoF8LYeCV2 X-Received: by 10.99.167.74 with SMTP id w10mr30451401pgo.2.1490002355357; Mon, 20 Mar 2017 02:32:35 -0700 (PDT) Received: from localhost ([122.171.239.200]) by smtp.gmail.com with ESMTPSA id i3sm31920267pfg.117.2017.03.20.02.32.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Mar 2017 02:32:34 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Kevin Hilman , Pavel Machek , Len Brown Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V4 3/9] PM / QOS: Keep common notifier list for genpd constraints Date: Mon, 20 Mar 2017 15:02:15 +0530 Message-Id: X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Only the resume_latency constraint uses the notifiers right now. In order to prepare for adding new constraint types with notifiers, move to a common notifier list. Update pm_qos_update_target() to pass a pointer to the constraint structure to the notifier callbacks. Also update the notifier callbacks as well to error out for unexpected constraints. Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 26 +++++++++++++++++++------- drivers/base/power/qos.c | 15 ++++----------- include/linux/pm_qos.h | 7 +++++++ kernel/power/qos.c | 2 +- 4 files changed, 31 insertions(+), 19 deletions(-) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 1a0549f1944a..6e4e22aa14a2 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -416,14 +416,10 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) return ret; } -static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, - unsigned long val, void *ptr) +static int __resume_latency_notifier(struct generic_pm_domain_data *gpd_data, + unsigned long val) { - struct generic_pm_domain_data *gpd_data; - struct device *dev; - - gpd_data = container_of(nb, struct generic_pm_domain_data, nb); - dev = gpd_data->base.dev; + struct device *dev = gpd_data->base.dev; for (;;) { struct generic_pm_domain *genpd; @@ -456,6 +452,22 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, + unsigned long val, void *ptr) +{ + struct generic_pm_domain_data *gpd_data; + struct device *dev; + + gpd_data = container_of(nb, struct generic_pm_domain_data, nb); + dev = gpd_data->base.dev; + + if (dev_pm_qos_notifier_is_resume_latency(dev, ptr)) + return __resume_latency_notifier(gpd_data, val); + + dev_err(dev, "%s: Unexpected notifier call\n", __func__); + return NOTIFY_BAD; +} + /** * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0. * @work: Work structure used for scheduling the execution of this function. diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index f850daeffba4..654d8a12c2e7 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -172,18 +172,12 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) { struct dev_pm_qos *qos; struct pm_qos_constraints *c; - struct blocking_notifier_head *n; qos = kzalloc(sizeof(*qos), GFP_KERNEL); if (!qos) return -ENOMEM; - n = kzalloc(sizeof(*n), GFP_KERNEL); - if (!n) { - kfree(qos); - return -ENOMEM; - } - BLOCKING_INIT_NOTIFIER_HEAD(n); + BLOCKING_INIT_NOTIFIER_HEAD(&qos->notifiers); c = &qos->resume_latency; plist_head_init(&c->list); @@ -191,7 +185,7 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) c->default_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; c->no_constraint_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; c->type = PM_QOS_MIN; - c->notifiers = n; + c->notifiers = &qos->notifiers; c = &qos->latency_tolerance; plist_head_init(&c->list); @@ -268,7 +262,6 @@ void dev_pm_qos_constraints_destroy(struct device *dev) dev->power.qos = ERR_PTR(-ENODEV); spin_unlock_irq(&dev->power.lock); - kfree(qos->resume_latency.notifiers); kfree(qos); out: @@ -487,7 +480,7 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) ret = dev_pm_qos_constraints_allocate(dev); if (!ret) - ret = blocking_notifier_chain_register(dev->power.qos->resume_latency.notifiers, + ret = blocking_notifier_chain_register(&dev->power.qos->notifiers, notifier); mutex_unlock(&dev_pm_qos_mtx); @@ -514,7 +507,7 @@ int dev_pm_qos_remove_notifier(struct device *dev, /* Silently return if the constraints object is not present. */ if (!IS_ERR_OR_NULL(dev->power.qos)) - retval = blocking_notifier_chain_unregister(dev->power.qos->resume_latency.notifiers, + retval = blocking_notifier_chain_unregister(&dev->power.qos->notifiers, notifier); mutex_unlock(&dev_pm_qos_mtx); diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 032b55909145..bcae6abb3f21 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -100,6 +100,7 @@ struct dev_pm_qos { struct dev_pm_qos_request *resume_latency_req; struct dev_pm_qos_request *latency_tolerance_req; struct dev_pm_qos_request *flags_req; + struct blocking_notifier_head notifiers; /* common for all constraints */ }; /* Action requested to pm_qos_update_target */ @@ -114,6 +115,12 @@ static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req) return req->dev != NULL; } +static inline bool dev_pm_qos_notifier_is_resume_latency(struct device *dev, + struct pm_qos_constraints *c) +{ + return &dev->power.qos->resume_latency == c; +} + int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, enum pm_qos_req_action action, int value); bool pm_qos_update_flags(struct pm_qos_flags *pqf, diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 97b0df71303e..073324e0c3c8 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -315,7 +315,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, if (c->notifiers) blocking_notifier_call_chain(c->notifiers, (unsigned long)curr_value, - NULL); + c); } else { ret = 0; } From patchwork Mon Mar 20 09:32:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 95518 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp922947qgd; Mon, 20 Mar 2017 05:46:10 -0700 (PDT) X-Received: by 10.84.232.135 with SMTP id i7mr19747594plk.134.1490013970401; Mon, 20 Mar 2017 05:46:10 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f2si17421978pga.244.2017.03.20.05.46.10; Mon, 20 Mar 2017 05:46:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754917AbdCTMqB (ORCPT + 21 others); Mon, 20 Mar 2017 08:46:01 -0400 Received: from mail-pg0-f48.google.com ([74.125.83.48]:32983 "EHLO mail-pg0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753067AbdCTJck (ORCPT ); Mon, 20 Mar 2017 05:32:40 -0400 Received: by mail-pg0-f48.google.com with SMTP id n190so74538518pga.0 for ; Mon, 20 Mar 2017 02:32:39 -0700 (PDT) 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=1IL/SyEhedE+qVnDsK2ciXJIfAPTGIba87tqbMk7boM=; b=Oxr8m0JL2LCEA++N+4laErCpRr1GHYfk2gRag2jPhRVHuzBmgWlDtFm1oMb/K1K00j gpQd7/kgdbzP4sQ7AjVUkdCuviU2DgnskAaRaxbvkfbJ+aacf9XhYj+cPBF4lfuGY4Jp TFSvViMrWdGzz+KLAVIP6GIxPU3a2hQr92afg= 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=1IL/SyEhedE+qVnDsK2ciXJIfAPTGIba87tqbMk7boM=; b=RdzCBxj/NhTBnZaLKSffjxVGGnvRnzo6b7locK75icZq/jIEySWe2Da6Ib3BVWqeiF R7gQze4OxvAhLrS9dBiJevz9/6fQIzMreaA2+ahF0ncg9kTkmlB3LD0OZEOOeyAOrB6C lXPoh7N3tmg1QBUQsuAY02w5DNTjTr7Lm0RwVmBHpX8GKqCgqWCV3tYx2BCln366MJje Hge7pVlhMZSCNsJoS7dOGiMo4Eti426t+eM6pUpSYFPiT2KEpBn9FDHeXiOFT4686gjC Yf61iEnDMJe51+gMwGFT+FEYoe3CAwvr845FRBvbbnr5eJQyWj4W07oaHbHDzeH6kyS7 BAkw== X-Gm-Message-State: AFeK/H1NagpRqfYiNCgcgWMSuJijXCFWUgsA1SOZi6+F08R1jW5Sm8loOaJE0AWuqde9wAou X-Received: by 10.84.174.131 with SMTP id r3mr14248120plb.136.1490002358822; Mon, 20 Mar 2017 02:32:38 -0700 (PDT) Received: from localhost ([122.171.239.200]) by smtp.gmail.com with ESMTPSA id k76sm31905289pfg.42.2017.03.20.02.32.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Mar 2017 02:32:38 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Len Brown , Pavel Machek Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V4 4/9] PM / QOS: Add DEV_PM_QOS_PERFORMANCE request Date: Mon, 20 Mar 2017 15:02:16 +0530 Message-Id: <1dbed263e2fcc42906daaf584d3257c01aa11e13.1490001099.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some platforms have the capability to configure the performance state of their Power Domains. The performance levels are identified by positive integer values, a lower value represents lower performance state. The power domain driver should be able to retrieve all information required to configure the performance state of the power domain, with the help of the performance constraint's target value. This patch adds a new QOS request type: DEV_PM_QOS_PERFORMANCE to support runtime performance constraints for the devices. Also allow notifiers to be registered against it, which will be used by frameworks like genpd. Signed-off-by: Viresh Kumar --- Documentation/power/pm_qos_interface.txt | 2 +- drivers/base/power/qos.c | 21 +++++++++++++++++++++ include/linux/pm_qos.h | 10 ++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) -- 2.12.0.432.g71c3a4f4ba37 Acked-by: Ulf Hansson diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index 21d2d48f87a2..4b7decdebf98 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -168,7 +168,7 @@ The per-device PM QoS framework has a per-device notification tree. int dev_pm_qos_add_notifier(device, notifier): Adds a notification callback function for the device. The callback is called when the aggregated value of the device constraints list -is changed (for resume latency device PM QoS only). +is changed (for resume latency and performance device PM QoS only). int dev_pm_qos_remove_notifier(device, notifier): Removes the notification callback function for the device. diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 654d8a12c2e7..084d26960dae 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -150,6 +150,10 @@ static int apply_constraint(struct dev_pm_qos_request *req, req->dev->power.set_latency_tolerance(req->dev, value); } break; + case DEV_PM_QOS_PERFORMANCE: + ret = pm_qos_update_target(&qos->performance, &req->data.pnode, + action, value); + break; case DEV_PM_QOS_FLAGS: ret = pm_qos_update_flags(&qos->flags, &req->data.flr, action, value); @@ -194,6 +198,14 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; c->type = PM_QOS_MIN; + c = &qos->performance; + plist_head_init(&c->list); + c->target_value = PM_QOS_PERFORMANCE_DEFAULT_VALUE; + c->default_value = PM_QOS_PERFORMANCE_DEFAULT_VALUE; + c->no_constraint_value = PM_QOS_PERFORMANCE_DEFAULT_VALUE; + c->type = PM_QOS_MAX; + c->notifiers = &qos->notifiers; + INIT_LIST_HEAD(&qos->flags.list); spin_lock_irq(&dev->power.lock); @@ -252,6 +264,11 @@ void dev_pm_qos_constraints_destroy(struct device *dev) apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); memset(req, 0, sizeof(*req)); } + c = &qos->performance; + plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) { + apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); + memset(req, 0, sizeof(*req)); + } f = &qos->flags; list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) { apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); @@ -362,6 +379,7 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, switch(req->type) { case DEV_PM_QOS_RESUME_LATENCY: case DEV_PM_QOS_LATENCY_TOLERANCE: + case DEV_PM_QOS_PERFORMANCE: curr_value = req->data.pnode.prio; break; case DEV_PM_QOS_FLAGS: @@ -571,6 +589,9 @@ static void __dev_pm_qos_drop_user_request(struct device *dev, req = dev->power.qos->flags_req; dev->power.qos->flags_req = NULL; break; + case DEV_PM_QOS_PERFORMANCE: + dev_err(dev, "Invalid user request (performance)\n"); + return; } __dev_pm_qos_remove_request(req); kfree(req); diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index bcae6abb3f21..0f5135d55406 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -36,6 +36,7 @@ enum pm_qos_flags_status { #define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) +#define PM_QOS_PERFORMANCE_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_ANY ((s32)(~(__u32)0 >> 1)) #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) @@ -55,6 +56,7 @@ struct pm_qos_flags_request { enum dev_pm_qos_req_type { DEV_PM_QOS_RESUME_LATENCY = 1, DEV_PM_QOS_LATENCY_TOLERANCE, + DEV_PM_QOS_PERFORMANCE, DEV_PM_QOS_FLAGS, }; @@ -96,9 +98,11 @@ struct pm_qos_flags { struct dev_pm_qos { struct pm_qos_constraints resume_latency; struct pm_qos_constraints latency_tolerance; + struct pm_qos_constraints performance; struct pm_qos_flags flags; struct dev_pm_qos_request *resume_latency_req; struct dev_pm_qos_request *latency_tolerance_req; + struct dev_pm_qos_request *performance_req; struct dev_pm_qos_request *flags_req; struct blocking_notifier_head notifiers; /* common for all constraints */ }; @@ -121,6 +125,12 @@ static inline bool dev_pm_qos_notifier_is_resume_latency(struct device *dev, return &dev->power.qos->resume_latency == c; } +static inline bool dev_pm_qos_notifier_is_performance(struct device *dev, + struct pm_qos_constraints *c) +{ + return &dev->power.qos->performance == c; +} + int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, enum pm_qos_req_action action, int value); bool pm_qos_update_flags(struct pm_qos_flags *pqf, From patchwork Mon Mar 20 09:32:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 95486 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp852617qgd; Mon, 20 Mar 2017 02:33:41 -0700 (PDT) X-Received: by 10.84.174.131 with SMTP id r3mr14253657plb.136.1490002421233; Mon, 20 Mar 2017 02:33:41 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g21si16849481pgh.125.2017.03.20.02.33.40; Mon, 20 Mar 2017 02:33:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753810AbdCTJdf (ORCPT + 23 others); Mon, 20 Mar 2017 05:33:35 -0400 Received: from mail-pg0-f43.google.com ([74.125.83.43]:34591 "EHLO mail-pg0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753401AbdCTJcn (ORCPT ); Mon, 20 Mar 2017 05:32:43 -0400 Received: by mail-pg0-f43.google.com with SMTP id 21so41260189pgg.1 for ; Mon, 20 Mar 2017 02:32:43 -0700 (PDT) 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=Z7OzrvkXaJoB1Gt8tMLen/o8PTnfkbWOi6mPcrs5mmw=; b=X2xvxQndgBXsgYJJlYfxwbdoVOjLBbe+UGNTbESq6gZq1XHyjpF7nkdW/WDQy9YVp1 e2dSr7L9KL5S/xaksSrC5/32n+6sGDjxmlojanK5fj+BDTvMt3TG5TfGgFIy73RIO5tP yhkuA2Fw0npY8SqsTu+evDwK3dC8FpmHUQngk= 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=Z7OzrvkXaJoB1Gt8tMLen/o8PTnfkbWOi6mPcrs5mmw=; b=lHCYwANqgsJxvwy4Sgfgs0Z2swzlP7h2O2B+GB/qAyj1U6mNFXEhCVyN+HDoDQJv8G OkLt5Wm++0ZKv9mxqoI4IBobNJ3HAupSFbWoSLQIItzWRHub46SXs5K2gkHtWTj3vlH6 ibQ6gUz4R+YEPLJ03zFXz13geudLtRr21cfIbj8D/L6tAPwzaBXOYdgcnj1St+NjMb8K izrZbH0fqIREMTqK5j9DXIelJQkMM96a097IKXqfUgw8kLsoDA6iEftNIqSHQHeo7X7I GvuqDgLCeFXkhrKCcqzGBeckbN9+hZf02rL96/CKheG3J26n5I7il3k6aICq6ESF6cgh pyOg== X-Gm-Message-State: AFeK/H04xzb8FwMbuPiWXWtS80SVQzgXB1BfvDAqYGz6HPrjEbTI7bjeuhiZCikAL8wvWSFZ X-Received: by 10.84.236.79 with SMTP id h15mr22735625pln.110.1490002362339; Mon, 20 Mar 2017 02:32:42 -0700 (PDT) Received: from localhost ([122.171.239.200]) by smtp.gmail.com with ESMTPSA id b11sm31926770pfj.27.2017.03.20.02.32.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Mar 2017 02:32:41 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , 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 V4 5/9] PM / OPP: Add support to parse OPP table for power-domains Date: Mon, 20 Mar 2017 15:02:17 +0530 Message-Id: <6831fa7061f4eee66b66b2d0eb8763ad6cf86938.1490001099.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Power domains can also represent their active states with the help of OPP tables now and this patch enhances the OPP core to support that. The OPP nodes are allowed to have the "domain-performance-state" property, only if the device node contains a "power-domains" or "#power-domain-cells" property. The OPP nodes aren't allowed to contain this property partially, i.e. Either all OPP nodes in the OPP table have the "domain-performance-state" property or none of them have it. The "opp-hz" property isn't mandatory anymore. It is still required for non-power-domain devices though. The power-domain devices need the unique "domain-performance-state" property per OPP node. The OPP core errors out if these rules aren't obeyed. The per-OPP debugfs directories are also named based on domain-performance-state for power-domain devices. Signed-off-by: Viresh Kumar --- drivers/base/power/opp/core.c | 163 +++++++++++++++++++++++++++++++++++---- drivers/base/power/opp/debugfs.c | 9 ++- drivers/base/power/opp/of.c | 80 ++++++++++++++++--- drivers/base/power/opp/opp.h | 14 ++++ 4 files changed, 240 insertions(+), 26 deletions(-) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index dae61720b314..c435acb21a47 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -543,6 +543,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_domain(struct device *dev, struct clk *clk, + struct dev_pm_qos_request *req, + unsigned long old_freq, unsigned long freq, + int old_dps, int new_dps) +{ + int ret; + + /* Scaling up? Scale voltage before frequency */ + if (freq > old_freq) { + ret = _update_pm_qos_request(dev, req, new_dps); + if (ret) + return ret; + } + + /* Change frequency */ + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + if (ret) + goto restore_dps; + + /* Scaling down? Scale voltage after frequency */ + if (freq < old_freq) { + ret = _update_pm_qos_request(dev, req, new_dps); + 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_dps: + if (old_dps != -1) + _update_pm_qos_request(dev, req, old_dps); + + 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; @@ -663,6 +720,19 @@ 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_domain_perf_states) { + int old_dps = -1, new_dps; + struct dev_pm_qos_request *req = &opp_table->qos_request; + + new_dps = opp->domain_perf_state; + if (!IS_ERR(old_opp)) + old_dps = old_opp->domain_perf_state; + + return _generic_set_opp_domain(dev, clk, req, old_freq, freq, + old_dps, new_dps); + } + /* Only frequency scaling */ if (!regulators) { ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); @@ -808,6 +878,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); @@ -950,18 +1023,8 @@ static bool _opp_supported_by_regulators(struct dev_pm_opp *opp, return true; } -/* - * Returns: - * 0: On success. And appropriate error message for duplicate OPPs. - * -EBUSY: For OPP with same freq/volt and is available. The callers of - * _opp_add() must return 0 if they receive -EBUSY from it. This is to make - * sure we don't print error messages unnecessarily if different parts of - * kernel try to initialize the OPP table. - * -EEXIST: For OPP with same freq but different volt or is unavailable. This - * should be considered an error by the callers of _opp_add(). - */ -int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, - struct opp_table *opp_table) +struct list_head *_opp_add_freq(struct device *dev, struct dev_pm_opp *new_opp, + struct opp_table *opp_table) { struct dev_pm_opp *opp; struct list_head *head; @@ -975,7 +1038,6 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, * loop, don't replace it with head otherwise it will become an infinite * loop. */ - mutex_lock(&opp_table->lock); head = &opp_table->opp_list; list_for_each_entry(opp, &opp_table->opp_list, node) { @@ -997,8 +1059,81 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, ret = opp->available && new_opp->supplies[0].u_volt == opp->supplies[0].u_volt ? -EBUSY : -EEXIST; + return ERR_PTR(ret); + } + + return head; +} + +struct list_head *_opp_add_domain(struct device *dev, struct dev_pm_opp *new_opp, + struct opp_table *opp_table) +{ + struct dev_pm_opp *opp; + struct list_head *head; + int ret; + + /* + * Insert new OPP in order of increasing performance level and discard + * if already present. + * + * Need to use &opp_table->opp_list in the condition part of the 'for' + * loop, don't replace it with head otherwise it will become an infinite + * loop. + */ + head = &opp_table->opp_list; + + list_for_each_entry(opp, &opp_table->opp_list, node) { + if (new_opp->domain_perf_state > opp->domain_perf_state) { + head = &opp->node; + continue; + } + + if (new_opp->domain_perf_state < opp->domain_perf_state) + break; + + /* Duplicate OPPs */ + dev_warn(dev, "%s: duplicate OPPs detected. Existing: DPS: %u, volt: %lu, enabled: %d. New-DPS: %u, volt: %lu, enabled: %d\n", + __func__, opp->domain_perf_state, + opp->supplies[0].u_volt, opp->available, + new_opp->domain_perf_state, + new_opp->supplies[0].u_volt, new_opp->available); + + /* Should we compare voltages for all regulators here ? */ + ret = opp->available && + new_opp->supplies[0].u_volt == opp->supplies[0].u_volt ? -EBUSY : -EEXIST; + + return ERR_PTR(ret); + } + + return head; +} + +/* + * Returns: + * 0: On success. And appropriate error message for duplicate OPPs. + * -EBUSY: For OPP with same freq/dps and volt and is available. The callers of + * _opp_add() must return 0 if they receive -EBUSY from it. This is to make + * sure we don't print error messages unnecessarily if different parts of + * kernel try to initialize the OPP table. + * -EEXIST: For OPP with same freq/dps but different volt or is unavailable. + * This should be considered an error by the callers of _opp_add(). + */ +int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, + struct opp_table *opp_table) +{ + struct list_head *head; + int ret; + + mutex_lock(&opp_table->lock); + + if (new_opp->rate) + head = _opp_add_freq(dev, new_opp, opp_table); + else + head = _opp_add_domain(dev, new_opp, opp_table); + + if (IS_ERR(head)) { mutex_unlock(&opp_table->lock); - return ret; + return PTR_ERR(head); } list_add(&new_opp->node, head); diff --git a/drivers/base/power/opp/debugfs.c b/drivers/base/power/opp/debugfs.c index 95f433db4ac7..779f911fdf38 100644 --- a/drivers/base/power/opp/debugfs.c +++ b/drivers/base/power/opp/debugfs.c @@ -81,8 +81,9 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table) struct dentry *d; char name[25]; /* 20 chars for 64 bit value + 5 (opp:\0) */ - /* Rate is unique to each OPP, use it to give opp-name */ - snprintf(name, sizeof(name), "opp:%lu", opp->rate); + /* Rate and perf-state are unique to each OPP, use them for opp-name */ + snprintf(name, sizeof(name), "opp:%lu", + opp->rate ? opp->rate : opp->domain_perf_state); /* Create per-opp directory */ d = debugfs_create_dir(name, pdentry); @@ -104,6 +105,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->domain_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 779428676f63..15c62010e816 100644 --- a/drivers/base/power/opp/of.c +++ b/drivers/base/power/opp/of.c @@ -284,24 +284,70 @@ static int _opp_add_static_v2(struct opp_table *opp_table, struct device *dev, if (!new_opp) return -ENOMEM; - ret = of_property_read_u64(np, "opp-hz", &rate); - if (ret < 0) { - dev_err(dev, "%s: opp-hz not found\n", __func__); + /* Check if the OPP supports hardware's hierarchy of versions or not */ + if (!_opp_is_supported(dev, opp_table, np)) { + dev_dbg(dev, "OPP %s not supported by hardware\n", + np->full_name); + ret = 0; goto free_opp; } - /* Check if the OPP supports hardware's hierarchy of versions or not */ - if (!_opp_is_supported(dev, opp_table, np)) { - dev_dbg(dev, "OPP not supported by hardware: %llu\n", rate); + ret = of_property_read_u64(np, "opp-hz", &rate); + if (!ret) { + /* + * Rate is defined as an unsigned long in clk API, and so + * casting explicitly to its type. Must be fixed once rate is 64 + * bit guaranteed in clk API. + */ + new_opp->rate = (unsigned long)rate; + } else if (unlikely(!opp_table->is_domain)) { + /* All devices except power-domains must have opp-hz */ + dev_err(dev, "%s: opp-hz not found\n", __func__); goto free_opp; } /* - * Rate is defined as an unsigned long in clk API, and so casting - * explicitly to its type. Must be fixed once rate is 64 bit - * guaranteed in clk API. + * Nodes can contain domain-performance-state property only if they are + * power-domains or they have parent power domain. And either all nodes + * must have domain-performance-state property or none. */ - new_opp->rate = (unsigned long)rate; + if (!of_property_read_u32(np, "domain-performance-state", + &new_opp->domain_perf_state)) { + if (unlikely(!(opp_table->has_domain || + opp_table->is_domain))) { + ret = -EINVAL; + dev_err(dev, "%s: OPP node can't have domain-performance-state\n", + __func__); + goto free_opp; + } + + if (opp_table->has_domain_perf_states == -1) { + opp_table->has_domain_perf_states = 1; + } else if (unlikely(!opp_table->has_domain_perf_states)) { + ret = -EINVAL; + dev_err(dev, "%s: Not all OPP nodes have domain-performance-state\n", + __func__); + goto free_opp; + } + } else { + /* Power-domains must have this property */ + if (unlikely(opp_table->is_domain)) { + ret = -EINVAL; + dev_err(dev, "%s: OPP node doesn't have domain-performance-state property\n", + __func__); + goto free_opp; + } + + if (opp_table->has_domain_perf_states == -1) { + opp_table->has_domain_perf_states = 0; + } else if (unlikely(opp_table->has_domain_perf_states)) { + ret = -EINVAL; + dev_err(dev, "%s: Not all OPP nodes have domain-performance-state\n", + __func__); + goto free_opp; + } + } + new_opp->turbo = of_property_read_bool(np, "turbo-mode"); new_opp->np = np; @@ -375,6 +421,20 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np) if (!opp_table) return -ENOMEM; + /* + * Only power domains or devices with parent power-domains can have + * domain-performance states. + */ + if (of_find_property(dev->of_node, "power-domains", NULL)) { + opp_table->has_domain = true; + opp_table->has_domain_perf_states = -1; + } + + if (of_find_property(dev->of_node, "#power-domain-cells", NULL)) { + opp_table->is_domain = true; + opp_table->has_domain_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..1d1e9ea8cda5 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 + * @domain_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 domain_perf_state; unsigned long rate; struct dev_pm_opp_supply *supplies; @@ -137,6 +140,12 @@ 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 + * @is_domain: True if the device node contains "#power-domain-cells" property + * @has_domain: True if the device node contains "power-domain" property + * @has_domain_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 +183,11 @@ struct opp_table { int (*set_opp)(struct dev_pm_set_opp_data *data); struct dev_pm_set_opp_data *set_opp_data; + bool is_domain; + bool has_domain; + int has_domain_perf_states; + struct dev_pm_qos_request qos_request; + #ifdef CONFIG_DEBUG_FS struct dentry *dentry; char dentry_name[NAME_MAX]; From patchwork Mon Mar 20 09:32:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 95485 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp852614qgd; Mon, 20 Mar 2017 02:33:40 -0700 (PDT) X-Received: by 10.98.137.75 with SMTP id v72mr32143364pfd.190.1490002420683; Mon, 20 Mar 2017 02:33:40 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g21si16849481pgh.125.2017.03.20.02.33.39; Mon, 20 Mar 2017 02:33:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753794AbdCTJde (ORCPT + 23 others); Mon, 20 Mar 2017 05:33:34 -0400 Received: from mail-pg0-f41.google.com ([74.125.83.41]:34604 "EHLO mail-pg0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752945AbdCTJcq (ORCPT ); Mon, 20 Mar 2017 05:32:46 -0400 Received: by mail-pg0-f41.google.com with SMTP id 21so41260787pgg.1 for ; Mon, 20 Mar 2017 02:32:45 -0700 (PDT) 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=b1/unE8WWBT9vN1SczLDRGVUSz20jLQgbXzKmlFzS0w=; b=dOkEG3cE4fijKhDpeupsaF6BNucO/YJVcSQknalR1nJFdnprWonoySbFouEJ0UTIuA Jb9cMXWEz4GLM11/UgUpsi+FKaqjD02Dly8ODfogld9b8X38tJA/9pnknS7Y96atYi50 mELGvbXmRsDz1Mv3n59u2cfzJoWeYmmvIpvHg= 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=b1/unE8WWBT9vN1SczLDRGVUSz20jLQgbXzKmlFzS0w=; b=L6zuTvp6vPjTYYsRcyUoLLdcuoB8kI6PyaBNyx65BHBwpGVkYC7VAA8qAfppyWrJb+ TFSqJNFt2bClMKCetKYeB/NIE18ZOFtCxu7qQYl2Li9YPg0EjAzI/Dz1WIK4vnWg+JQ0 iXuAkA03U/KlnlVeNeDvDmjwJJCTDcYH04mpM+G8VN9/BosrfjK7BPvl2/cjwx8tvNFZ yObZSSds4uVDG/ZqDW7oh9k3nAuMCO/baOlVGNEJrQHfj3EV9WJ2KUohWT1V4ujijnuS ecm+Sttts5SxzjHuURliAdi6JrJfb4wKcxruWboklhI0hiD5pl3j5OUzLG2y6h4QKAvq YA9A== X-Gm-Message-State: AFeK/H1MkxdmeUT1tMYmBbZYDziryECiK13ETDFOKnSRmsSVgxtHI56dNzIBGHuRQ9xqdzRL X-Received: by 10.98.36.151 with SMTP id k23mr29401145pfk.53.1490002365385; Mon, 20 Mar 2017 02:32:45 -0700 (PDT) Received: from localhost ([122.171.239.200]) by smtp.gmail.com with ESMTPSA id p6sm32162192pgn.40.2017.03.20.02.32.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Mar 2017 02:32:44 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , 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 V4 6/9] PM / OPP: Add dev_pm_opp_find_dps() helper Date: Mon, 20 Mar 2017 15:02:18 +0530 Message-Id: <746e4e6f040cefb280569754cebd49db57d58d59.1490001099.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds dev_pm_opp_find_dps() helper to get the OPP node for a domain-performance-state. This helper is only supported for tables representing power domains. Signed-off-by: Viresh Kumar --- drivers/base/power/opp/core.c | 66 +++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 8 ++++++ 2 files changed, 74 insertions(+) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index c435acb21a47..212f11d65790 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -503,6 +503,72 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); +/** + * dev_pm_opp_find_dps() - search for an exact domain-performance-state + * @dev: device for which we do this operation + * @dps: domain-performance-state + * @available: true/false - match for available opp + * + * Return: Searches for exact match in the opp table and returns pointer to the + * matching opp if found, else returns ERR_PTR in case of error and should + * be handled using IS_ERR. Error return values can be: + * EINVAL: for bad pointer + * ERANGE: no match found for search + * ENODEV: if device not found in list of registered devices + * + * Note: available is a modifier for the search. if available=true, then the + * match is for exact matching domain-performance-state and is available in the + * stored OPP table. if false, the match is for exact domain-performance-state + * which is not available. + * + * This provides a mechanism to enable an opp which is not available currently + * or the opposite as well. + * + * The callers are required to call dev_pm_opp_put() for the returned OPP after + * use. + */ +struct dev_pm_opp *dev_pm_opp_find_dps(struct device *dev, unsigned int dps, + bool available) +{ + struct opp_table *opp_table; + struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-EINVAL); + + opp_table = _find_opp_table(dev); + if (IS_ERR(opp_table)) { + int r = PTR_ERR(opp_table); + + dev_err(dev, "%s: OPP table not found (%d)\n", __func__, r); + return ERR_PTR(r); + } + + /* This API is only supported for tables representing power domains */ + if (WARN_ON(!opp_table->is_domain)) + goto put_table; + + opp = ERR_PTR(-ERANGE); + + mutex_lock(&opp_table->lock); + + list_for_each_entry(temp_opp, &opp_table->opp_list, node) { + if (temp_opp->available == available && + temp_opp->domain_perf_state == dps) { + opp = temp_opp; + + /* Increment the reference count of OPP */ + dev_pm_opp_get(opp); + break; + } + } + + mutex_unlock(&opp_table->lock); + +put_table: + dev_pm_opp_put_opp_table(opp_table); + + return opp; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_find_dps); + static int _set_opp_voltage(struct device *dev, struct regulator *reg, struct dev_pm_opp_supply *supply) { diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index a6685b3dde26..11d3ff4de4b0 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -102,6 +102,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq); +struct dev_pm_opp *dev_pm_opp_find_dps(struct device *dev, unsigned int freq, + bool available); void dev_pm_opp_put(struct dev_pm_opp *opp); int dev_pm_opp_add(struct device *dev, unsigned long freq, @@ -194,6 +196,12 @@ static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, return ERR_PTR(-ENOTSUPP); } +static inline struct dev_pm_opp *dev_pm_opp_find_dps(struct device *dev, + unsigned int freq, bool available) +{ + return ERR_PTR(-ENOTSUPP); +} + static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {} static inline int dev_pm_opp_add(struct device *dev, unsigned long freq, From patchwork Mon Mar 20 09:32:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 95484 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp852564qgd; Mon, 20 Mar 2017 02:33:32 -0700 (PDT) X-Received: by 10.84.234.8 with SMTP id m8mr38447941plk.25.1490002412887; Mon, 20 Mar 2017 02:33:32 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z190si11979390pfb.188.2017.03.20.02.33.32; Mon, 20 Mar 2017 02:33:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753772AbdCTJdc (ORCPT + 23 others); Mon, 20 Mar 2017 05:33:32 -0400 Received: from mail-pg0-f42.google.com ([74.125.83.42]:34621 "EHLO mail-pg0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753325AbdCTJcu (ORCPT ); Mon, 20 Mar 2017 05:32:50 -0400 Received: by mail-pg0-f42.google.com with SMTP id 21so41261540pgg.1 for ; Mon, 20 Mar 2017 02:32:49 -0700 (PDT) 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=UDDIGanfDgPJu9k4o6CjScW8F8Q7MStcB/l3rPpHtE0=; b=eD7cN4dEi72ahE/fyOo8kXbC1mSz2lSxHSTnWqyY7ACTOSb/3+6Fo4EDm6bS3QbbjA +mOKIgN1X4HieTf7Rt9u28XQHasbj0kWrAoATcKMJzVyC7uGHBtvkrWc7DlxTnRUOTOO 5fIUjFvjWeRiE/vu3prOffZfd26V6hbwbYxZY= 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=UDDIGanfDgPJu9k4o6CjScW8F8Q7MStcB/l3rPpHtE0=; b=O5LA1ShGDQhtn00TItP9v9yfQusYVcSbXCdwesCCloxp+t+omm0n6xBQ8UUn4Q/SvR bGRuNveRrJuHtwoxZ1FDgcdbtJZynrs/Gvk9cyiKyhg1cXr2Wy9se1CwSRw3HtiY8YTY UZBg8c2wdklBd7ZKMaJ37NQ4yobR8GgfnReWp5Kvr8ph5DCVW23FZSZsTCqn1NAkDqkF BZbqhSC4u1+K/Ubiia9te0PnskV1Dh5NLy+chgMsHUXQJzagiQ9S1oyj4cC7Flpt9vW3 9iNqJgFeqWgrH6zg6uOO3QiiNFFuyFyrVxJA9vptrKfYOqTWc+VIaIvCfZfmxehRqBrm mNqA== X-Gm-Message-State: AFeK/H0JOah4yMoTGmqah4j2shW0euwWZlHQPmHbBhN/k8LvjKMLYu1liYFATyRGhKBHmPOA X-Received: by 10.99.66.193 with SMTP id p184mr30073145pga.213.1490002368671; Mon, 20 Mar 2017 02:32:48 -0700 (PDT) Received: from localhost ([122.171.239.200]) by smtp.gmail.com with ESMTPSA id l29sm22031526pfb.118.2017.03.20.02.32.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Mar 2017 02:32:48 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Kevin Hilman , Pavel Machek , Len Brown Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V4 7/9] PM / domain: Register for PM QOS performance notifier Date: Mon, 20 Mar 2017 15:02:19 +0530 Message-Id: X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some platforms have the capability to configure the performance state of their Power Domains. The performance levels are identified by positive integer values, a lower value represents lower performance state. The power domain driver should be able to retrieve all information required to configure the performance state of the power domain, with the help of the performance constraint's target value. This patch implements performance state management in PM domain core. The performance QOS uses the common QOS notifier list and we call __performance_notifier() if the notifier is issued for performance constraint. This also allows the power domain drivers to implement a ->set_performance_state() callback, which will be called by the power domain core from within the notifier routine. If a domain doesn't implement ->set_performance_state() callback, then it is assumed that its parents are responsible for performance state configuration. Both devices and sub-domains are accounted for while finding the highest performance state requested. Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 4 +++ 2 files changed, 81 insertions(+) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 6e4e22aa14a2..03dd7a61f08a 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -452,6 +452,79 @@ static int __resume_latency_notifier(struct generic_pm_domain_data *gpd_data, return NOTIFY_DONE; } +static void __update_domain_performance_state(struct generic_pm_domain *genpd, + int depth) +{ + struct generic_pm_domain_data *pd_data; + struct generic_pm_domain *subdomain; + struct pm_domain_data *pdd; + unsigned int state = 0; + struct gpd_link *link; + + /* Traverse all devices within the domain */ + list_for_each_entry(pdd, &genpd->dev_list, list_node) { + pd_data = to_gpd_data(pdd); + + if (pd_data->performance_state > state) + state = pd_data->performance_state; + } + + /* Traverse all subdomains within the domain */ + list_for_each_entry(link, &genpd->master_links, master_node) { + subdomain = link->slave; + + if (subdomain->performance_state > state) + state = subdomain->performance_state; + } + + if (genpd->performance_state == state) + return; + + genpd->performance_state = state; + + if (genpd->set_performance_state) { + genpd->set_performance_state(genpd, state); + return; + } + + /* Propagate to parent power domains */ + list_for_each_entry(link, &genpd->slave_links, slave_node) { + struct generic_pm_domain *master = link->master; + + genpd_lock_nested(master, depth + 1); + __update_domain_performance_state(master, depth + 1); + genpd_unlock(master); + } +} + +static int __performance_notifier(struct generic_pm_domain_data *gpd_data, + unsigned long val) +{ + struct generic_pm_domain *genpd = ERR_PTR(-ENODATA); + struct device *dev = gpd_data->base.dev; + struct pm_domain_data *pdd; + + spin_lock_irq(&dev->power.lock); + + pdd = dev->power.subsys_data ? + dev->power.subsys_data->domain_data : NULL; + + if (pdd && pdd->dev) + genpd = dev_to_genpd(dev); + + spin_unlock_irq(&dev->power.lock); + + if (IS_ERR(genpd)) + return NOTIFY_DONE; + + genpd_lock(genpd); + gpd_data->performance_state = val; + __update_domain_performance_state(genpd, 0); + genpd_unlock(genpd); + + return NOTIFY_DONE; +} + static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, unsigned long val, void *ptr) { @@ -464,6 +537,9 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, if (dev_pm_qos_notifier_is_resume_latency(dev, ptr)) return __resume_latency_notifier(gpd_data, val); + if (dev_pm_qos_notifier_is_performance(dev, ptr)) + return __performance_notifier(gpd_data, val); + dev_err(dev, "%s: Unexpected notifier call\n", __func__); return NOTIFY_BAD; } @@ -1157,6 +1233,7 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev, gpd_data->td.constraint_changed = true; gpd_data->td.effective_constraint_ns = -1; gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; + gpd_data->performance_state = 0; spin_lock_irq(&dev->power.lock); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 5339ed5bd6f9..83795935709e 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -62,8 +62,11 @@ struct generic_pm_domain { unsigned int device_count; /* Number of devices */ unsigned int suspended_count; /* System suspend device counter */ unsigned int prepared_count; /* Suspend counter of prepared devices */ + unsigned int performance_state; /* Max requested performance state */ int (*power_off)(struct generic_pm_domain *domain); int (*power_on)(struct generic_pm_domain *domain); + int (*set_performance_state)(struct generic_pm_domain *domain, + unsigned int state); struct gpd_dev_ops dev_ops; s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ bool max_off_time_changed; @@ -117,6 +120,7 @@ struct generic_pm_domain_data { struct pm_domain_data base; struct gpd_timing_data td; struct notifier_block nb; + unsigned int performance_state; }; #ifdef CONFIG_PM_GENERIC_DOMAINS From patchwork Mon Mar 20 09:32:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 95487 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp852810qgd; Mon, 20 Mar 2017 02:34:24 -0700 (PDT) X-Received: by 10.84.193.129 with SMTP id f1mr8012086pld.63.1490002464549; Mon, 20 Mar 2017 02:34:24 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e26si11956014pfb.379.2017.03.20.02.34.24; Mon, 20 Mar 2017 02:34:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753755AbdCTJda (ORCPT + 23 others); Mon, 20 Mar 2017 05:33:30 -0400 Received: from mail-pf0-f181.google.com ([209.85.192.181]:33436 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753416AbdCTJcx (ORCPT ); Mon, 20 Mar 2017 05:32:53 -0400 Received: by mail-pf0-f181.google.com with SMTP id e129so24618962pfh.0 for ; Mon, 20 Mar 2017 02:32:52 -0700 (PDT) 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=dQuT8bm7gWUSN2fQIQ2FsDbg5lfkq36qPJFqckV+Dds=; b=PIfRmSq18RU5iJLOE/LSQR2DwFRLAefiyHXDn2Ehs64Y/j8PTrOVmtOuA6ebURNNk7 8w4ifm04UWx/iLVFxL4xF4ZGsoK458KbDRZHKQ+W4blcxn22HszLwc3hMYM2rDpntPv9 VEbIB9XG7JjmUsQgOPYH5480hBF5O2Xb1xRZU= 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=dQuT8bm7gWUSN2fQIQ2FsDbg5lfkq36qPJFqckV+Dds=; b=Dndxcdyy8+VaZifPol62FUjEhqjre/zNR/IfpDjLpfNBb2drjpAgiyHwA7EnTeEc9G WvZ+fJqafKU3eXKOIoAXGS64jEfQStaHKJUi0ih0ZxLsxZa/AETeuC3Kzb+/fuFZ6X1H ula8xFCpzUZxZdvzaZbvQsqPtrSdI2hU63IzRZThQcu1oWIov/ruFrl1v2ONeJwLZhun tTPYMHxUhe45XVi/QCi1PgW0PNbvvOEesjYcybPjbXuKc+vO77tJ2UQmW6wMxTsUKHtW Gy8zqpNlI2TCO9XatmwbSx26sMOw0N7QtxUnplxmd5SDji80qb233npSCHMLzrrYuTSl t/YQ== X-Gm-Message-State: AFeK/H0tuaf4he3E5WZBm2dpd3pKUpmB76Y/lMYb1/zGwRhN3t3mTffWm1QCWaOPtcEkMH/N X-Received: by 10.98.99.196 with SMTP id x187mr31354128pfb.168.1490002371905; Mon, 20 Mar 2017 02:32:51 -0700 (PDT) Received: from localhost ([122.171.239.200]) by smtp.gmail.com with ESMTPSA id y70sm2951417pfa.96.2017.03.20.02.32.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Mar 2017 02:32:51 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Kevin Hilman , Len Brown , Pavel Machek Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V4 8/9] PM / Domain: Add struct device to genpd Date: Mon, 20 Mar 2017 15:02:20 +0530 Message-Id: X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The power-domain core would be using the OPP core going forward and the OPP core has a basic requirement of a device structure for its working. Add a struct device to the genpd structure and also add a genpd bus type for the devices. Note that the of_node field of the device is only set when separate DT node is present for the power-domain, otherwise the of node is common across multiple genpd devices and filling the of_node field with it doesn't sound right. Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 36 ++++++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 1 + 2 files changed, 37 insertions(+) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 03dd7a61f08a..51d3afc0476d 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1536,6 +1536,10 @@ static void genpd_lock_init(struct generic_pm_domain *genpd) } } +static struct bus_type genpd_bus_type = { + .name = "genpd", +}; + /** * pm_genpd_init - Initialize a generic I/O PM domain object. * @genpd: PM domain object to initialize. @@ -1588,6 +1592,18 @@ int pm_genpd_init(struct generic_pm_domain *genpd, return ret; } + genpd->dev.bus = &genpd_bus_type; + device_initialize(&genpd->dev); + dev_set_name(&genpd->dev, "%s", genpd->name); + + ret = device_add(&genpd->dev); + if (ret) { + dev_err(&genpd->dev, "failed to add device: %d\n", ret); + put_device(&genpd->dev); + kfree(genpd->free); + return ret; + } + mutex_lock(&gpd_list_lock); list_add(&genpd->gpd_list_node, &gpd_list); mutex_unlock(&gpd_list_lock); @@ -1625,6 +1641,7 @@ static int genpd_remove(struct generic_pm_domain *genpd) list_del(&genpd->gpd_list_node); genpd_unlock(genpd); + device_del(&genpd->dev); cancel_work_sync(&genpd->power_off_work); kfree(genpd->free); pr_debug("%s: removed %s\n", __func__, genpd->name); @@ -1794,6 +1811,7 @@ int of_genpd_add_provider_simple(struct device_node *np, if (!ret) { genpd->provider = &np->fwnode; genpd->has_provider = true; + genpd->dev->of_node = np; } } @@ -2407,3 +2425,21 @@ static void __exit pm_genpd_debug_exit(void) } __exitcall(pm_genpd_debug_exit); #endif /* CONFIG_DEBUG_FS */ + +static int __init pm_genpd_core_init(void) +{ + int ret; + + ret = bus_register(&genpd_bus_type); + if (ret) + pr_err("bus_register failed (%d)\n", ret); + + return ret; +} +pure_initcall(pm_genpd_core_init); + +static void __exit pm_genpd_core_exit(void) +{ + bus_unregister(&genpd_bus_type); +} +__exitcall(pm_genpd_core_exit); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 83795935709e..d55c0112dcde 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -47,6 +47,7 @@ struct genpd_power_state { struct genpd_lock_ops; struct generic_pm_domain { + struct device dev; struct dev_pm_domain domain; /* PM domain operations */ struct list_head gpd_list_node; /* Node in the global PM domains list */ struct list_head master_links; /* Links with PM domain as a master */ From patchwork Mon Mar 20 09:32:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 95483 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp852514qgd; Mon, 20 Mar 2017 02:33:24 -0700 (PDT) X-Received: by 10.84.233.200 with SMTP id m8mr38430122pln.92.1490002404616; Mon, 20 Mar 2017 02:33:24 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z190si11979390pfb.188.2017.03.20.02.33.24; Mon, 20 Mar 2017 02:33:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753654AbdCTJdY (ORCPT + 23 others); Mon, 20 Mar 2017 05:33:24 -0400 Received: from mail-pf0-f175.google.com ([209.85.192.175]:36432 "EHLO mail-pf0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753458AbdCTJc4 (ORCPT ); Mon, 20 Mar 2017 05:32:56 -0400 Received: by mail-pf0-f175.google.com with SMTP id o126so63458548pfb.3 for ; Mon, 20 Mar 2017 02:32:55 -0700 (PDT) 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=VAtpsp66u03PA5o+V+1AuMFlVe2NFyiT+Q3mC376Mks=; b=WYKBVGd4F/uDYJmIST9NnWsBF3WSv44kRPRqM/+TLYZmaNnHY0LQVeUsZ0E7759hQy CVTYDv7GUpBaBVjOkoQ5AOmWHmBOt9xhwJtuzLiIZtEoghqk2KIJp+9UuUjGRkdK9qs9 EG2d6W+1xiq2tKA/V64G7Z5mRvfUIu5ZddqPU= 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=VAtpsp66u03PA5o+V+1AuMFlVe2NFyiT+Q3mC376Mks=; b=oA4kblj8xbGcxCmB7nMbzuoKBJQ5Hg+dw1XjBp8wINFnIHB65uVysqIAbgqO9/j1u1 k7ara9xXANHFImEVfKBRjV2n7ePcq9PJKKTWg8ZLJzW2x1AY2G+bu2b6D+uPIYCiy82i b3/6tSPCTwmAclCpcyAxGelDO9jQMddg8ZzIf3UnLK2tI5yqwR/ogkJM2XC+w6mR6M7k MP0iDeQjX82mF09oGJg83Estp4TQNW6UJ71ndAiBrCv4hB0Hj3EeV6fFR6XiWZKCje7U QPweMNpfenTvxaSsz6u/M0VhgMLOLsOGYMEGJrJNIVaKEzsuxKtCErzoRQOpAI7mFUUT 4DVw== X-Gm-Message-State: AFeK/H3dLzSsqqZSjtNu4H/sZG+xLQtwZCLGBYAu7Q9I71VVATZoGCHQ+wGit1slMIckv+cZ X-Received: by 10.84.139.195 with SMTP id 61mr39422710plr.109.1490002375090; Mon, 20 Mar 2017 02:32:55 -0700 (PDT) Received: from localhost ([122.171.239.200]) by smtp.gmail.com with ESMTPSA id c16sm31633620pfl.7.2017.03.20.02.32.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Mar 2017 02:32:54 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Kevin Hilman , Pavel Machek , Len Brown Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V4 9/9] PM / Domain: Add support to parse domain's OPP table Date: Mon, 20 Mar 2017 15:02:21 +0530 Message-Id: <4816e672e5f3495d87c85cda353e29df3885a0b1.1490001099.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Parse the OPP table from of_genpd_add_provider_simple() by calling dev_pm_opp_of_add_table(), if the power domain supports changing of performance states. Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 46 +++++++++++++++++++++++++++++++++++++-------- include/linux/pm_domain.h | 1 + 2 files changed, 39 insertions(+), 8 deletions(-) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 51d3afc0476d..8155f95b0db2 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1806,15 +1807,37 @@ int of_genpd_add_provider_simple(struct device_node *np, mutex_lock(&gpd_list_lock); - if (pm_genpd_present(genpd)) { - ret = genpd_add_provider(np, genpd_xlate_simple, genpd); - if (!ret) { - genpd->provider = &np->fwnode; - genpd->has_provider = true; - genpd->dev->of_node = np; + if (!pm_genpd_present(genpd)) + goto unlock; + + genpd->dev.of_node = np; + + /* Parse genpd OPP table */ + if (genpd->set_performance_state) { + ret = dev_pm_opp_of_add_table(&genpd->dev); + if (ret) { + dev_err(&genpd->dev, "Failed to add OPP table: %d\n", + ret); + goto unlock; + } + + genpd->has_opp_table = true; + } + + ret = genpd_add_provider(np, genpd_xlate_simple, genpd); + if (ret) { + if (genpd->has_opp_table) { + genpd->has_opp_table = false; + dev_pm_opp_of_remove_table(&genpd->dev); } + + goto unlock; } + genpd->provider = &np->fwnode; + genpd->has_provider = true; + +unlock: mutex_unlock(&gpd_list_lock); return ret; @@ -1887,10 +1910,17 @@ void of_genpd_del_provider(struct device_node *np) * provider, set the 'has_provider' to false * so that the PM domain can be safely removed. */ - list_for_each_entry(gpd, &gpd_list, gpd_list_node) - if (gpd->provider == &np->fwnode) + list_for_each_entry(gpd, &gpd_list, gpd_list_node) { + if (gpd->provider == &np->fwnode) { gpd->has_provider = false; + if (!gpd->has_opp_table) + continue; + + dev_pm_opp_of_remove_table(&gpd->dev); + } + } + list_del(&cp->link); of_node_put(cp->node); kfree(cp); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index d55c0112dcde..821d7cf5974b 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -57,6 +57,7 @@ struct generic_pm_domain { struct work_struct power_off_work; struct fwnode_handle *provider; /* Identity of the domain provider */ bool has_provider; + bool has_opp_table; const char *name; atomic_t sd_count; /* Number of subdomains with power "on" */ enum gpd_status status; /* Current state of the domain */