From patchwork Wed Apr 8 15:42:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Axel Haslam X-Patchwork-Id: 6181071 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9B41BBF4A6 for ; Wed, 8 Apr 2015 15:42:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9FFD920357 for ; Wed, 8 Apr 2015 15:42:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9653F2037A for ; Wed, 8 Apr 2015 15:42:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753343AbbDHPm2 (ORCPT ); Wed, 8 Apr 2015 11:42:28 -0400 Received: from mail-wi0-f180.google.com ([209.85.212.180]:38022 "EHLO mail-wi0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753535AbbDHPm1 (ORCPT ); Wed, 8 Apr 2015 11:42:27 -0400 Received: by wiun10 with SMTP id n10so63558177wiu.1 for ; Wed, 08 Apr 2015 08:42:26 -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=RGsD/X22sD2XnyFm7QIyxV4oUfFNoPMSdk+JU0Fh9Mo=; b=KxQPAmk/xnK2HlCodP2ty7TByZkkjHZcrZOY8Qgd+i6dZDz8K9NET/UEWZWJxXVfJO MUUKl0fsj+oQ8D8sRQHCJRC0egQJRMSSrzh5b5KrNRpiOEJouPFa1429rRMMSRqqXGd/ sKZ66LYJ75XlUnGBuNQvd4k+aSo0iey9RXt6vlEqWzrzF56p4etk7nJLgKmohyXTRFtR MEikUaE4ZqDLz3hi6AOp0mF2/cGLyvE8++ZFg025F4/Snsu+XtE+45jDEdc0BW8Jn0Ps HjE8LW8LW7bugYtte436xs/j607Y96nMydFJ3io6qPJvQrRyHDcQyxY8J2yHa/OC4pAY huEw== X-Gm-Message-State: ALoCoQlAsrnY7wA4q5ebV4Pq9AnOrTAzfbOuRWdzZPd7BmWakX/KZ0rUWcAc02DidMiUFOByUAkB X-Received: by 10.180.105.136 with SMTP id gm8mr15746085wib.13.1428507746052; Wed, 08 Apr 2015 08:42:26 -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 k6sm16213978wia.6.2015.04.08.08.42.24 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 08 Apr 2015 08:42:25 -0700 (PDT) From: ahaslam@baylibre.com To: khilman@linaro.org, rjw@rjwysocki.net, linux-pm@vger.kernel.org Cc: bcousson@baylibre.com, Axel Haslam Subject: [PATCH 2/2] [RFC] PM / Domains: select deepest state Date: Wed, 8 Apr 2015 17:42:05 +0200 Message-Id: <1428507725-12205-3-git-send-email-ahaslam@baylibre.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1428507725-12205-1-git-send-email-ahaslam@baylibre.com> References: <1428507725-12205-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 subdomains 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 target state will be valid until 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 | 65 +++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index deaaa76..a36c387 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 generic_pm_domain_data *gpd_data; @@ -105,26 +105,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd) struct pm_domain_data *pdd; s64 min_off_time_ns; s64 off_on_time_ns; - int state = 0; - - 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; - } off_on_time_ns = genpd->states[state].power_off_latency_ns + genpd->states[state].power_on_latency_ns; @@ -204,8 +184,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 @@ -224,6 +202,47 @@ static bool default_power_down_ok(struct dev_pm_domain *pd) 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; + genpd->target_state = 0; + + /* 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->target_state = 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;