From patchwork Tue Nov 17 22:37:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 7643191 Return-Path: X-Original-To: patchwork-linux-arm@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 5873B9F392 for ; Tue, 17 Nov 2015 22:41:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6369D20437 for ; Tue, 17 Nov 2015 22:41:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 65B8F2044B for ; Tue, 17 Nov 2015 22:41:34 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zyoub-00065y-SN; Tue, 17 Nov 2015 22:39:41 +0000 Received: from mail-pa0-x22e.google.com ([2607:f8b0:400e:c03::22e]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zyoth-0005X8-Ah for linux-arm-kernel@lists.infradead.org; Tue, 17 Nov 2015 22:38:49 +0000 Received: by padhx2 with SMTP id hx2so22129569pad.1 for ; Tue, 17 Nov 2015 14:38:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=p28PewcxxRuJ4m+ZU1at/8InTjXheBWKyA4zUHqhvIQ=; b=uUxLLJIiWqvMBwv2DicqNX9U55E/nStO05cOCVL8SGyr3cPfCe2G4xpjimeIzbj9e0 pE+NtZJUHFgxD5Mdj0uA7325c6dNWVkgo6hhRrJXksnpVmW09z9iR/0zEIJWWtwpcsSl nBCqKqkx0qRjbWZQVVia6ugvplxqnP96dN40VF8I0DSWkd7QtgDHGLo2dUUommF6x5ZN v9gyRrc1YugQswWL6Py60wlBAHI1VSxwmU/Pqi4o/P3Y59GxfOT757gkSU3sWHzjQ34c p4uR4E2vkPjxCus1Yv7IsUaTMnHXCd2Dh5cqUjhPAp7EHv6Pvx7FfYxV8PHtFT6OzSDT 9Kkw== 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=p28PewcxxRuJ4m+ZU1at/8InTjXheBWKyA4zUHqhvIQ=; b=g9+PjWLyB8F2p2DzPXRBqFw4sdY6TifTpG09bmpLBkZKQYxKxsyOylhVsuDOczLpOW H75YtGESLMWDvEtGf15HG7AMNHQWHSi2e+cEAWLsEcfGNzJEvsZQdPkcSBsYQdYWT9O9 Zqq79qGMbf913oI9+t8Bd8Uw5NobPhxW+oQt6eAlrGVohq3bgzstrfFgN8k+FRX/iXSE G/FGbH8dpMNOBYiZlHEjMsqTgVPVbdWFoxIBkqZ0i5y4dBgJ2WVLU077gZaEwpSgiAOr 4xDsgvP0K/tDQzYf7SP95U1J+MyYLxUGYSayYiOIEam/zQ+Qyfh7eZDnX5141UcRlLKo qNxQ== X-Gm-Message-State: ALoCoQkGOjWNc7dMB+w/svr1L5oXoCV+CMaietQlIw8sqDi5fBLCMK+LYV44gk2dOBqvEDzApLuy X-Received: by 10.68.241.194 with SMTP id wk2mr66401772pbc.45.1447799904321; Tue, 17 Nov 2015 14:38:24 -0800 (PST) Received: from ubuntu.localdomain ([8.42.77.226]) by smtp.gmail.com with ESMTPSA id hy1sm14875199pbb.63.2015.11.17.14.38.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Nov 2015 14:38:23 -0800 (PST) From: Lina Iyer To: ulf.hansson@linaro.org, khilman@linaro.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH RFC 04/27] PM / Domains: make governor select deepest state Date: Tue, 17 Nov 2015 15:37:28 -0700 Message-Id: <1447799871-56374-5-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1447799871-56374-1-git-send-email-lina.iyer@linaro.org> References: <1447799871-56374-1-git-send-email-lina.iyer@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151117_143845_665583_E726CAF5 X-CRM114-Status: GOOD ( 20.99 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Axel Haslam , k.kozlowski@samsung.com, lorenzo.pieralisi@arm.com, ahaslam@baylibre.com, linux-arm-msm@vger.kernel.org, sboyd@codeaurora.org, msivasub@codeaurora.org, geert@linux-m68k.org, agross@codeaurora.org, mtitinger@baylibre.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable 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, 45 insertions(+), 30 deletions(-) diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index b4984f5..ad69dc0 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c @@ -98,7 +98,8 @@ 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, + unsigned int state) { struct generic_pm_domain *genpd = pd_to_genpd(pd); struct gpd_link *link; @@ -106,31 +107,9 @@ 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; + off_on_time_ns = genpd->states[state].power_off_latency_ns + + genpd->states[state].power_on_latency_ns; - /* - * 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; min_off_time_ns = -1; /* @@ -193,8 +172,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 @@ -207,14 +184,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); + unsigned int last_state_idx = genpd->state_count - 1; + struct gpd_link *link; + bool retval = false; + unsigned 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;