From patchwork Wed Apr 29 19:10:13 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Axel Haslam X-Patchwork-Id: 6297871 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8F27D9F373 for ; Wed, 29 Apr 2015 19:11:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7DB7F201C0 for ; Wed, 29 Apr 2015 19:11:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 723B220148 for ; Wed, 29 Apr 2015 19:11:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751846AbbD2TLW (ORCPT ); Wed, 29 Apr 2015 15:11:22 -0400 Received: from mail-wi0-f169.google.com ([209.85.212.169]:33111 "EHLO mail-wi0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751564AbbD2TLW (ORCPT ); Wed, 29 Apr 2015 15:11:22 -0400 Received: by wief7 with SMTP id f7so47239915wie.0 for ; Wed, 29 Apr 2015 12:11:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rmpGlVgT7uD0umoDxGQrlZUrnwvDJi28vY9hMv8z2OE=; b=nObhJAGihxtruBkIJhEw+XPyLFX3R8aFx3dPlC8HtYeMik+NL8pRxYqGB+ZWaneuKB oJJoY7L/e3UnrkVIQkfpFYBQ55j7SWpWh63dUeZOcCSmCjYQlyT1d4NVqHluVPKXqTij drpUx2ObnImQAxcjHPfuTSv7pXGx6dbKb5+9xDH/lXIpnAjlxthHhcOA9RUEeE8LK7v5 nis+Fu06rOTsFEfiQm+b5/fH/KKPJgd7xQHCpNRMSJ4jjLUn+mXb2ykq+cEclpSuce1e LQZrweZx3MnfvAV2Bx65xo1OlNjt7H2tqIClgzPoC3GV522TVDXahQKHAX9lXFnAi4ZB wUfg== X-Gm-Message-State: ALoCoQmH6Nf3usX7yF0cWCGh9EWTfMij1plNBTGjkQ+j0PbYESRcfGNtKPFzaD9RnS9Yn9Us1CdB X-Received: by 10.194.87.38 with SMTP id u6mr1265853wjz.24.1430334681014; Wed, 29 Apr 2015 12:11:21 -0700 (PDT) Received: from axelh-ThinkPad-T440s.home (LPoitiers-656-1-62-228.w90-63.abo.wanadoo.fr. [90.63.143.228]) by mx.google.com with ESMTPSA id be3sm418738wib.21.2015.04.29.12.11.19 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 29 Apr 2015 12:11:20 -0700 (PDT) From: ahaslam@baylibre.com To: ulf.hansson@linaro.org, khilman@linaro.org, k.kozlowski.k@gmail.com, geert@linux-m68k.org, rjw@rjwysocki.net Cc: bcousson@baylibre.com, linux-pm@vger.kernel.org, Axel Haslam Subject: [PATCH/RFC v6 3/5] PM / Domains: make governor select deepest state Date: Wed, 29 Apr 2015 21:10:13 +0200 Message-Id: <1430334615-1161-4-git-send-email-ahaslam@baylibre.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1430334615-1161-1-git-send-email-ahaslam@baylibre.com> References: <1430334615-1161-1-git-send-email-ahaslam@baylibre.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Axel Haslam now that the structures of genpd can support multiple state definitions, add the logic in the governor to select the deepest possible state when powering down. For this, create the new function power_down_ok_for_state which will test if a particular state will not violate the devices and sub-domains constraints. default_power_down_ok is modified to try each state starting from the deepest until a valid state is found or there are no more states to test. the resulting state will be valid until there are latency or constraint changes, thus, we can avoid looping every power_down, and use the cached results instead. Signed-off-by: Axel Haslam --- drivers/base/power/domain_governor.c | 75 +++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index 5e63a84..144305a 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c @@ -97,7 +97,7 @@ static bool default_stop_ok(struct device *dev) * * This routine must be executed under the PM domain's lock. */ -static bool default_power_down_ok(struct dev_pm_domain *pd) +static bool power_down_ok_for_state(struct dev_pm_domain *pd, int state) { struct generic_pm_domain *genpd = pd_to_genpd(pd); struct gpd_link *link; @@ -105,31 +105,8 @@ static bool default_power_down_ok(struct dev_pm_domain *pd) s64 min_off_time_ns; s64 off_on_time_ns; - if (genpd->max_off_time_changed) { - struct gpd_link *link; - - /* - * We have to invalidate the cached results for the masters, so - * use the observation that default_power_down_ok() is not - * going to be called for any master until this instance - * returns. - */ - list_for_each_entry(link, &genpd->slave_links, slave_node) - link->master->max_off_time_changed = true; - - genpd->max_off_time_changed = false; - genpd->cached_power_down_ok = false; - genpd->max_off_time_ns = -1; - } else { - return genpd->cached_power_down_ok; - } - - /* - * Use the only available state, until multiple state support is added - * to the governor. - */ - off_on_time_ns = genpd->states[0].power_off_latency_ns + - genpd->states[0].power_on_latency_ns; + off_on_time_ns = genpd->states[state].power_off_latency_ns + + genpd->states[state].power_on_latency_ns; /* * It doesn't make sense to remove power from the domain if saving * the state of all devices in it and the power off/power on operations @@ -205,8 +182,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd) min_off_time_ns = constraint_ns; } - genpd->cached_power_down_ok = true; - /* * If the computed minimum device off time is negative, there are no * latency constraints, so the domain can spend arbitrary time in the @@ -219,14 +194,52 @@ static bool default_power_down_ok(struct dev_pm_domain *pd) * The difference between the computed minimum subdomain or device off * time and the time needed to turn the domain on is the maximum * theoretical time this domain can spend in the "off" state. - * Use the only available state, until multiple state support is added - * to the governor. */ genpd->max_off_time_ns = min_off_time_ns - - genpd->states[0].power_on_latency_ns; + genpd->states[state].power_on_latency_ns; return true; } +static bool default_power_down_ok(struct dev_pm_domain *pd) +{ + struct generic_pm_domain *genpd = pd_to_genpd(pd); + int last_state_idx = genpd->state_count - 1; + struct gpd_link *link; + bool retval = false; + int i; + + /* + * if there was no change on max_off_time, we can return the + * cached value and we dont need to find a new target_state + */ + if (!genpd->max_off_time_changed) + return genpd->cached_power_down_ok; + + /* + * We have to invalidate the cached results for the masters, so + * use the observation that default_power_down_ok() is not + * going to be called for any master until this instance + * returns. + */ + list_for_each_entry(link, &genpd->slave_links, slave_node) + link->master->max_off_time_changed = true; + + genpd->max_off_time_ns = -1; + genpd->max_off_time_changed = false; + + /* find a state to power down to, starting from the deepest */ + for (i = 0; i < genpd->state_count; i++) { + if (power_down_ok_for_state(pd, last_state_idx - i)) { + genpd->state_idx = last_state_idx - i; + retval = true; + break; + } + } + + genpd->cached_power_down_ok = retval; + return retval; +} + static bool always_on_power_down_ok(struct dev_pm_domain *domain) { return false;