From patchwork Fri Feb 17 09:55:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 94134 Delivered-To: patches@linaro.org Received: by 10.140.20.99 with SMTP id 90csp89032qgi; Fri, 17 Feb 2017 01:55:31 -0800 (PST) X-Received: by 10.46.22.81 with SMTP id 17mr1821135ljw.13.1487325331699; Fri, 17 Feb 2017 01:55:31 -0800 (PST) Return-Path: Received: from mail-lf0-x235.google.com (mail-lf0-x235.google.com. [2a00:1450:4010:c07::235]) by mx.google.com with ESMTPS id i30si4742880ljb.119.2017.02.17.01.55.31 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Feb 2017 01:55:31 -0800 (PST) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c07::235 as permitted sender) client-ip=2a00:1450:4010:c07::235; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c07::235 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by mail-lf0-x235.google.com with SMTP id x1so20213445lff.0 for ; Fri, 17 Feb 2017 01:55:31 -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; bh=6RUmNvLGKADJ18DWAOm4UuDsfpio7yRChXph+k/cSCs=; b=gGSK6JQ/345OI7oogG/l8eWbGGmzZDICThRVP5dqCTFWLzGLim/S0qxbMAWkyknkMc pYXee+FyUo52XnkfCPxm3AiJKjQvoYUANX8nuV3J7kyY2r4c89h3UDt8OAy4qpJPNTac q9aZrQxj/0EUBLliekPBsVQNTKXzn0IpOhFDA= 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; bh=6RUmNvLGKADJ18DWAOm4UuDsfpio7yRChXph+k/cSCs=; b=qm6ylPV2iBUgzkHaqC4kS//SkkVxlk0Jp4j3j9WTBwiFqNDJZ4g0xde6G610gp3Eu0 uEZI6h0U9PFGgOaZyxc67gkhrmWqTbWYVYbGyUh2jAD+HMZAMTNGMJWqeYpS+hWL3ND+ pgjQgNUxLblflLum45C7CLL69SJ/aMpaeL2KHwdJ62kFBNkSYSeofE2AsOG0rTvEyKva Q3OTAwBpxpBmgxztFjFzzbqunwPamHzX7qOi/KD2ErnWRB6r2pt0CrO0TXnmUrdYsxUB w3WZ3DExddt7sgWGAHCHFF9O3I4qLg/VsgYISavTweSKus/u1vBsD3MKLduKH5iAM+6E TdeQ== X-Gm-Message-State: AMke39kb4VS/a4nxxFoUTacSN6EP9JsCcXhPaUj1uqc3OxgvuXIKBAGP9DFzKS35RbSuS3ZEYK4= X-Received: by 10.25.29.195 with SMTP id d186mr2054046lfd.72.1487325331243; Fri, 17 Feb 2017 01:55:31 -0800 (PST) Return-Path: Received: from localhost.localdomain (h-155-4-221-67.na.cust.bahnhof.se. [155.4.221.67]) by smtp.gmail.com with ESMTPSA id f133sm2372773lfg.32.2017.02.17.01.55.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 17 Feb 2017 01:55:30 -0800 (PST) From: Ulf Hansson To: "Rafael J. Wysocki" , Ulf Hansson , linux-pm@vger.kernel.org Cc: Len Brown , Pavel Machek , Kevin Hilman , Geert Uytterhoeven , Lina Iyer , Jon Hunter , Marek Szyprowski Subject: [PATCH 1/3] PM / Domains: Move genpd_power_off() above genpd_power_on() Date: Fri, 17 Feb 2017 10:55:23 +0100 Message-Id: <1487325325-18212-2-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1487325325-18212-1-git-send-email-ulf.hansson@linaro.org> References: <1487325325-18212-1-git-send-email-ulf.hansson@linaro.org> Following changes in genpd_power_on() makes it invoke genpd_power_off(). To enable these changes and avoiding to declare genpd_power_off(), let's move its implementation above genpd_power_on(). In this way, following changes should become easier to review. Signed-off-by: Ulf Hansson --- drivers/base/power/domain.c | 162 ++++++++++++++++++++++---------------------- 1 file changed, 81 insertions(+), 81 deletions(-) -- 1.9.1 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 3a75fb1..3dc44f2 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -274,6 +274,87 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) } /** + * genpd_power_off - Remove power from a given PM domain. + * @genpd: PM domain to power down. + * @is_async: PM domain is powered down from a scheduled work + * + * If all of the @genpd's devices have been suspended and all of its subdomains + * have been powered down, remove power from @genpd. + */ +static int genpd_power_off(struct generic_pm_domain *genpd, bool is_async) +{ + struct pm_domain_data *pdd; + struct gpd_link *link; + unsigned int not_suspended = 0; + + /* + * Do not try to power off the domain in the following situations: + * (1) The domain is already in the "power off" state. + * (2) System suspend is in progress. + */ + if (genpd->status == GPD_STATE_POWER_OFF + || genpd->prepared_count > 0) + return 0; + + if (atomic_read(&genpd->sd_count) > 0) + return -EBUSY; + + list_for_each_entry(pdd, &genpd->dev_list, list_node) { + enum pm_qos_flags_status stat; + + stat = dev_pm_qos_flags(pdd->dev, + PM_QOS_FLAG_NO_POWER_OFF + | PM_QOS_FLAG_REMOTE_WAKEUP); + if (stat > PM_QOS_FLAGS_NONE) + return -EBUSY; + + /* + * Do not allow PM domain to be powered off, when an IRQ safe + * device is part of a non-IRQ safe domain. + */ + if (!pm_runtime_suspended(pdd->dev) || + irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd)) + not_suspended++; + } + + if (not_suspended > 1 || (not_suspended == 1 && is_async)) + return -EBUSY; + + if (genpd->gov && genpd->gov->power_down_ok) { + if (!genpd->gov->power_down_ok(&genpd->domain)) + return -EAGAIN; + } + + if (genpd->power_off) { + int ret; + + if (atomic_read(&genpd->sd_count) > 0) + return -EBUSY; + + /* + * If sd_count > 0 at this point, one of the subdomains hasn't + * managed to call genpd_power_on() for the master yet after + * incrementing it. In that case genpd_power_on() will wait + * for us to drop the lock, so we can call .power_off() and let + * the genpd_power_on() restore power for us (this shouldn't + * happen very often). + */ + ret = _genpd_power_off(genpd, true); + if (ret) + return ret; + } + + genpd->status = GPD_STATE_POWER_OFF; + + list_for_each_entry(link, &genpd->slave_links, slave_node) { + genpd_sd_counter_dec(link->master); + genpd_queue_power_off_work(link->master); + } + + return 0; +} + +/** * genpd_power_on - Restore power to a given PM domain and its masters. * @genpd: PM domain to power up. * @depth: nesting count for lockdep. @@ -368,87 +449,6 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, } /** - * genpd_power_off - Remove power from a given PM domain. - * @genpd: PM domain to power down. - * @is_async: PM domain is powered down from a scheduled work - * - * If all of the @genpd's devices have been suspended and all of its subdomains - * have been powered down, remove power from @genpd. - */ -static int genpd_power_off(struct generic_pm_domain *genpd, bool is_async) -{ - struct pm_domain_data *pdd; - struct gpd_link *link; - unsigned int not_suspended = 0; - - /* - * Do not try to power off the domain in the following situations: - * (1) The domain is already in the "power off" state. - * (2) System suspend is in progress. - */ - if (genpd->status == GPD_STATE_POWER_OFF - || genpd->prepared_count > 0) - return 0; - - if (atomic_read(&genpd->sd_count) > 0) - return -EBUSY; - - list_for_each_entry(pdd, &genpd->dev_list, list_node) { - enum pm_qos_flags_status stat; - - stat = dev_pm_qos_flags(pdd->dev, - PM_QOS_FLAG_NO_POWER_OFF - | PM_QOS_FLAG_REMOTE_WAKEUP); - if (stat > PM_QOS_FLAGS_NONE) - return -EBUSY; - - /* - * Do not allow PM domain to be powered off, when an IRQ safe - * device is part of a non-IRQ safe domain. - */ - if (!pm_runtime_suspended(pdd->dev) || - irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd)) - not_suspended++; - } - - if (not_suspended > 1 || (not_suspended == 1 && is_async)) - return -EBUSY; - - if (genpd->gov && genpd->gov->power_down_ok) { - if (!genpd->gov->power_down_ok(&genpd->domain)) - return -EAGAIN; - } - - if (genpd->power_off) { - int ret; - - if (atomic_read(&genpd->sd_count) > 0) - return -EBUSY; - - /* - * If sd_count > 0 at this point, one of the subdomains hasn't - * managed to call genpd_power_on() for the master yet after - * incrementing it. In that case genpd_power_on() will wait - * for us to drop the lock, so we can call .power_off() and let - * the genpd_power_on() restore power for us (this shouldn't - * happen very often). - */ - ret = _genpd_power_off(genpd, true); - if (ret) - return ret; - } - - genpd->status = GPD_STATE_POWER_OFF; - - list_for_each_entry(link, &genpd->slave_links, slave_node) { - genpd_sd_counter_dec(link->master); - genpd_queue_power_off_work(link->master); - } - - return 0; -} - -/** * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0. * @work: Work structure used for scheduling the execution of this function. */