From patchwork Fri Feb 24 09:06:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 94422 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp601431qgi; Fri, 24 Feb 2017 01:14:23 -0800 (PST) X-Received: by 10.98.81.6 with SMTP id f6mr2151914pfb.180.1487927663383; Fri, 24 Feb 2017 01:14:23 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e1si6807633pga.366.2017.02.24.01.14.23; Fri, 24 Feb 2017 01:14:23 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=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 S1751057AbdBXJOQ (ORCPT + 13 others); Fri, 24 Feb 2017 04:14:16 -0500 Received: from mail-pf0-f179.google.com ([209.85.192.179]:35520 "EHLO mail-pf0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751319AbdBXJOL (ORCPT ); Fri, 24 Feb 2017 04:14:11 -0500 Received: by mail-pf0-f179.google.com with SMTP id 68so1826701pfx.2 for ; Fri, 24 Feb 2017 01:14:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=gsuCtws8MWOt/9zwkP5/cAhsYml+a2H42TdzieZaLUQ=; b=eQsb9JIouBnOinXRiKyPZwAwJcu/0gGPYH4suLTBe4RltxDGsZAtl445tE33uOo5B3 yUYfbgxBTNN7lsj3e0Hsj8jDK302Nk8sZwRjct2KGCpW7au+/iFloRg1iV/wtssAcF58 avygv8gg2hgDbm5i0mfWfr5WgEtg0IFGifmMI= 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=gsuCtws8MWOt/9zwkP5/cAhsYml+a2H42TdzieZaLUQ=; b=texgOpl+7L1VA09K27ZF3lsJGA0oBfkw968GX2IGkX6iWk4Prn7Drx2tngKa/M8jJY E7BQMFUdWMktOa98HVupi7jp3lZOKP6NP7Ztubrb+tPbaXWDIR8nYP8SR7jDUWuBMkPM H/WjocokBAgANFXrQLsFsrBcE3vfJ3BTy2jkwvGt+S4mm37Z9+ald9G5FGVcpsxyIJTr 53FPh8TIyYiJmfaTp8nkKLBJQE9aV4P9YyOCYy50zt8xpjwyPbZuyV/pVuS5xllXAZwI 3CEI4fLtWjeH1dWQysgOmLuusmqVcXQV+66sY6V5/6kArHdm13hPwM8E+uD1HOCZTaGc r7Cw== X-Gm-Message-State: AMke39lMWo0IiZ4yKJgWcEJThpf3mLBPh9Ikh2gYmMPjMzApu1AMu6IIrdoZ/czi6q810EZy X-Received: by 10.84.212.2 with SMTP id d2mr2410600pli.152.1487927224776; Fri, 24 Feb 2017 01:07:04 -0800 (PST) Received: from localhost ([122.172.165.189]) by smtp.gmail.com with ESMTPSA id t6sm14047990pgt.8.2017.02.24.01.07.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Feb 2017 01:07:04 -0800 (PST) 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, Stephen Boyd , Nishanth Menon , Vincent Guittot , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V3 6/7] PM / Domains: Allow domain performance states to be read from DT Date: Fri, 24 Feb 2017 14:36:38 +0530 Message-Id: <84786c05d90e5f3c9dc41a65fe3b8ce6052a7628.1487926924.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.1.410.g6faf27b In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org This patch allows SoC's to define domains performance states in the DT using the "performance-states" node in the domain provider node. Add API to read the performance states from DT by the domain specific drivers. Note that this information is only used by the domain specific drivers and the power domain core doesn't need to store it for now. Signed-off-by: Viresh Kumar Tested-by: Rajendra Nayak --- drivers/base/power/domain.c | 101 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 15 +++++++ 2 files changed, 116 insertions(+) -- 2.7.1.410.g6faf27b diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 202effbebfd1..a7449c492990 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2251,6 +2251,107 @@ int of_genpd_parse_idle_states(struct device_node *dn, } EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states); +/* Power domain performance state management helpers */ +static const struct of_device_id performance_state_match[] = { + { .compatible = "domain-performance-state", }, + { } +}; + +static int genpd_parse_performance_state(struct genpd_performance_state *state, + struct device_node *np) +{ + int ret; + + ret = of_property_read_u32(np, "reg", &state->performance_state); + if (ret) { + pr_err(" * %s missing reg property\n", np->full_name); + return ret; + } + + ret = of_property_read_variable_u32_array(np, "domain-microvolt", + &state->u_volt, 1, 3); + if (ret >= 0) + return 0; + + /* Property not found */ + if (ret == -EINVAL) + return 0; + + pr_err(" * %s Invalid domain-microvolt property\n", np->full_name); + return ret; +} + +/** + * of_genpd_parse_performance_states: Return array of performance states for the + * genpd. + * + * @dn: The genpd device node + * @states: The pointer to which the state array will be saved. + * @n: The count of elements in the array returned from this function. + * + * Returns the device performance states parsed from the OF node. The memory for + * the states is allocated by this function and is the responsibility of the + * caller to free the memory after use. + */ +int of_genpd_parse_performance_states(struct device_node *dn, + struct genpd_performance_state **states, int *n) +{ + struct genpd_performance_state *st; + struct device_node *perf_np, *np; + int i = 0, ret, count; + + perf_np = of_get_child_by_name(dn, "performance-states"); + if (!perf_np) { + pr_err("performance-states node not found in %s node\n", + dn->full_name); + return -ENODEV; + } + + if (!of_match_node(performance_state_match, perf_np)) { + pr_err("performance-states node found in %s node isn't compatible\n", + dn->full_name); + ret = -EINVAL; + goto put_node; + } + + count = of_get_child_count(perf_np); + if (count <= 0) { + pr_err("performance-states node found in %s node doesn't have any child nodes\n", + dn->full_name); + ret = -EINVAL; + goto put_node; + } + + st = kcalloc(count, sizeof(*st), GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto put_node; + } + + for_each_available_child_of_node(perf_np, np) { + ret = genpd_parse_performance_state(&st[i++], np); + if (ret) { + pr_err("Parsing of performance state node %s failed with err %d\n", + np->full_name, ret); + goto free_st; + } + } + + of_node_put(perf_np); + *n = count; + *states = st; + + return 0; + +free_st: + kfree(st); +put_node: + of_node_put(perf_np); + + return ret; +} +EXPORT_SYMBOL_GPL(of_genpd_parse_performance_states); + #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */ diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 83795935709e..7659ce3968c7 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -44,6 +44,13 @@ struct genpd_power_state { struct fwnode_handle *fwnode; }; +struct genpd_performance_state { + unsigned int performance_state; + unsigned int u_volt; + unsigned int u_volt_min; + unsigned int u_volt_max; +}; + struct genpd_lock_ops; struct generic_pm_domain { @@ -226,6 +233,8 @@ extern int of_genpd_add_subdomain(struct of_phandle_args *parent, extern struct generic_pm_domain *of_genpd_remove_last(struct device_node *np); extern int of_genpd_parse_idle_states(struct device_node *dn, struct genpd_power_state **states, int *n); +extern int of_genpd_parse_performance_states(struct device_node *dn, + struct genpd_performance_state **states, int *n); int genpd_dev_pm_attach(struct device *dev); #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */ @@ -261,6 +270,12 @@ static inline int of_genpd_parse_idle_states(struct device_node *dn, return -ENODEV; } +static inline int of_genpd_parse_performance_states(struct device_node *dn, + struct genpd_performance_state **states, int *n) +{ + return -ENODEV; +} + static inline int genpd_dev_pm_attach(struct device *dev) { return -ENODEV;