From: Arun Iyengar via B4 Relay <devnull+aiyengar1990.gmail.com@kernel.org>
To: Ulf Hansson <ulfh@kernel.org>, Heiko Stuebner <heiko@sntech.de>,
Shawn Lin <shawn.lin@rock-chips.com>,
Sebastian Reichel <sebastian.reichel@collabora.com>,
Kevin Hilman <khilman@linaro.org>,
Caesar Wang <wxt@rock-chips.com>,
Elaine Zhang <zhangqing@rock-chips.com>
Cc: linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-rockchip@lists.infradead.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: [PATCH 2/3] pmdomain: rockchip: remove subdomain links before the domains on error
Date: Tue, 10 Nov 2026 07:11:29 +0000 [thread overview]
Message-ID: <20261110-pmdomain-rockchip-v1-2-6b9fa6ebaa86@gmail.com> (raw)
In-Reply-To: <20261110-pmdomain-rockchip-v1-0-6b9fa6ebaa86@gmail.com>
From: Arun Iyengar <aiyengar1990@gmail.com>
When rockchip_pm_domain_probe() fails after some domains were
registered, for example because a clock of a nested domain is not
available yet and returns -EPROBE_DEFER, rockchip_pm_domain_cleanup()
calls pm_genpd_remove() for every registered domain in domain id order.
pm_genpd_remove() refuses a domain that is still the parent of another
domain and returns -EBUSY. The cleanup walks parents before their
children in id order, and on RK3588 RKVDEC0/RKVDEC1 (ids 14 and 15) are
also children of VDPU (id 21), so no ordering of the domain array lets
every removal succeed. Each refused parent only gets the "state may be
inconsistent" message, and on return devm frees its struct
rockchip_pm_domain, the embedded generic_pm_domain included, while it
is still linked on the global gpd_list. The next registration, the
unused domain power off at late_initcall and the genpd debugfs files
then walk freed memory.
Remove the parent/child links first, walking the power domain nodes
depth first in the same way rockchip_pm_add_subdomain() added them, so
that each child no longer has subdomains of its own when its link is
removed. With no links left, and no provider or devices attached in the
probe error path, pm_genpd_remove() succeeds for every domain before
devm frees it. pm_genpd_remove_subdomain() also drops the parent's
subdomain count, which removing the child with pm_genpd_remove() alone
does not.
Fixes: 79d12b7a7f22 ("soc: rockchip: power-domain: use pm_genpd_remove in error cleanup")
Cc: stable@vger.kernel.org
Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
drivers/pmdomain/rockchip/pm-domains.c | 46 ++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index 3b39b231ca0e..d7df19e10000 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -957,12 +957,58 @@ static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
/* devm will free our memory */
}
+static struct generic_pm_domain *
+rockchip_pm_node_to_genpd(struct rockchip_pmu *pmu, struct device_node *node)
+{
+ u32 id;
+
+ if (of_property_read_u32(node, "reg", &id) ||
+ id >= pmu->genpd_data.num_domains)
+ return NULL;
+
+ return pmu->genpd_data.domains[id];
+}
+
+/*
+ * Undo the pm_genpd_add_subdomain() calls of rockchip_pm_add_subdomain().
+ * Links are only ever added between a DT node and its children, so walking
+ * the tree depth first and removing the links of the children before the
+ * link to their parent always finds the subdomain without subdomains of its
+ * own, as pm_genpd_remove_subdomain() requires. This also covers domains with
+ * more than one parent (RKVDEC0/RKVDEC1 on RK3588), which a walk in domain id
+ * or registration order does not.
+ */
+static void rockchip_pm_remove_subdomains(struct rockchip_pmu *pmu,
+ struct device_node *parent)
+{
+ struct generic_pm_domain *parent_domain, *child_domain;
+
+ parent_domain = rockchip_pm_node_to_genpd(pmu, parent);
+
+ for_each_child_of_node_scoped(parent, np) {
+ rockchip_pm_remove_subdomains(pmu, np);
+
+ child_domain = rockchip_pm_node_to_genpd(pmu, np);
+ if (parent_domain && child_domain)
+ pm_genpd_remove_subdomain(parent_domain, child_domain);
+ }
+}
+
static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu)
{
struct generic_pm_domain *genpd;
struct rockchip_pm_domain *pd;
int i;
+ /*
+ * pm_genpd_remove() refuses a domain that still has subdomains, and
+ * devm frees the domains on return whether or not they were removed,
+ * which would leave freed memory on the global genpd list. Remove all
+ * parent/child links first, so every domain can be removed.
+ */
+ for_each_available_child_of_node_scoped(pmu->dev->of_node, np)
+ rockchip_pm_remove_subdomains(pmu, np);
+
for (i = 0; i < pmu->genpd_data.num_domains; i++) {
genpd = pmu->genpd_data.domains[i];
if (genpd) {
--
2.55.0
next prev parent reply other threads:[~2026-11-10 7:11 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 7:11 [PATCH 0/3] pmdomain: rockchip: fix the probe error and deferral paths Arun Iyengar via B4 Relay
2026-11-10 7:11 ` [PATCH 1/3] pmdomain: rockchip: put only the clocks that were got on error Arun Iyengar via B4 Relay
2026-11-10 7:11 ` Arun Iyengar via B4 Relay [this message]
2026-11-10 7:11 ` [PATCH 3/3] pmdomain: rockchip: do not report probe deferral of a domain as an error Arun Iyengar via B4 Relay
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261110-pmdomain-rockchip-v1-2-6b9fa6ebaa86@gmail.com \
--to=devnull+aiyengar1990.gmail.com@kernel.org \
--cc=aiyengar1990@gmail.com \
--cc=heiko@sntech.de \
--cc=khilman@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=sebastian.reichel@collabora.com \
--cc=shawn.lin@rock-chips.com \
--cc=stable@vger.kernel.org \
--cc=ulfh@kernel.org \
--cc=wxt@rock-chips.com \
--cc=zhangqing@rock-chips.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®