From patchwork Wed Apr 26 10:57:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 98238 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp261444qgf; Wed, 26 Apr 2017 03:58:06 -0700 (PDT) X-Received: by 10.98.76.140 with SMTP id e12mr32094039pfj.128.1493204285898; Wed, 26 Apr 2017 03:58:05 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w28si25058184pfk.227.2017.04.26.03.58.05; Wed, 26 Apr 2017 03:58:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1038058AbdDZK6C (ORCPT + 14 others); Wed, 26 Apr 2017 06:58:02 -0400 Received: from mail-pf0-f170.google.com ([209.85.192.170]:35545 "EHLO mail-pf0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2998893AbdDZK5f (ORCPT ); Wed, 26 Apr 2017 06:57:35 -0400 Received: by mail-pf0-f170.google.com with SMTP id v14so36980239pfd.2 for ; Wed, 26 Apr 2017 03:57: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=jgFxHr+7s4Tdird13zMdMi4GqFXmetymbC5sOfC1mig=; b=e63JKAs/Z3a/q5yZBh3si+yjyzmSkHLGfIBHFPkvZLCMvVEd5tomJkWPPplVT8ZRUW sS90uMrv4P8FjqdyWKwwgn1u6nmzJicNfHMzUuL21n7HBjAAh8xciWECvcKxsrxX9lDr a5be+gmCubGhJC16TLVvcAOPJ04pVC+Bdwxfg= 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=jgFxHr+7s4Tdird13zMdMi4GqFXmetymbC5sOfC1mig=; b=kU5ihhCJZ09kpvE3uCXLl9B9UEclOtwTkq7gJyNpOHyWXnTkowLa1MY1FeNlVFE5MT fPoeiCgMuqQ/ZejA6AefG8gf9CdVpO+3zP00dkMmURbU0qwEjljwwXyKPrzISmZuLmQg 6COukcWdH+9duvoT9n/b+krCWS/PQ5A1ZNsN/inavHQPF3JplUvwCQ3VMKJVdng1afEA iKSBVEWYqKE9fWfzDKdjFqf4k9m67IxKKQc3dNItWE7tiadcwVgg31DSXR6YJeuTfsmL srUFzJboGaq9FvXw2QX/om6ZDUY2jmcb/o8+NjSrUkuXu2JPqrr2AkNTFZQhQiLICvsI 73tA== X-Gm-Message-State: AN3rC/5QoLuFRat5Ov2Idq8aZB1GMtlg81PEstZt3RaOmCPeo/BYeUVD AQNB5aHBx3loryO2 X-Received: by 10.98.198.210 with SMTP id x79mr32102558pfk.224.1493204253926; Wed, 26 Apr 2017 03:57:33 -0700 (PDT) Received: from localhost ([122.172.121.5]) by smtp.gmail.com with ESMTPSA id 3sm21812524pfe.20.2017.04.26.03.57.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 03:57:33 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , 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 , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, Viresh Kumar Subject: [PATCH V6 3/9] PM / QOS: Keep common notifier list for genpd constraints Date: Wed, 26 Apr 2017 16:27:07 +0530 Message-Id: X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 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 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 Acked-by: Ulf Hansson --- 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 da49a8383dc3..f6f616ac5cc2 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -426,14 +426,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 genpd_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; @@ -466,6 +462,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_is_resume_latency(dev, ptr)) + return genpd_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..e546d1a2f237 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_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 Wed Apr 26 10:57:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 98241 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp261582qgf; Wed, 26 Apr 2017 03:58:34 -0700 (PDT) X-Received: by 10.84.233.136 with SMTP id l8mr43092644plk.49.1493204314755; Wed, 26 Apr 2017 03:58:34 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w20si25075278pgj.196.2017.04.26.03.58.34; Wed, 26 Apr 2017 03:58:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2998964AbdDZK6S (ORCPT + 14 others); Wed, 26 Apr 2017 06:58:18 -0400 Received: from mail-pg0-f46.google.com ([74.125.83.46]:34220 "EHLO mail-pg0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2998897AbdDZK5l (ORCPT ); Wed, 26 Apr 2017 06:57:41 -0400 Received: by mail-pg0-f46.google.com with SMTP id v1so31218185pgv.1 for ; Wed, 26 Apr 2017 03:57:41 -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=s7xx9y+NgAAID9R//tkAfBBzWhZjBvgfxdDNG6MSfoQ=; b=VZHiqjr5pMEvftOcxYfKqXnV7PQcKEedjglHTqBAeAZppfL6/TcWZ5xWaRjjb/J2F4 ExbCctZl5GtdPkJHwLCuB5CpzjevgVw+TlQlpT7/yw/4RKTpN9NG1wliwMujregHJNiB bjR8h8/FkYRpw5tOEipWour8V0vg9ILMpfQ5o= 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=s7xx9y+NgAAID9R//tkAfBBzWhZjBvgfxdDNG6MSfoQ=; b=Qlmc+aYJIKHzcg8N/WbKliY3k3IugYfpivw2IczTIv20C4Tyo9G5POUvoYHhoVrUtN fZRDr0GixULJCcFpnMgEJt3/YvFj3KynLK+k9IpI9owNmJpWObDF0Aw+gbZ21/Up77Kw EWiCcM0fr1ZuKlAlv8f5JcPbh12xSYC4OREuwLWER+jp2GeJBg743+UHJ9ztLcNMpQxT REv0ZSC80gn7OJbzjZXvyam/gjCi3urE3E9x/VUjArnw6TD29fD397Vb0bZ8zhycZt7r hj8ryvcNvXlQ/G2tVYz4ie+E2xGNfdOAcKu2gInXJyzAV6NxjG1BY1Ws20OtOuypsKwE p9kw== X-Gm-Message-State: AN3rC/5H92UwkwepZhjRjplS06HTU47zaN1zmyTD09Hyiaaclc1e68ZD Mlf6BzOhYKAg3vBg X-Received: by 10.84.128.66 with SMTP id 60mr31122768pla.167.1493204260963; Wed, 26 Apr 2017 03:57:40 -0700 (PDT) Received: from localhost ([122.172.121.5]) by smtp.gmail.com with ESMTPSA id g22sm41728779pfd.22.2017.04.26.03.57.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 03:57:40 -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, sudeep.holla@arm.com, Viresh Kumar Subject: [PATCH V6 5/9] PM / OPP: Add support to parse "power-domain-opp" property Date: Wed, 26 Apr 2017 16:27:09 +0530 Message-Id: <127ea4f4f4451c3ea6740c6cdde9d0cdde405075.1493203884.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-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The devices can specify phandle to their power-domain's OPP node in their OPP nodes under the "power-domain-opp" property. This patch updates the OPP core to parse it. The OPP nodes are allowed to have the "power-domain-opp" property, only if the device node contains the "power-domains" property. The OPP nodes aren't allowed to contain this property partially, i.e. Either all OPP nodes in the OPP table have the "power-domain-opp" property or none of them have it. The QoS framework represents the request values by s32 type variables and so we are forced to convert the 64 bit values read from DT (from the "opp-hz" property) into s32. It shouldn't be a problem unless someone uses real frequency values in "opp-hz" property for the power domains. A comment is added in the code to take a note of that. We can fix that later once we have real platforms that want it. Signed-off-by: Viresh Kumar --- drivers/base/power/opp/core.c | 72 +++++++++++++++++++++++++++++++++++++ drivers/base/power/opp/debugfs.c | 3 ++ drivers/base/power/opp/of.c | 77 ++++++++++++++++++++++++++++++++++++++++ drivers/base/power/opp/opp.h | 12 +++++++ 4 files changed, 164 insertions(+) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index dae61720b314..dc8b7bc0061a 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -543,6 +543,62 @@ _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, 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_dfreq, int new_dfreq) +{ + int ret; + + /* Scaling up? Scale voltage before frequency */ + if (freq > old_freq) { + ret = _update_pm_qos_request(dev, req, new_dfreq); + if (ret) + return ret; + } + + /* Change frequency */ + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + if (ret) + goto restore_dfreq; + + /* Scaling down? Scale voltage after frequency */ + if (freq < old_freq) { + ret = _update_pm_qos_request(dev, req, new_dfreq); + 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_dfreq: + if (old_dfreq != -1) + _update_pm_qos_request(dev, req, old_dfreq); + + 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 +719,19 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) regulators = opp_table->regulators; + /* Need to configure power domain performance state */ + if (opp_table->has_domain_opp) { + int old_dfreq = -1, new_dfreq; + struct dev_pm_qos_request *req = &opp_table->qos_request; + + new_dfreq = opp->domain_rate; + if (!IS_ERR(old_opp)) + old_dfreq = old_opp->domain_rate; + + return _generic_set_opp_domain(dev, clk, req, old_freq, freq, + old_dfreq, new_dfreq); + } + /* Only frequency scaling */ if (!regulators) { ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); @@ -808,6 +877,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..4b7eb379c84f 100644 --- a/drivers/base/power/opp/debugfs.c +++ b/drivers/base/power/opp/debugfs.c @@ -104,6 +104,9 @@ 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("domain_rate", S_IRUGO, d, &opp->domain_rate)) + 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..77693ba3ed55 100644 --- a/drivers/base/power/opp/of.c +++ b/drivers/base/power/opp/of.c @@ -254,6 +254,70 @@ struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) } EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node); +static int _parse_domain_opp(struct dev_pm_opp *opp, + struct opp_table *opp_table, struct device *dev, + struct device_node *np) +{ + struct device_node *dnp; + u64 rate; + int ret; + + if (!of_find_property(np, "power-domain-opp", NULL)) { + if (unlikely(opp_table->has_domain_opp == 1)) { + dev_err(dev, "%s: Not all OPP nodes have power-domain-opp\n", + __func__); + return -EINVAL; + } + + /* overwrite to avoid conditional statement */ + opp_table->has_domain_opp = 0; + return 0; + } + + if (unlikely(!opp_table->has_domain)) { + dev_err(dev, "%s: OPP node can't have power-domain-opp property without power domain\n", + __func__); + return -EINVAL; + } + + if (unlikely(!opp_table->has_domain_opp)) { + dev_err(dev, "%s: Not all OPP nodes have power-domain-opp\n", + __func__); + return -EINVAL; + } + + dnp = of_parse_phandle(np, "power-domain-opp", 0); + if (unlikely(!dnp)) { + dev_err(dev, "%s: Unable to parse phandle of power-domain-opp\n", + __func__); + return -EINVAL; + } + + /* Read opp-hz from domain's OPP table */ + ret = of_property_read_u64(dnp, "opp-hz", &rate); + if (ret < 0) { + dev_err(dev, "%s: opp-hz not found in domain's node\n", + __func__); + goto put_node; + } + + /* + * The "domain_rate" field is directly passed to the QoS APIs and they + * accept s32 values only. Will check this again once we have platforms + * that really keep u64 values for power domains. + */ + opp->domain_rate = (int)rate; + + /* overwrite to avoid conditional statement */ + opp_table->has_domain_opp = 1; + + ret = 0; + +put_node: + of_node_put(dnp); + return ret; +} + /** * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings) * @opp_table: OPP table @@ -296,6 +360,10 @@ static int _opp_add_static_v2(struct opp_table *opp_table, struct device *dev, goto free_opp; } + ret = _parse_domain_opp(new_opp, opp_table, dev, np); + if (ret) + 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 @@ -375,6 +443,15 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np) if (!opp_table) return -ENOMEM; + /* + * Only devices with parent power-domains can have "power-domain-opp" + * property. + */ + if (of_find_property(dev->of_node, "power-domains", NULL)) { + opp_table->has_domain = true; + opp_table->has_domain_opp = -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..5350eb4eedd0 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; @@ -59,6 +60,7 @@ extern struct list_head opp_tables; * @turbo: true if turbo (boost) OPP * @suspend: true if suspend OPP * @rate: Frequency in hertz + * @domain_rate: Copy of domain's rate * @supplies: Power supplies voltage/current values * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's * frequency from any other OPP's frequency. @@ -77,6 +79,7 @@ struct dev_pm_opp { bool turbo; bool suspend; unsigned long rate; + int domain_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_domain: True if the device node contains "power-domain" property + * @has_domain_opp: Can have value of 0, 1 or -1. -1 means uninitialized state, + * 0 means that OPP nodes don't have "power-domain-opp" property and 1 means + * that OPP nodes have it. + * @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_domain; + int has_domain_opp; + struct dev_pm_qos_request qos_request; + #ifdef CONFIG_DEBUG_FS struct dentry *dentry; char dentry_name[NAME_MAX]; From patchwork Wed Apr 26 10:57:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 98242 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp261587qgf; Wed, 26 Apr 2017 03:58:36 -0700 (PDT) X-Received: by 10.99.3.214 with SMTP id 205mr31690249pgd.222.1493204316087; Wed, 26 Apr 2017 03:58:36 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w20si25075278pgj.196.2017.04.26.03.58.34; Wed, 26 Apr 2017 03:58:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2998967AbdDZK6V (ORCPT + 14 others); Wed, 26 Apr 2017 06:58:21 -0400 Received: from mail-pg0-f48.google.com ([74.125.83.48]:34232 "EHLO mail-pg0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2998900AbdDZK5o (ORCPT ); Wed, 26 Apr 2017 06:57:44 -0400 Received: by mail-pg0-f48.google.com with SMTP id v1so31218763pgv.1 for ; Wed, 26 Apr 2017 03:57:44 -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=B50qpEdCppdKvHSCFLGRht8u1PFQdSOBZbnakedoE6M=; b=eUkNJNJcahI6OFRQ6vQELGbXGcoXot6GH3qXd2sGbyX9tUI69qE7s7L7Qoxju4oQPW z5ANA2BbWABNwtz+KfoqUM+uizuAX9Hf5+G6Z8x3b6I1V6Hzt5k+RSyo0ykaDjh0x6pj QA1EVsQSh3HoJzHSdJzCh7IjNfWXo4IhsnRWs= 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=B50qpEdCppdKvHSCFLGRht8u1PFQdSOBZbnakedoE6M=; b=iNnHMwNu0lU0/rVEHiXra5EHifrgEReHsT9Yz2YyxZbWwAlwIY6JciUAOryQ18+qvv w8gByQXenVuvLLGrs1/0EMmDPttpA9/JJJGAbMU3d5kTnbrPjpCUoTA6t5VfZ9ebdqO5 L1Ofa22ZRimc/J1S6tXX3VCuQxXJacBV2eKRBXHLWweHscKO5IcPnUtVh9OIorFA50X5 ThKPu4gMBPTjneoHqNHW+ge1fRn1o0HLIOXfAJy+EAGEkYakoc0hunQuW63j+fw5x5fw +u9ZmbUqJd6jZi4wsrGTgv7fIVmz+NoCnoOxHMSfnUHwyTOo3EANK1jwB4ULcCddWEO4 04VQ== X-Gm-Message-State: AN3rC/7+tSGj7zsQl66yZ2Pz4OS/+6Kq/MgCfF/ubGeaf223r9Xj215U fYaQhk5kg6JMXs+L X-Received: by 10.84.230.229 with SMTP id e92mr42379318plk.2.1493204264240; Wed, 26 Apr 2017 03:57:44 -0700 (PDT) Received: from localhost ([122.172.121.5]) by smtp.gmail.com with ESMTPSA id p6sm41912810pgn.9.2017.04.26.03.57.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 03:57:43 -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, sudeep.holla@arm.com, Viresh Kumar Subject: [PATCH V6 6/9] PM / OPP: Implement dev_pm_opp_of_add_table_indexed() Date: Wed, 26 Apr 2017 16:27:10 +0530 Message-Id: <2268452b1c6929fc5b08c34aec9a06ebd0993461.1493203884.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-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The "operating-points-v2" property can contain a list of phandles now, specifically for the power domain providers that provide multiple domains. Add support to parse that. Signed-off-by: Viresh Kumar --- drivers/base/power/opp/of.c | 50 +++++++++++++++++++++++++++++++++++++++------ include/linux/pm_opp.h | 6 ++++++ 2 files changed, 50 insertions(+), 6 deletions(-) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/opp/of.c b/drivers/base/power/opp/of.c index 77693ba3ed55..9cdf3a848e69 100644 --- a/drivers/base/power/opp/of.c +++ b/drivers/base/power/opp/of.c @@ -243,14 +243,17 @@ void dev_pm_opp_of_remove_table(struct device *dev) EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); /* Returns opp descriptor node for a device, caller must do of_node_put() */ -struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) +static struct device_node *_of_get_opp_desc_node_indexed(struct device *dev, + int index) { - /* - * There should be only ONE phandle present in "operating-points-v2" - * property. - */ + /* "operating-points-v2" can be an array for power domain providers */ + return of_parse_phandle(dev->of_node, "operating-points-v2", index); +} - return of_parse_phandle(dev->of_node, "operating-points-v2", 0); +/* Returns opp descriptor node for a device, caller must do of_node_put() */ +struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) +{ + return _of_get_opp_desc_node_indexed(dev, 0); } EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node); @@ -572,6 +575,41 @@ int dev_pm_opp_of_add_table(struct device *dev) } EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table); +/** + * dev_pm_opp_of_add_table_indexed() - Initialize indexed opp table from device tree + * @dev: device pointer used to lookup OPP table. + * @index: Index number. + * + * Register the initial OPP table with the OPP library for given device only + * using the "operating-points-v2" property. + * + * Return: + * 0 On success OR + * Duplicate OPPs (both freq and volt are same) and opp->available + * -EEXIST Freq are same and volt are different OR + * Duplicate OPPs (both freq and volt are same) and !opp->available + * -ENOMEM Memory allocation failure + * -ENODEV when 'operating-points' property is not found or is invalid data + * in device node. + * -ENODATA when empty 'operating-points' property is found + * -EINVAL when invalid entries are found in opp-v2 table + */ +int dev_pm_opp_of_add_table_indexed(struct device *dev, int index) +{ + struct device_node *opp_np; + int ret; + + opp_np = _of_get_opp_desc_node_indexed(dev, index); + if (!opp_np) + return -ENODEV; + + ret = _of_add_opp_table_v2(dev, opp_np); + of_node_put(opp_np); + + return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed); + /* CPU device specific helpers */ /** diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index a6685b3dde26..8263d831715c 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -284,6 +284,7 @@ static inline void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) int dev_pm_opp_of_add_table(struct device *dev); +int dev_pm_opp_of_add_table_indexed(struct device *dev, int index); void dev_pm_opp_of_remove_table(struct device *dev); int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask); void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask); @@ -295,6 +296,11 @@ static inline int dev_pm_opp_of_add_table(struct device *dev) return -ENOTSUPP; } +static inline int dev_pm_opp_of_add_table_indexed(struct device *dev, int index) +{ + return -ENOTSUPP; +} + static inline void dev_pm_opp_of_remove_table(struct device *dev) { } From patchwork Wed Apr 26 10:57:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 98243 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp261591qgf; Wed, 26 Apr 2017 03:58:36 -0700 (PDT) X-Received: by 10.84.129.4 with SMTP id 4mr43148049plb.37.1493204316814; Wed, 26 Apr 2017 03:58:36 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w20si25075278pgj.196.2017.04.26.03.58.36; Wed, 26 Apr 2017 03:58:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2998889AbdDZK6X (ORCPT + 14 others); Wed, 26 Apr 2017 06:58:23 -0400 Received: from mail-pg0-f46.google.com ([74.125.83.46]:33561 "EHLO mail-pg0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2998904AbdDZK5x (ORCPT ); Wed, 26 Apr 2017 06:57:53 -0400 Received: by mail-pg0-f46.google.com with SMTP id 63so42917319pgh.0 for ; Wed, 26 Apr 2017 03:57:53 -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=RlVYrEmx7ZrG06nsAH/haTkq4F7Jhe6eAZ7lCLVRKvo=; b=G5OJTfXh5ejITGkqekgxKRGSVbnj9d0bFYwAPK57xRO1G2E+U/CXejQkKGzjW0ML0S Qr8V2TIhcXCmGgevJa2LWbTz6YMj5oQutBoMQgWuzRh0oaqa6FJavhUIqY4PVPFiSFbJ LlX71qMp6EVQ7fDP/gDCV3/UGsdEy/7qF66gU= 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=RlVYrEmx7ZrG06nsAH/haTkq4F7Jhe6eAZ7lCLVRKvo=; b=UT2O42kdAT1aVzsecyCFOzcvE71CTfkvz8oG7r+Dc75KDmzCs63RNMZI1dBdyRfxAK rgw+pB/oMkQjrl1s266HKgJMaXxBGxcynBE0zoY8XM7k9L3dBc5R7NpPSnUAHdTvFOuV BM3aZdzviVBDz+d/KtROSmEg+aCU5Ouw+IVW+V32VObxn34oY/HsxXfpvlQJ4idxOFqS t7kba/2QdTtP19aLLueXKb0YnQrqpflFBmqbTncl4xlB8MrH2F0qS1O65dQ7+Erz5RI0 GUtPofkuU/v8UcVGC28nrRiwM9K4BojOiEMpmzZlHecyjzLyJdhb2zBFQYxTo2/iioUz 3Kcg== X-Gm-Message-State: AN3rC/7vUxokA+1jUp8EvW/oVHxnoAb0bTdx5b27XsNmOwa52FdReq5v GVfp0jYBxCE2BHSx X-Received: by 10.84.224.70 with SMTP id a6mr42582242plt.25.1493204270787; Wed, 26 Apr 2017 03:57:50 -0700 (PDT) Received: from localhost ([122.172.121.5]) by smtp.gmail.com with ESMTPSA id e22sm41954809pgn.11.2017.04.26.03.57.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 03:57:50 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , 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 , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, Viresh Kumar Subject: [PATCH V6 8/9] PM / Domain: Add struct device to genpd Date: Wed, 26 Apr 2017 16:27:12 +0530 Message-Id: <695de87a5901febfbd15603fe9de7f32ff513fff.1493203884.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-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The power-domain core would be using the OPP core going forward and the OPP core has the 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. Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 1 + 2 files changed, 38 insertions(+) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 7d35dafe8c97..85365611b258 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1546,6 +1546,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. @@ -1602,6 +1606,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); @@ -1639,6 +1655,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); @@ -1806,6 +1823,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; } } @@ -1839,6 +1857,7 @@ int of_genpd_add_provider_onecell(struct device_node *np, data->domains[i]->provider = &np->fwnode; data->domains[i]->has_provider = true; + data->domains[i]->dev.of_node = np; } ret = genpd_add_provider(np, genpd_xlate_onecell, data); @@ -2421,3 +2440,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 84ee474e66d0..c01f12b370d2 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -48,6 +48,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 Wed Apr 26 10:57:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 98244 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp261596qgf; Wed, 26 Apr 2017 03:58:37 -0700 (PDT) X-Received: by 10.98.75.25 with SMTP id y25mr31964979pfa.157.1493204317442; Wed, 26 Apr 2017 03:58:37 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w20si25075278pgj.196.2017.04.26.03.58.37; Wed, 26 Apr 2017 03:58:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2998985AbdDZK62 (ORCPT + 14 others); Wed, 26 Apr 2017 06:58:28 -0400 Received: from mail-pg0-f44.google.com ([74.125.83.44]:36357 "EHLO mail-pg0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2998906AbdDZK5z (ORCPT ); Wed, 26 Apr 2017 06:57:55 -0400 Received: by mail-pg0-f44.google.com with SMTP id t7so3631790pgt.3 for ; Wed, 26 Apr 2017 03:57:54 -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=FXJeXEklpTI2HOkCxHSnegIIoW+qE6oMPvFq9gq7Wf0=; b=dn55QwYWI60wQzniH9SjCVbHu6+s5jn6HUh4mIH15vYW9mVVT91pF8ahwGNu6CA5E6 wEODYyClWJo1asT/6MPDs9Xtcvlwm2LNGItcC/2srbmToE9vzdein+aqdgwl0fmnSZuN gU0Zr/HQm2XjfrpvHKp0pKvjxjLrj4iw4F+jo= 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=FXJeXEklpTI2HOkCxHSnegIIoW+qE6oMPvFq9gq7Wf0=; b=tgElh1y+f25YgtCKgOgJ0baTS03c/FbIUnn8UJakyqZesSphdCSAE0mebYuoeGNOWJ CnrncpGpzwxTiefafRA7mQGh0fggfC3IpY+KdQ6X1oYEDUPG/1WUmddF25J1Yzha4JcE VCxIRPGKaouIOCj50xTKos1jJ44TnMk3jYETuSqCkrh+1pVb0Nmh7wSUi+cKmOUL+P4i ccAWb0Pbno8VdO1mWwkeBRL05i8LL3cNANwe89xBevXNkaxAKpPPfw8YxkJjjANcDLky 9wc8xN0emFTeYYLVyGcvPmgsOdlo1XuJZWy5b9yaoydOjWkGKhRlKPGEZ2MC1jMAq8Mn UNBg== X-Gm-Message-State: AN3rC/4qVWD3Jn18m5iP8YZochnKKQhfDS4kB7+T//reN8dQit2Lp0af IOS0gR/lA681R7+A X-Received: by 10.98.57.71 with SMTP id g68mr31838039pfa.53.1493204274166; Wed, 26 Apr 2017 03:57:54 -0700 (PDT) Received: from localhost ([122.172.121.5]) by smtp.gmail.com with ESMTPSA id r1sm41799901pfg.12.2017.04.26.03.57.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 03:57:53 -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, sudeep.holla@arm.com, Viresh Kumar Subject: [PATCH V6 9/9] PM / Domain: Add support to parse domain's OPP table Date: Wed, 26 Apr 2017 16:27:13 +0530 Message-Id: X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 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 Parse the OPP table for power domains if they have their set_performance_state() callback set. Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 86 ++++++++++++++++++++++++++++++++++++--------- include/linux/pm_domain.h | 1 + 2 files changed, 71 insertions(+), 16 deletions(-) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 85365611b258..17ba541ec3c8 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1818,15 +1819,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; @@ -1841,6 +1864,7 @@ EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple); int of_genpd_add_provider_onecell(struct device_node *np, struct genpd_onecell_data *data) { + struct generic_pm_domain *genpd; unsigned int i; int ret = -EINVAL; @@ -1850,14 +1874,29 @@ int of_genpd_add_provider_onecell(struct device_node *np, mutex_lock(&gpd_list_lock); for (i = 0; i < data->num_domains; i++) { - if (!data->domains[i]) + genpd = data->domains[i]; + + if (!genpd) continue; - if (!pm_genpd_present(data->domains[i])) + if (!pm_genpd_present(genpd)) goto error; - data->domains[i]->provider = &np->fwnode; - data->domains[i]->has_provider = true; - data->domains[i]->dev.of_node = np; + genpd->dev.of_node = np; + + /* Parse genpd OPP table */ + if (genpd->set_performance_state) { + ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); + if (ret) { + dev_err(&genpd->dev, "Failed to add OPP table for index %d: %d\n", + i, ret); + goto error; + } + + genpd->has_opp_table = true; + } + + genpd->provider = &np->fwnode; + genpd->has_provider = true; } ret = genpd_add_provider(np, genpd_xlate_onecell, data); @@ -1870,10 +1909,18 @@ int of_genpd_add_provider_onecell(struct device_node *np, error: while (i--) { - if (!data->domains[i]) + genpd = data->domains[i]; + + if (!genpd) continue; - data->domains[i]->provider = NULL; - data->domains[i]->has_provider = false; + + genpd->provider = NULL; + genpd->has_provider = false; + + if (genpd->has_opp_table) { + genpd->has_opp_table = false; + dev_pm_opp_of_remove_table(&genpd->dev); + } } mutex_unlock(&gpd_list_lock); @@ -1900,10 +1947,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 c01f12b370d2..60fc5b165b91 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -58,6 +58,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 */