From patchwork Fri Jul 31 06:13:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 51737 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f200.google.com (mail-lb0-f200.google.com [209.85.217.200]) by patches.linaro.org (Postfix) with ESMTPS id E816822A24 for ; Fri, 31 Jul 2015 06:14:01 +0000 (UTC) Received: by lbcjj5 with SMTP id jj5sf20744215lbc.1 for ; Thu, 30 Jul 2015 23:14:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:date:from:to:cc:subject:message-id :references:mime-version:content-type:content-disposition :in-reply-to:user-agent:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=nhrVZa+i2ZLSRZ02wyr8EnjQy8oI2ZLHNPBcTZ7irzE=; b=Z1wGIjjKINWC8hnAqweRM75sfIIlK8tTohYp6+ws83uGk5aV93ELAdPwtTb2V5fMro mMukbhmSK7I9l+KgWQTsVwO285ud1vE1veK2Sa83VtXIdkzrwPiyXeu2pxv7tvLQuHoF VMlk4TxCmd4F6t6R3JN4uS+f7SWucw2oVrMZkbWDvU65znqWCMRmiJT/43FigZJTnh6P OgP5WsiZfdPrO8qRC6jRi1M/9Hg6HK9JK2GwBoWi+rjhIuDEM4HmvY+Yzg38sWYWfzKv GSFvJ/vS1LyV9IdUfTCbV5dJ0V0AuQ6jhtnuFHaHvR0G/xtVvEEEMjWccprP7XKT/mRp DASQ== X-Gm-Message-State: ALoCoQnL/tRgOQ5YtpZrkbngsCVvNG/cJs251otKwY/nDWJ4vANIsqnsWV5gO1xR6pRcixS5vYAx X-Received: by 10.152.1.105 with SMTP id 9mr394605lal.3.1438323240899; Thu, 30 Jul 2015 23:14:00 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.242.131 with SMTP id wq3ls222526lac.106.gmail; Thu, 30 Jul 2015 23:14:00 -0700 (PDT) X-Received: by 10.152.245.43 with SMTP id xl11mr1053452lac.26.1438323240617; Thu, 30 Jul 2015 23:14:00 -0700 (PDT) Received: from mail-lb0-f178.google.com (mail-lb0-f178.google.com. [209.85.217.178]) by mx.google.com with ESMTPS id l9si2689956lam.36.2015.07.30.23.14.00 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 30 Jul 2015 23:14:00 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.178 as permitted sender) client-ip=209.85.217.178; Received: by lbqc9 with SMTP id c9so14792590lbq.1 for ; Thu, 30 Jul 2015 23:14:00 -0700 (PDT) X-Received: by 10.152.5.228 with SMTP id v4mr1066941lav.36.1438323240193; Thu, 30 Jul 2015 23:14:00 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.7.198 with SMTP id l6csp164489lba; Thu, 30 Jul 2015 23:13:58 -0700 (PDT) X-Received: by 10.70.126.133 with SMTP id my5mr3306163pdb.14.1438323238072; Thu, 30 Jul 2015 23:13:58 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id mq9si7918157pdb.128.2015.07.30.23.13.56; Thu, 30 Jul 2015 23:13:58 -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; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751492AbbGaGNz (ORCPT + 12 others); Fri, 31 Jul 2015 02:13:55 -0400 Received: from mail-pa0-f42.google.com ([209.85.220.42]:34525 "EHLO mail-pa0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751396AbbGaGNy (ORCPT ); Fri, 31 Jul 2015 02:13:54 -0400 Received: by pacan13 with SMTP id an13so36178610pac.1 for ; Thu, 30 Jul 2015 23:13:54 -0700 (PDT) X-Received: by 10.66.141.109 with SMTP id rn13mr3010284pab.127.1438323233945; Thu, 30 Jul 2015 23:13:53 -0700 (PDT) Received: from localhost ([122.171.186.190]) by smtp.gmail.com with ESMTPSA id k9sm5399996pdp.60.2015.07.30.23.13.52 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 30 Jul 2015 23:13:53 -0700 (PDT) Date: Fri, 31 Jul 2015 11:43:48 +0530 From: Viresh Kumar To: Stephen Boyd Cc: Rafael Wysocki , linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, rob.herring@linaro.org, arnd.bergmann@linaro.org, nm@ti.com, broonie@kernel.org, mturquette@baylibre.com, Sudeep.Holla@arm.com, viswanath.puttagunta@linaro.org, l.stach@pengutronix.de, thomas.petazzoni@free-electrons.com, linux-arm-kernel@lists.infradead.org, ta.omasab@gmail.com, kesavan.abhilash@gmail.com, khilman@linaro.org, santosh.shilimkar@oracle.com, b.zolnierkie@samsung.com, Greg Kroah-Hartman , Len Brown , open list , Pavel Machek Subject: Re: [PATCH V3 11/16] PM / OPP: Add helpers for initializing CPU OPPs Message-ID: <20150731061348.GP17794@linux> References: <41e8c355e4e9f5a71b380cf87a7e09d10f00c606.1438166099.git.viresh.kumar@linaro.org> <20150731060711.GK3159@codeaurora.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20150731060711.GK3159@codeaurora.org> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.178 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , On 30-07-15, 23:07, Stephen Boyd wrote: > On 07/29, Viresh Kumar wrote: > > With "operating-points-v2" its possible to tell which devices share > > OPPs. We already have infrastructure to decode that information. > > > > This patch adds following APIs: > > - of_get_cpus_sharing_opps: Returns cpumask of CPUs sharing OPPs (only > > valid with v2 bindings). > > - of_cpumask_init_opp_table: Initializes OPPs for all CPUs present in > > cpumask. > > - of_cpumask_free_opp_table: Frees OPPs for all CPUs present in cpumask. > > > > - set_cpus_sharing_opps: Sets which CPUs share OPPs (only valid with old > > OPP bindings, as this information isn't present in DT). > > > > Reviewed-by: Bartlomiej Zolnierkiewicz > > Signed-off-by: Viresh Kumar > > Reviewed-by: Stephen Boyd > > Some minor nitpicks below: > if (!of_property_read_bool(np, "opp-shared")) ? > dev_err? > Why aren't we returning the PTR_ERR value here? ----------8<--------------- Message-Id: <6e499ed9e4d1eead26550f96002ef7ea9d067cb9.1438323186.git.viresh.kumar@linaro.org> From: Viresh Kumar Date: Fri, 12 Jun 2015 17:10:38 +0530 Subject: [PATCH] PM / OPP: Add helpers for initializing CPU OPPs With "operating-points-v2" its possible to tell which devices share OPPs. We already have infrastructure to decode that information. This patch adds following APIs: - of_get_cpus_sharing_opps: Returns cpumask of CPUs sharing OPPs (only valid with v2 bindings). - of_cpumask_init_opp_table: Initializes OPPs for all CPUs present in cpumask. - of_cpumask_free_opp_table: Frees OPPs for all CPUs present in cpumask. - set_cpus_sharing_opps: Sets which CPUs share OPPs (only valid with old OPP bindings, as this information isn't present in DT). Reviewed-by: Stephen Boyd Reviewed-by: Bartlomiej Zolnierkiewicz Signed-off-by: Viresh Kumar --- drivers/base/power/opp.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 23 +++++++ 2 files changed, 198 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 0ebcea49145a..663aae1c9834 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -11,6 +11,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -1195,6 +1196,26 @@ void of_free_opp_table(struct device *dev) } EXPORT_SYMBOL_GPL(of_free_opp_table); +void of_cpumask_free_opp_table(cpumask_var_t cpumask) +{ + struct device *cpu_dev; + int cpu; + + WARN_ON(cpumask_empty(cpumask)); + + for_each_cpu(cpu, cpumask) { + cpu_dev = get_cpu_device(cpu); + if (!cpu_dev) { + pr_err("%s: failed to get cpu%d device\n", __func__, + cpu); + continue; + } + + of_free_opp_table(cpu_dev); + } +} +EXPORT_SYMBOL_GPL(of_cpumask_free_opp_table); + /* Returns opp descriptor node from its phandle. Caller must do of_node_put() */ static struct device_node * _of_get_opp_desc_node_from_prop(struct device *dev, const struct property *prop) @@ -1211,6 +1232,31 @@ _of_get_opp_desc_node_from_prop(struct device *dev, const struct property *prop) return opp_np; } +/* Returns opp descriptor node for a device. Caller must do of_node_put() */ +static struct device_node *_of_get_opp_desc_node(struct device *dev) +{ + const struct property *prop; + + prop = of_find_property(dev->of_node, "operating-points-v2", NULL); + if (!prop) + return ERR_PTR(-ENODEV); + if (!prop->value) + return ERR_PTR(-ENODATA); + + /* + * TODO: Support for multiple OPP tables. + * + * There should be only ONE phandle present in "operating-points-v2" + * property. + */ + if (prop->length != sizeof(__be32)) { + dev_err(dev, "%s: Invalid opp desc phandle\n", __func__); + return ERR_PTR(-EINVAL); + } + + return _of_get_opp_desc_node_from_prop(dev, prop); +} + /* Initializes OPP tables based on new bindings */ static int _of_init_opp_table_v2(struct device *dev, const struct property *prop) @@ -1351,4 +1397,133 @@ int of_init_opp_table(struct device *dev) return _of_init_opp_table_v2(dev, prop); } EXPORT_SYMBOL_GPL(of_init_opp_table); + +int of_cpumask_init_opp_table(cpumask_var_t cpumask) +{ + struct device *cpu_dev; + int cpu, ret = 0; + + WARN_ON(cpumask_empty(cpumask)); + + for_each_cpu(cpu, cpumask) { + cpu_dev = get_cpu_device(cpu); + if (!cpu_dev) { + pr_err("%s: failed to get cpu%d device\n", __func__, + cpu); + continue; + } + + ret = of_init_opp_table(cpu_dev); + if (ret) { + pr_err("%s: couldn't find opp table for cpu:%d, %d\n", + __func__, cpu, ret); + + /* Free all other OPPs */ + of_cpumask_free_opp_table(cpumask); + break; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(of_cpumask_init_opp_table); + +/* Required only for V1 bindings, as v2 can manage it from DT itself */ +int set_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask) +{ + struct device_list_opp *list_dev; + struct device_opp *dev_opp; + struct device *dev; + int cpu, ret = 0; + + rcu_read_lock(); + + dev_opp = _find_device_opp(cpu_dev); + if (IS_ERR(dev_opp)) { + ret = -EINVAL; + goto out_rcu_read_unlock; + } + + for_each_cpu(cpu, cpumask) { + if (cpu == cpu_dev->id) + continue; + + dev = get_cpu_device(cpu); + if (!dev) { + dev_err(cpu_dev, "%s: failed to get cpu%d device\n", + __func__, cpu); + continue; + } + + list_dev = _add_list_dev(dev, dev_opp); + if (!list_dev) { + dev_err(dev, "%s: failed to add list-dev for cpu%d device\n", + __func__, cpu); + continue; + } + } +out_rcu_read_unlock: + rcu_read_unlock(); + + return 0; +} +EXPORT_SYMBOL_GPL(set_cpus_sharing_opps); + +/* + * Works only for OPP v2 bindings. + * + * cpumask should be already set to mask of cpu_dev->id. + * Returns -ENOENT if operating-points-v2 bindings aren't supported. + */ +int of_get_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask) +{ + struct device_node *np, *tmp_np; + struct device *tcpu_dev; + int cpu, ret = 0; + + /* Get OPP descriptor node */ + np = _of_get_opp_desc_node(cpu_dev); + if (IS_ERR(np)) { + dev_dbg(cpu_dev, "%s: Couldn't find opp node: %ld\n", __func__, + PTR_ERR(np)); + return -ENOENT; + } + + /* OPPs are shared ? */ + if (!of_property_read_bool(np, "opp-shared")) + goto put_cpu_node; + + for_each_possible_cpu(cpu) { + if (cpu == cpu_dev->id) + continue; + + tcpu_dev = get_cpu_device(cpu); + if (!tcpu_dev) { + dev_err(cpu_dev, "%s: failed to get cpu%d device\n", + __func__, cpu); + ret = -ENODEV; + goto put_cpu_node; + } + + /* Get OPP descriptor node */ + tmp_np = _of_get_opp_desc_node(tcpu_dev); + if (IS_ERR(tmp_np)) { + dev_err(tcpu_dev, "%s: Couldn't find opp node: %ld\n", + __func__, PTR_ERR(tmp_np)); + ret = PTR_ERR(tmp_np); + goto put_cpu_node; + } + + /* CPUs are sharing opp node */ + if (np == tmp_np) + cpumask_set_cpu(cpu, cpumask); + + of_node_put(tmp_np); + } + +put_cpu_node: + of_node_put(np); + return ret; +} +EXPORT_SYMBOL_GPL(of_get_cpus_sharing_opps); #endif diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 20324b579adc..bb52fae5b921 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -121,6 +121,10 @@ static inline struct srcu_notifier_head *dev_pm_opp_get_notifier( #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) int of_init_opp_table(struct device *dev); void of_free_opp_table(struct device *dev); +int of_cpumask_init_opp_table(cpumask_var_t cpumask); +void of_cpumask_free_opp_table(cpumask_var_t cpumask); +int of_get_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask); +int set_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask); #else static inline int of_init_opp_table(struct device *dev) { @@ -130,6 +134,25 @@ static inline int of_init_opp_table(struct device *dev) static inline void of_free_opp_table(struct device *dev) { } + +static inline int of_cpumask_init_opp_table(cpumask_var_t cpumask) +{ + return -ENOSYS; +} + +static inline void of_cpumask_free_opp_table(cpumask_var_t cpumask) +{ +} + +static inline int of_get_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask) +{ + return -ENOSYS; +} + +static inline int set_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask) +{ + return -ENOSYS; +} #endif #endif /* __LINUX_OPP_H__ */