From patchwork Wed Aug 19 10:40:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 247943 Delivered-To: patches@linaro.org Received: by 2002:a05:6e02:522:0:0:0:0 with SMTP id h2csp348133ils; Wed, 19 Aug 2020 03:41:25 -0700 (PDT) X-Received: by 2002:a2e:b8c2:: with SMTP id s2mr12361549ljp.179.1597833685532; Wed, 19 Aug 2020 03:41:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597833685; cv=none; d=google.com; s=arc-20160816; b=Zbstdm0Om4F97ECRLFqyh1arhhF/nlshhgTOWrCuOx+M715/X0B+anqG3FsbpvT4v/ 66RH1upBntt0gk2CDgoWbflJ1GBYBzm7Tk8Est3DiFCWjn5rIrhuJavCA9asIpMMM4vB w8i93il2AYHNZs7YFmMt0TjSwHKAVajkpO6B/qlaAWlFEvzdiONBBQff+B88XwPM7o1i cDdRvwqb8sMPthzIE348QjzhuHbHy8tjMDLhHDVzt9wsfW8S4CKHf0XXUeLPrIFzyBmq h5AhHqfNk+oLaSE1IScDO9nHxYK6C6KA+oTaUUwtZbvVq9qup03bbsPMzxKZlx8tCcL4 kGRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=KZ6+UHIbVBHDAWxAlM3ATUhUkPp750TK89JntGb8KGk=; b=W4jrY9ph6uuV3ThXbnYEQ75YBIzijwx4/E8ZogPbrbVwyGJ6gEi9uHnjlu1bH1XzvH eAys4xxXpl5FX9+wUNXBsJJ2xM5V1FESliRHDh4tUglnR7ubcgzkqDeJJuxUyU9/5trM IqtyqPI+SOqQGsIRMv30QBZ8208BNS3PHxxkJsuWJlPI6ibcBZUbdAqDnkNJ7rdXiQpk f2Py4dhedcUE0Swm8K/uNaOoLD5HUmBO2WL71/3lAZ9aWqTXOaIkt0L7+ln9+gwX79t6 Ub26DGPQ+YuiJUiAby4STJiWnncny5c9EvajtEla4SM2+0wwqp8XWBJFd/Lk1OsbILZI z/QA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=eqHxl6sg; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id m7sor10522795ljg.61.2020.08.19.03.41.25 for (Google Transport Security); Wed, 19 Aug 2020 03:41:25 -0700 (PDT) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=eqHxl6sg; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 :mime-version:content-transfer-encoding; bh=KZ6+UHIbVBHDAWxAlM3ATUhUkPp750TK89JntGb8KGk=; b=eqHxl6sgWAC7D+BQpSMtUxV0B7StzvgVfcDyTEA08E6mtrZB5/LfbrXlTT2vvCLyUb fish0uKFHQKEENO9VwlCA7jhMcyySws72fxlUqqtcbVt6tkWrF/2ngREysTpwzU5EyHe uxJHcmLtFlviFx3w5A489rwULsNuGwABe34RCJRBXiJUDAxMHDhtctkQS9IzVoIx0ZuT 7GvpW6ODn619eV2y+08qOheaYpxFPZ1rIHwqEIHaaQARH/d/mETMjut5ZXK7q8neSM8r sCw+ZaAdpkCNVqo2qwJK17kE3TtOxkty4/eqwJmXsfVBto5W0w5ZZ021aWMYRxJAFcSu +Yzw== 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:mime-version:content-transfer-encoding; bh=KZ6+UHIbVBHDAWxAlM3ATUhUkPp750TK89JntGb8KGk=; b=fnrmPK4qZ8anwPW4jNCoPjTy21yGtzlNdtiw4BYJct1UBwUE54PqUV/ioDh9MRfNJF rJzo2Ijqn6Lswo6sPGOEtAH55MuPdRgh4W3iMsESce7Xgoy+vNeFgyEtWB+g1ZVrqpjz oeOdvDBE6t8U1tLPq/+MZd7smUH3HL52ufZtf4bWo0aipDJ9/CLQeRLxiXNXEqf4DTb5 LO7bezLhFX016EZ+xAdILOhGHmpcUbTv/9BjqPuvYVQeAJKD5M4vOgSpRgIbXdU8Z+u/ PccopDeMgcBqjR/Th5IYjDU39+vDvgaEiMW6n+QlBFWqHV7UNkY3Cmfi2IfWodxI0CbL dI9A== X-Gm-Message-State: AOAM5302jNx/ejMY9/DsbeJBiCUB1/TdpY27DWo7WyS3UtGufTQVJ+4M bvH/vH7CC+5wrmfGzaa0tp8gJutI X-Google-Smtp-Source: ABdhPJxlSNzQXvCTCZGYjwTP2UKOt/Xj4UpdpG5DKosqqiXBiTTdOnhx0Q72Y0Z1Da5Z0IHl63f5AA== X-Received: by 2002:a2e:3312:: with SMTP id d18mr11415054ljc.222.1597833684915; Wed, 19 Aug 2020 03:41:24 -0700 (PDT) Return-Path: Received: from localhost.localdomain (h-98-128-180-79.NA.cust.bahnhof.se. [98.128.180.79]) by smtp.gmail.com with ESMTPSA id y13sm6534822ljd.19.2020.08.19.03.41.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Aug 2020 03:41:23 -0700 (PDT) From: Ulf Hansson To: "Rafael J . Wysocki" , Kevin Hilman , linux-pm@vger.kernel.org Cc: Sudeep Holla , Lorenzo Pieralisi , Daniel Lezcano , Lina Iyer , Lukasz Luba , Vincent Guittot , Stephen Boyd , Bjorn Andersson , Benjamin Gaignard , Ulf Hansson , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] PM / Domains: Rename power state enums for genpd Date: Wed, 19 Aug 2020 12:40:55 +0200 Message-Id: <20200819104057.318230-2-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200819104057.318230-1-ulf.hansson@linaro.org> References: <20200819104057.318230-1-ulf.hansson@linaro.org> MIME-Version: 1.0 To clarify the code a bit, let's rename GPD_STATE_ACTIVE into GENPD_STATE_ON and GPD_STATE_POWER_OFF to GENPD_STATE_OFF. Signed-off-by: Ulf Hansson --- drivers/base/power/domain.c | 32 ++++++++++++++++---------------- include/linux/pm_domain.h | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) -- 2.25.1 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 2cb5e04cf86c..2ea99032b658 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -123,7 +123,7 @@ static const struct genpd_lock_ops genpd_spin_ops = { #define genpd_lock_interruptible(p) p->lock_ops->lock_interruptible(p) #define genpd_unlock(p) p->lock_ops->unlock(p) -#define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE) +#define genpd_status_on(genpd) (genpd->status == GENPD_STATE_ON) #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE) #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON) #define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP) @@ -222,7 +222,7 @@ static void genpd_update_accounting(struct generic_pm_domain *genpd) * out of off and so update the idle time and vice * versa. */ - if (genpd->status == GPD_STATE_ACTIVE) { + if (genpd->status == GENPD_STATE_ON) { int state_idx = genpd->state_idx; genpd->states[state_idx].idle_time = @@ -563,7 +563,7 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, return ret; } - genpd->status = GPD_STATE_POWER_OFF; + genpd->status = GENPD_STATE_OFF; genpd_update_accounting(genpd); list_for_each_entry(link, &genpd->child_links, child_node) { @@ -616,7 +616,7 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) if (ret) goto err; - genpd->status = GPD_STATE_ACTIVE; + genpd->status = GENPD_STATE_ON; genpd_update_accounting(genpd); return 0; @@ -961,7 +961,7 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, if (_genpd_power_off(genpd, false)) return; - genpd->status = GPD_STATE_POWER_OFF; + genpd->status = GENPD_STATE_OFF; list_for_each_entry(link, &genpd->child_links, child_node) { genpd_sd_counter_dec(link->parent); @@ -1008,7 +1008,7 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock, _genpd_power_on(genpd, false); - genpd->status = GPD_STATE_ACTIVE; + genpd->status = GENPD_STATE_ON; } /** @@ -1287,7 +1287,7 @@ static int genpd_restore_noirq(struct device *dev) * so make it appear as powered off to genpd_sync_power_on(), * so that it tries to power it on in case it was really off. */ - genpd->status = GPD_STATE_POWER_OFF; + genpd->status = GENPD_STATE_OFF; genpd_sync_power_on(genpd, true, 0); genpd_unlock(genpd); @@ -1777,7 +1777,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd, genpd->gov = gov; INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); atomic_set(&genpd->sd_count, 0); - genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE; + genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON; genpd->device_count = 0; genpd->max_off_time_ns = -1; genpd->max_off_time_changed = true; @@ -2802,8 +2802,8 @@ static int genpd_summary_one(struct seq_file *s, struct generic_pm_domain *genpd) { static const char * const status_lookup[] = { - [GPD_STATE_ACTIVE] = "on", - [GPD_STATE_POWER_OFF] = "off" + [GENPD_STATE_ON] = "on", + [GENPD_STATE_OFF] = "off" }; struct pm_domain_data *pm_data; const char *kobj_path; @@ -2881,8 +2881,8 @@ static int summary_show(struct seq_file *s, void *data) static int status_show(struct seq_file *s, void *data) { static const char * const status_lookup[] = { - [GPD_STATE_ACTIVE] = "on", - [GPD_STATE_POWER_OFF] = "off" + [GENPD_STATE_ON] = "on", + [GENPD_STATE_OFF] = "off" }; struct generic_pm_domain *genpd = s->private; @@ -2895,7 +2895,7 @@ static int status_show(struct seq_file *s, void *data) if (WARN_ON_ONCE(genpd->status >= ARRAY_SIZE(status_lookup))) goto exit; - if (genpd->status == GPD_STATE_POWER_OFF) + if (genpd->status == GENPD_STATE_OFF) seq_printf(s, "%s-%u\n", status_lookup[genpd->status], genpd->state_idx); else @@ -2938,7 +2938,7 @@ static int idle_states_show(struct seq_file *s, void *data) ktime_t delta = 0; s64 msecs; - if ((genpd->status == GPD_STATE_POWER_OFF) && + if ((genpd->status == GENPD_STATE_OFF) && (genpd->state_idx == i)) delta = ktime_sub(ktime_get(), genpd->accounting_time); @@ -2961,7 +2961,7 @@ static int active_time_show(struct seq_file *s, void *data) if (ret) return -ERESTARTSYS; - if (genpd->status == GPD_STATE_ACTIVE) + if (genpd->status == GENPD_STATE_ON) delta = ktime_sub(ktime_get(), genpd->accounting_time); seq_printf(s, "%lld ms\n", ktime_to_ms( @@ -2984,7 +2984,7 @@ static int total_idle_time_show(struct seq_file *s, void *data) for (i = 0; i < genpd->state_count; i++) { - if ((genpd->status == GPD_STATE_POWER_OFF) && + if ((genpd->status == GENPD_STATE_OFF) && (genpd->state_idx == i)) delta = ktime_sub(ktime_get(), genpd->accounting_time); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index ee11502a575b..66f3c5d64d81 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -64,8 +64,8 @@ #define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5) enum gpd_status { - GPD_STATE_ACTIVE = 0, /* PM domain is active */ - GPD_STATE_POWER_OFF, /* PM domain is off */ + GENPD_STATE_ON = 0, /* PM domain is on */ + GENPD_STATE_OFF, /* PM domain is off */ }; struct dev_power_governor { From patchwork Wed Aug 19 10:40:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 247944 Delivered-To: patches@linaro.org Received: by 2002:a05:6e02:522:0:0:0:0 with SMTP id h2csp348145ils; Wed, 19 Aug 2020 03:41:27 -0700 (PDT) X-Received: by 2002:a2e:321a:: with SMTP id y26mr11178190ljy.388.1597833687044; Wed, 19 Aug 2020 03:41:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597833687; cv=none; d=google.com; s=arc-20160816; b=uhOzCl2n5I9Un/Y2uXY4VnzOqYjH07iIY7L8h/u4HhTVIagx4MP14UzwaWDELERWLl GHC/a4vFGzxoYg05zwaFXZJ5C4hjF4DeM9jnKHvN6fjru/6t17f6qA8IG/xv8HTbUFSv BPf/kfLOp3uNsBSL2pI7RJRP8qROt7f/PyPaE13+Wr62Sl+sVaLdag63XWuf2TRjkfol X2j9uzQqoynGwBXdIeK0B8xGc7YLYSBKHxyPZEWvYYEjCJBfqNKHkiraXXerXElxQfdP 2AE6Hn/tlrhXdHZX53EOcL+OjoBBHPKkhW2GNI2aVb+nYNpskSwe8Dtqw7ALM4r1cnGu Q+BA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=6AfisJdiJUtL2PXoC9gz6YzWImXc+sSWUPeXDWlUbHI=; b=ettb+qj7GN/W9rxFkMKEdv9N8XyuvXpLPxfIhzh7bLTJtGcu/X7iC4DPIgM3QSXMMA +QW5EjEFXkPPqa/THpa3XNw5lheM/VxDQeLth9gofSwreUWYEtPugZpTqpG6jlHSEUeC NmK7RuX0frCq9AWfVt67YL9Z1LEVl1oYIwGaSrhNKljKFarpfOd1iBaHJtNxnL1I38YU LCCKSYXRRpdiz8gBGdiFfgpin2sKLmJbdCN0DB+yQjm92QXruE0pvwBV3mm5LM6vgYIc VZobGVO4zNYQ92bDIvO7oQYJ/KuiDJAEQg9DWl+fzxvfk3Z4k+mhhUVaJZwwmcTHGZBM oXsw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FDmP20zS; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id i20sor5469589lfi.14.2020.08.19.03.41.26 for (Google Transport Security); Wed, 19 Aug 2020 03:41:27 -0700 (PDT) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FDmP20zS; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 :mime-version:content-transfer-encoding; bh=6AfisJdiJUtL2PXoC9gz6YzWImXc+sSWUPeXDWlUbHI=; b=FDmP20zScS9Lp7NKqKhHNqZWR3liO/ZnL7w+TyagTnjUgOnvbWYGP2viYAlT07dtf9 tzK3xWyFoLgHKBhueu6FnaKkhTojI9LUqKWVL8IsUd5nmJLNd8CZzvGMPbbwzwm9iW8z O087glIP1Z7zeJKFKxZwBIOC3bJlf/NudjYGq4tcFESU3ROywqhOTSrQ83v+uqDEZe3k D59T/x538Q36zAC1Q7SAWFT0byDw1FjFnmfs484p02nBj2CKmFOizB29nOJ4Zm1GroJr xiorhamZgN4JM/GM+2+jfuXcACWB3Wj12pb9iBlAZE4okK13c3vLRwcrOb8Z6+36YDAQ 0boA== 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:mime-version:content-transfer-encoding; bh=6AfisJdiJUtL2PXoC9gz6YzWImXc+sSWUPeXDWlUbHI=; b=OPtMuLqHezHYERWl4OL6k0wyW+ywZcNizYkb8IBhhWOPkvXCeZSXNmLohX6rqY/Cfc zP6s2LL7261sjPqgNiR7IZcyZhiylFzKdinuASHZZK7CVIVbm2G8+yW06FoyHikQwSFJ zjLbo/62WLNRlJwOR0ihe6ephXr7xYTiYpMIpWV9kNH5WJR6xFBgAJVEro0rv9BDCBwz MDw1yTMP7S2+zyt8o0CL6zSIsg8DwnQqK4hnh/diElkykW4HI4YP36tT4rKTrt/d4Ngg 50YQSXz7CruXS4HlRHK7EpLdFC9MIyGQSIqDszVbv4hKuctaMHRoJBCEno6xJ1jDi0kQ L5Bw== X-Gm-Message-State: AOAM531Tjo34h8+Eh6XOjdhjWyYQEl1C3PUtNPhHAazCzqKIRs3RjXLG m88YQG5kaIzzva9C6QthIbbZOVKMI0KBj3H6zzU= X-Google-Smtp-Source: ABdhPJygHSyy3z4agvjAxmYVV4QRQjCkH5wyaAw1ePZcKIW+aup9SWYdYaWUsgZtrrWbS9OSPi9VCQ== X-Received: by 2002:a19:cb53:: with SMTP id b80mr11846376lfg.77.1597833686628; Wed, 19 Aug 2020 03:41:26 -0700 (PDT) Return-Path: Received: from localhost.localdomain (h-98-128-180-79.NA.cust.bahnhof.se. [98.128.180.79]) by smtp.gmail.com with ESMTPSA id y13sm6534822ljd.19.2020.08.19.03.41.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Aug 2020 03:41:25 -0700 (PDT) From: Ulf Hansson To: "Rafael J . Wysocki" , Kevin Hilman , linux-pm@vger.kernel.org Cc: Sudeep Holla , Lorenzo Pieralisi , Daniel Lezcano , Lina Iyer , Lukasz Luba , Vincent Guittot , Stephen Boyd , Bjorn Andersson , Benjamin Gaignard , Ulf Hansson , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/3] PM / Domains: Allow to abort power off when no ->power_off() callback Date: Wed, 19 Aug 2020 12:40:56 +0200 Message-Id: <20200819104057.318230-3-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200819104057.318230-1-ulf.hansson@linaro.org> References: <20200819104057.318230-1-ulf.hansson@linaro.org> MIME-Version: 1.0 In genpd_power_off() we may decide to abort the power off of the PM domain, even beyond the point when the governor would accept it. The abort is done if it turns out that a child domain has been requested to be powered on, which means it's waiting for the lock of the parent to be released. However, the abort is currently only considered if the genpd in question has a ->power_off() callback assigned. This is unnecessary limiting, especially if the genpd would have a parent of its own. Let's remove the limitation and make the behaviour consistent. Signed-off-by: Ulf Hansson --- drivers/base/power/domain.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) -- 2.25.1 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 2ea99032b658..4b787e1ff188 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -497,6 +497,7 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, struct pm_domain_data *pdd; struct gpd_link *link; unsigned int not_suspended = 0; + int ret; /* * Do not try to power off the domain in the following situations: @@ -544,24 +545,13 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, if (!genpd->gov) genpd->state_idx = 0; - if (genpd->power_off) { - int ret; - - if (atomic_read(&genpd->sd_count) > 0) - return -EBUSY; + /* Don't power off, if a child domain is waiting to power on. */ + 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 parent 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; - } + ret = _genpd_power_off(genpd, true); + if (ret) + return ret; genpd->status = GENPD_STATE_OFF; genpd_update_accounting(genpd); From patchwork Wed Aug 19 10:40:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 247945 Delivered-To: patches@linaro.org Received: by 2002:a05:6e02:522:0:0:0:0 with SMTP id h2csp348156ils; Wed, 19 Aug 2020 03:41:28 -0700 (PDT) X-Received: by 2002:a2e:1302:: with SMTP id 2mr12941046ljt.303.1597833688752; Wed, 19 Aug 2020 03:41:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597833688; cv=none; d=google.com; s=arc-20160816; b=oNhr0q2jMWM0jfZemuVAZmyCW6KMEwdSIu342SRyRDvP+LGQggEx5Q8dNrV8NevYyK +uYKY7XY35LzozVA5EDSjY38B+/ry8exSGEl3Et4bEWhOLaIllAnamKahTVxl4dy66JU CkFQaN3ER9w07ol43HGvBO7egUyFGqjmYudUo4a46SXN47W4rvJmnO5iwMzwBdX581Ds WBU8VW0A85RqY/QkEaBYwdxpQ0AcMBfwqTznv4OkSKSsdbj6Xepbd/OVI8pBsP1tSM+i QD+mFfkjYCE31IPGFWsWOSBj3LDumj4SAl8FGtpDhNJjRWD2GCVSCHxje3WsjrCCUPCS lEmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=9RMBVqpjUp8MGjjw2ybmtBG8DxRTJjmlR17pvN82CuE=; b=ag5h4RvAxV1rkoZGh6G/Z1gVJdCVgQ2r670VJUiHkZJU8+to9zyVUZXmUwLGZRk9tT zU5BqIoM/EtLliAvagY8uCSjmZ0w78ZrzRKXn4CQmRigzlJ/qSgRYbkEZ/36QYCFM5yv eYj59/LpfMqfL9v/2P8QEKtO378HYAs7xC9YHEhNpdHzBT4W0zwGkdgiMtjJ8E9uhlgz y+7MFQo+Gh7gWdg3aYLshaOc8p+Q/WBGYVmzvpuq1FZvMR8js7W+kX4a9qrdBnc6oKQH cSs+CtihrVQouks+m26B/QDLtwWISaeuVkB2B07Wzswk4YhMMCVR7k1xXX4EMfIguNBi zeTA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VjJV+eVo; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id e4sor10715741ljo.42.2020.08.19.03.41.28 for (Google Transport Security); Wed, 19 Aug 2020 03:41:28 -0700 (PDT) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VjJV+eVo; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 :mime-version:content-transfer-encoding; bh=9RMBVqpjUp8MGjjw2ybmtBG8DxRTJjmlR17pvN82CuE=; b=VjJV+eVo8zaCYQaKgtgJ0pUzGTNQijAvgEEQ6SitMzyLgqskQq3J0ZhTOPboxiT83f DuCyLIadompPwaiq7TB+9l5MNiaM6p1Kw4io95V0RsgHMalVKgnTAoj7f4d8ML27u8Pz xWHqcSkbsEEXewcTWfsH9KdRazv403T9IWUZqYMDoHdpnHE21tvKLs71/9dTkMBB6Hcd Ct5yHtcrVHOVQO0KtalxoHYrlHTksbPN6iKwSJBQFnJ+5l7KI0tQDAl74Z+f009qIuVG lZ97CSGxeuCpXGnYwGWG/yniCkiytwIGjIavaqgtjp/xnFE+/4V0oCdugxjv6LwF3hde /KeA== 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:mime-version:content-transfer-encoding; bh=9RMBVqpjUp8MGjjw2ybmtBG8DxRTJjmlR17pvN82CuE=; b=IxzFQWuR3w0BkQbJmoMW6VBrPizNU7zzUMNziyNIHUq3aEp5D0x04tW//sgdJEoS3R rN6Q/oqK5EFQ7Di2WtkCEAU0NdUULRRJDtfeufN4zPPv0emmadhZKAPB11M+l3KCVgzh jjOw/kROLTufQQUQspioip2zQLLySPMbq5yxCljcev+d1f8ZDfL3g5tlz0ShUu2utlvi M/j+GdbNW2QxU4ckbMPL+I+VPBNeg7zVHm+vLV1VdL/vcLSM/kzPHrjyZkgncl4WVvMk QhEjH/bIkBASNFBIX0O2aRmqo4emtOMn/lSK38CLN2ChTcpL/qiE8c39xmQquHuZTDZJ vYHQ== X-Gm-Message-State: AOAM533J+s/0SjFB9booQWc5NK2fP+JtAA4dP/I4uG8X3WQgvoGpU+Xh P1foPRQjYTRPJls/z9NcF8wiTVNm X-Google-Smtp-Source: ABdhPJxB5YJT6wbIN36q7Ogrzvwu7k1N2Xfq47t7Mi/SsWYgztmona1BE9Qt2h8uCQrQlUSbQFRrGA== X-Received: by 2002:a2e:8844:: with SMTP id z4mr11265188ljj.124.1597833688226; Wed, 19 Aug 2020 03:41:28 -0700 (PDT) Return-Path: Received: from localhost.localdomain (h-98-128-180-79.NA.cust.bahnhof.se. [98.128.180.79]) by smtp.gmail.com with ESMTPSA id y13sm6534822ljd.19.2020.08.19.03.41.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Aug 2020 03:41:27 -0700 (PDT) From: Ulf Hansson To: "Rafael J . Wysocki" , Kevin Hilman , linux-pm@vger.kernel.org Cc: Sudeep Holla , Lorenzo Pieralisi , Daniel Lezcano , Lina Iyer , Lukasz Luba , Vincent Guittot , Stephen Boyd , Bjorn Andersson , Benjamin Gaignard , Ulf Hansson , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] PM / Domains: Add support for PM domain on/off notifiers for genpd Date: Wed, 19 Aug 2020 12:40:57 +0200 Message-Id: <20200819104057.318230-4-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200819104057.318230-1-ulf.hansson@linaro.org> References: <20200819104057.318230-1-ulf.hansson@linaro.org> MIME-Version: 1.0 A device may have specific HW constraints that must be obeyed to, before its corresponding PM domain (genpd) can be powered off - and vice verse at power on. These constraints can't be managed through the regular runtime PM based deployment for a device, because the access pattern for it, isn't always request based. In other words, using the runtime PM callbacks to deal with the constraints doesn't work for these cases. For these reasons, let's instead add a PM domain power on/off notification mechanism to genpd. To add/remove a notifier for a device, the device must already have been attached to the genpd, which also means that it needs to be a part of the PM domain topology. To add/remove a notifier, let's introduce two genpd specific functions: - dev_pm_genpd_add|remove_notifier() Note that, to further clarify when genpd power on/off notifiers may be used, one can compare with the existing CPU_CLUSTER_PM_ENTER|EXIT notifiers. In the long run, the genpd power on/off notifiers should be able to replace them, but that requires additional genpd based platform support for the current users. Signed-off-by: Ulf Hansson --- drivers/base/power/domain.c | 130 ++++++++++++++++++++++++++++++++++-- include/linux/pm_domain.h | 15 +++++ 2 files changed, 141 insertions(+), 4 deletions(-) -- 2.25.1 Signed-off-by: Ulf Hansson diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 4b787e1ff188..9cb85a5e8342 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -545,13 +545,21 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, if (!genpd->gov) genpd->state_idx = 0; + /* Notify consumers that we are about to power off. */ + ret = raw_notifier_call_chain(&genpd->power_notifiers, GENPD_STATE_OFF, + NULL); + if (ret) + return ret; + /* Don't power off, if a child domain is waiting to power on. */ - if (atomic_read(&genpd->sd_count) > 0) - return -EBUSY; + if (atomic_read(&genpd->sd_count) > 0) { + ret = -EBUSY; + goto busy; + } ret = _genpd_power_off(genpd, true); if (ret) - return ret; + goto busy; genpd->status = GENPD_STATE_OFF; genpd_update_accounting(genpd); @@ -564,6 +572,9 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, } return 0; +busy: + raw_notifier_call_chain(&genpd->power_notifiers, GENPD_STATE_ON, NULL); + return ret; } /** @@ -606,6 +617,9 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) if (ret) goto err; + /* Inform consumers that we have powered on. */ + raw_notifier_call_chain(&genpd->power_notifiers, GENPD_STATE_ON, NULL); + genpd->status = GENPD_STATE_ON; genpd_update_accounting(genpd); @@ -948,9 +962,18 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, /* Choose the deepest state when suspending */ genpd->state_idx = genpd->state_count - 1; - if (_genpd_power_off(genpd, false)) + + /* Notify consumers that we are about to power off. */ + if (raw_notifier_call_chain(&genpd->power_notifiers, + GENPD_STATE_OFF, NULL)) return; + if (_genpd_power_off(genpd, false)) { + raw_notifier_call_chain(&genpd->power_notifiers, + GENPD_STATE_ON, NULL); + return; + } + genpd->status = GENPD_STATE_OFF; list_for_each_entry(link, &genpd->child_links, child_node) { @@ -998,6 +1021,9 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock, _genpd_power_on(genpd, false); + /* Inform consumers that we have powered on. */ + raw_notifier_call_chain(&genpd->power_notifiers, GENPD_STATE_ON, NULL); + genpd->status = GENPD_STATE_ON; } @@ -1593,6 +1619,101 @@ int pm_genpd_remove_device(struct device *dev) } EXPORT_SYMBOL_GPL(pm_genpd_remove_device); +/** + * dev_pm_genpd_add_notifier - Add a genpd power on/off notifier for @dev + * + * @dev: Device that should be associated with the notifier + * @nb: The notifier block to register + * + * Users may call this function to add a genpd power on/off notifier for an + * attached @dev. Only one notifier per device is allowed. The notifier is + * sent when genpd is powering on/off the PM domain. + * + * It is assumed that the user guarantee that the genpd wouldn't be detached + * while this routine is getting called. + * + * Returns 0 on success and negative error values on failures. + */ +int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb) +{ + struct generic_pm_domain *genpd; + struct generic_pm_domain_data *gpd_data; + int ret; + + genpd = dev_to_genpd_safe(dev); + if (!genpd) + return -ENODEV; + + if (WARN_ON(!dev->power.subsys_data || + !dev->power.subsys_data->domain_data)) + return -EINVAL; + + gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); + if (gpd_data->power_nb) + return -EEXIST; + + genpd_lock(genpd); + ret = raw_notifier_chain_register(&genpd->power_notifiers, nb); + genpd_unlock(genpd); + + if (ret) { + dev_warn(dev, "failed to add notifier for PM domain %s\n", + genpd->name); + return ret; + } + + gpd_data->power_nb = nb; + return 0; +} +EXPORT_SYMBOL_GPL(dev_pm_genpd_add_notifier); + +/** + * dev_pm_genpd_remove_notifier - Remove a genpd power on/off notifier for @dev + * + * @dev: Device that is associated with the notifier + * + * Users may call this function to remove a genpd power on/off notifier for an + * attached @dev. + * + * It is assumed that the user guarantee that the genpd wouldn't be detached + * while this routine is getting called. + * + * Returns 0 on success and negative error values on failures. + */ +int dev_pm_genpd_remove_notifier(struct device *dev) +{ + struct generic_pm_domain *genpd; + struct generic_pm_domain_data *gpd_data; + int ret; + + genpd = dev_to_genpd_safe(dev); + if (!genpd) + return -ENODEV; + + if (WARN_ON(!dev->power.subsys_data || + !dev->power.subsys_data->domain_data)) + return -EINVAL; + + gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); + if (!gpd_data->power_nb) + return -ENODEV; + + genpd_lock(genpd); + ret = raw_notifier_chain_unregister(&genpd->power_notifiers, + gpd_data->power_nb); + genpd_unlock(genpd); + + if (ret) { + dev_warn(dev, "failed to remove notifier for PM domain %s\n", + genpd->name); + return ret; + } + + gpd_data->power_nb = NULL; + return 0; +} +EXPORT_SYMBOL_GPL(dev_pm_genpd_remove_notifier); + static int genpd_add_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *subdomain) { @@ -1763,6 +1884,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd, INIT_LIST_HEAD(&genpd->parent_links); INIT_LIST_HEAD(&genpd->child_links); INIT_LIST_HEAD(&genpd->dev_list); + RAW_INIT_NOTIFIER_HEAD(&genpd->power_notifiers); genpd_lock_init(genpd); genpd->gov = gov; INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 66f3c5d64d81..3b2b561ce846 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -112,6 +112,7 @@ struct generic_pm_domain { cpumask_var_t cpus; /* A cpumask of the attached CPUs */ int (*power_off)(struct generic_pm_domain *domain); int (*power_on)(struct generic_pm_domain *domain); + struct raw_notifier_head power_notifiers; /* Power on/off notifiers */ struct opp_table *opp_table; /* OPP table of the genpd */ unsigned int (*opp_to_performance_state)(struct generic_pm_domain *genpd, struct dev_pm_opp *opp); @@ -178,6 +179,7 @@ struct generic_pm_domain_data { struct pm_domain_data base; struct gpd_timing_data td; struct notifier_block nb; + struct notifier_block *power_nb; int cpu; unsigned int performance_state; void *data; @@ -204,6 +206,8 @@ int pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); int pm_genpd_remove(struct generic_pm_domain *genpd); int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state); +int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb); +int dev_pm_genpd_remove_notifier(struct device *dev); extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; @@ -251,6 +255,17 @@ static inline int dev_pm_genpd_set_performance_state(struct device *dev, return -ENOTSUPP; } +static inline int dev_pm_genpd_add_notifier(struct device *dev, + struct notifier_block *nb) +{ + return -ENOTSUPP; +} + +static inline int dev_pm_genpd_remove_notifier(struct device *dev) +{ + return -ENOTSUPP; +} + #define simple_qos_governor (*(struct dev_power_governor *)(NULL)) #define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL)) #endif