From patchwork Wed Jun 21 07:10:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 9800975 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A0A5460329 for ; Wed, 21 Jun 2017 07:12:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E5842853C for ; Wed, 21 Jun 2017 07:12:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 824F328545; Wed, 21 Jun 2017 07:12:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D56DE2853C for ; Wed, 21 Jun 2017 07:12:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752633AbdFUHMU (ORCPT ); Wed, 21 Jun 2017 03:12:20 -0400 Received: from mail-pg0-f49.google.com ([74.125.83.49]:34866 "EHLO mail-pg0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752304AbdFUHLG (ORCPT ); Wed, 21 Jun 2017 03:11:06 -0400 Received: by mail-pg0-f49.google.com with SMTP id 132so39873919pgb.2 for ; Wed, 21 Jun 2017 00:11:06 -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=m+s6JsuMHct+vF461rcRxRWYhdMYL9+QiNWQa9d104E=; b=imbSJWeXXpOrDSL7/7sd7EAQelf/G2atOEpkMczUMu7IGt6SFD8xoOYDiOmr0+7rJ7 +9O99r5F9ad1odfbDRKMwe9dv29bGVVAvD1uhkLJUSgXg9JbhAgUT27OIGMKVkdC2Sxv ZeMsLUzwI1ub0/J3lEJ6vgN6SJOyWz+7Rcbnk= 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=m+s6JsuMHct+vF461rcRxRWYhdMYL9+QiNWQa9d104E=; b=o/bL13EP5g7d8/Dg4OlxvxnbNbM1omrGYGGTUlxFM7FsxYpEW5IcnrSJ/RjBQipvkP SVk7LNB/O6DAuiynwDRFCTcldTZeV/zwdPF8bqzquWgloNSTxhz/jKwuEEnzM7lqSQHN 04j+NH3BtOZ0/VOqMxQxJ9pshte++J0nrlIVAc9HF6gocAK9dH0pLIHnrTcaGDxg0xM6 MkD9NCqweCfuouxf9bpM9U8dCswdZcyJ7/SZLsBk/Vui/haov67mhNMLzbmud4eK5W+g 6EMW0E4nkM9NQU4gLNbOSk2/EffPhAWSNJ9vgDMJ04k0pzoASiIhg6LkLOaNeix0pc8Y WzNg== X-Gm-Message-State: AKS2vOyOE3uwum/Am3bXiogRlilFHhgJqQCVcOtp6r4WloSV5l+9Fh3f uIIAicVFiEJORBJL X-Received: by 10.84.128.107 with SMTP id 98mr36006840pla.285.1498029065395; Wed, 21 Jun 2017 00:11:05 -0700 (PDT) Received: from localhost ([122.172.59.234]) by smtp.gmail.com with ESMTPSA id q14sm19259895pgr.11.2017.06.21.00.11.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Jun 2017 00:11:04 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, linux-kernel@vger.kernel.org, Len Brown , Pavel Machek , Andy Gross , David Brown Subject: [PATCH V8 2/6] PM / OPP: Support updating performance state of device's power domains Date: Wed, 21 Jun 2017 12:40:49 +0530 Message-Id: X-Mailer: git-send-email 2.13.0.71.gd7076ec9c9cb 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 X-Virus-Scanned: ClamAV using ClamSMTP The genpd framework now provides an API to request device's power domain to update its performance state based on a particular target frequency for the device. Use that interface from the OPP core for devices whose power domains support performance states. Note that the current implementation is restricted to the case where the device doesn't have separate regulators for itself. We shouldn't over engineer the code before we have real use case for them. We can always come back and add more code to support such cases later on. Tested-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/base/power/opp/core.c | 48 ++++++++++++++++++++++++++++++++++++++++++- drivers/base/power/opp/opp.h | 2 ++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index a8cc14fd8ae4..ef623afcc5fd 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "opp.h" @@ -535,6 +536,42 @@ _generic_set_opp_clk_only(struct device *dev, struct clk *clk, return ret; } +static inline int +_generic_set_opp_domain(struct device *dev, struct clk *clk, + unsigned long old_freq, unsigned long freq) +{ + int ret; + + /* Scaling up? Scale domain performance state before frequency */ + if (freq > old_freq) { + ret = pm_genpd_update_performance_state(dev, freq); + if (ret) + return ret; + } + + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + if (ret) + goto restore_domain_state; + + /* Scaling down? Scale domain performance state after frequency */ + if (freq < old_freq) { + ret = pm_genpd_update_performance_state(dev, freq); + 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_domain_state: + pm_genpd_update_performance_state(dev, old_freq); + + return ret; +} + static int _generic_set_opp_regulator(const struct opp_table *opp_table, struct device *dev, unsigned long old_freq, @@ -653,7 +690,14 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) /* Only frequency scaling */ if (!opp_table->regulators) { - ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + /* + * We don't support devices with both regulator and + * domain performance-state for now. + */ + if (opp_table->genpd_performance_state) + ret = _generic_set_opp_domain(dev, clk, old_freq, freq); + else + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); } else if (!opp_table->set_opp) { ret = _generic_set_opp_regulator(opp_table, dev, old_freq, freq, IS_ERR(old_opp) ? NULL : old_opp->supplies, @@ -755,6 +799,8 @@ static struct opp_table *_allocate_opp_table(struct device *dev) ret); } + opp_table->genpd_performance_state = pm_genpd_has_performance_state(dev); + BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head); INIT_LIST_HEAD(&opp_table->opp_list); mutex_init(&opp_table->lock); diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h index 166eef990599..1efa253e1934 100644 --- a/drivers/base/power/opp/opp.h +++ b/drivers/base/power/opp/opp.h @@ -135,6 +135,7 @@ enum opp_table_access { * @clk: Device's clock handle * @regulators: Supply regulators * @regulator_count: Number of power supply regulators + * @genpd_performance_state: Device's power domain support performance state. * @set_opp: Platform specific set_opp callback * @set_opp_data: Data to be passed to set_opp callback * @dentry: debugfs dentry pointer of the real device directory (not links). @@ -170,6 +171,7 @@ struct opp_table { struct clk *clk; struct regulator **regulators; unsigned int regulator_count; + bool genpd_performance_state; int (*set_opp)(struct dev_pm_set_opp_data *data); struct dev_pm_set_opp_data *set_opp_data;