Skip to contentSkip to conversation

FAILED: patch "[PATCH] pmdomain: imx8m-blk-ctrl: Serialize power on/off across" failed to apply to 6.1-stable tree

PATCH New [email protected] 2 participants 2 messages Oct 12 – Oct 13

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 51c2db3ef0cb89a49ab7f47a40efd5d5b074ce8d
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026101234-smile-observant-e7bb@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 51c2db3ef0cb89a49ab7f47a40efd5d5b074ce8d Mon Sep 17 00:00:00 2001
From: Ming Qian <[email protected]>
Date: Mon, 21 Sep 2026 19:03:34 +0900
Subject: [PATCH] pmdomain: imx8m-blk-ctrl: Serialize power on/off across
sibling domains

On i.MX8MP the VPU blk-ctrl exposes G1, G2 and VC8000E as three separate genpds, each serialized only by its own genpd lock, so their power_on and power_off callbacks can run concurrently on SMP.

The sequences are not independent: they share the VPUMIX bus domain, the VPU_NOC and the ADB400 handshake. On power up the GPC cannot ack-verify the ADB400 handshake - the ack only completes once blk-ctrl sets the bus clk-en bit - so it just waits a fixed delay instead of polling hskack. A sibling transition landing inside another domain's reset window disturbs that shared clock and handshake timing, the victim's reset does not take effect, and its block registers read back all zeros: the decoder times out or the encoder fails its format check.

Serialize the blk-ctrl reset sequence with a per-blk-ctrl mutex; the driver deliberately avoids a genpd hierarchy, so the genpd core gives no cross-sibling serialization.

Fixes a1a5f15f7f6c ("soc: imx: imx8m-blk-ctrl: add i.MX8MP VPU blk ctrl")
drivers/pmdomain/imx/imx8m-blk-ctrl.c +15 -0
index 479789009c7f..f8105e87ea3c 100644
@@ -15,6 +15,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/clk.h>
+#include <linux/mutex.h>
 
 #include <dt-bindings/power/imx8mm-power.h>
 #include <dt-bindings/power/imx8mn-power.h>
@@ -34,6 +35,12 @@ struct imx8m_blk_ctrl {
 	struct regmap *regmap;
 	struct imx8m_blk_ctrl_domain *domains;
 	struct genpd_onecell_data onecell_data;
+	/*
+	 * Serializes the blk-ctrl reset/clock sequence across sibling domains;
+	 * their transitions interact through the shared VPUMIX bus domain,
+	 * VPU_NOC and the not-ack-verified ADB400 handshake (ERR050531).
+	 */
+	struct mutex power_lock;
 };
 
 struct imx8m_blk_ctrl_domain_data {
@@ -98,6 +105,8 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
 	struct imx8m_blk_ctrl *bc = domain->bc;
 	int ret;
 
+	guard(mutex)(&bc->power_lock);
+
 	/* make sure bus domain is awake */
 	ret = pm_runtime_get_sync(bc->bus_power_dev);
 	if (ret < 0) {
@@ -164,6 +173,8 @@ static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd)
 	const struct imx8m_blk_ctrl_domain_data *data = domain->data;
 	struct imx8m_blk_ctrl *bc = domain->bc;
 
+	guard(mutex)(&bc->power_lock);
+
 	/* put devices into reset and disable clocks */
 	if (data->mipi_phy_rst_mask)
 		regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
@@ -202,6 +213,10 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 
 	bc->dev = dev;
 
+	ret = devm_mutex_init(dev, &bc->power_lock);
+	if (ret)
+		return ret;
+
 	bc_data = of_device_get_match_data(dev);
 
 	base = devm_platform_ioremap_resource(pdev, 0);
maintainer
#1 lore raw

PATCH 1/1 pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains

From: Ming Qian <[email protected]>

[ Upstream commit 51c2db3ef0cb89a49ab7f47a40efd5d5b074ce8d ]

On i.MX8MP the VPU blk-ctrl exposes G1, G2 and VC8000E as three separate genpds, each serialized only by its own genpd lock, so their power_on and power_off callbacks can run concurrently on SMP.

The sequences are not independent: they share the VPUMIX bus domain, the VPU_NOC and the ADB400 handshake. On power up the GPC cannot ack-verify the ADB400 handshake - the ack only completes once blk-ctrl sets the bus clk-en bit - so it just waits a fixed delay instead of polling hskack. A sibling transition landing inside another domain's reset window disturbs that shared clock and handshake timing, the victim's reset does not take effect, and its block registers read back all zeros: the decoder times out or the encoder fails its format check.

Serialize the blk-ctrl reset sequence with a per-blk-ctrl mutex; the driver deliberately avoids a genpd hierarchy, so the genpd core gives no cross-sibling serialization.

Fixes a1a5f15f7f6c ("soc: imx: imx8m-blk-ctrl: add i.MX8MP VPU blk ctrl")
---
 drivers/soc/imx/imx8m-blk-ctrl.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
drivers/soc/imx/imx8m-blk-ctrl.c +15 -0
index 1b87823d835d3..65315bf908b36 100644
@@ -13,6 +13,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/clk.h>
+#include <linux/mutex.h>
 
 #include <dt-bindings/power/imx8mm-power.h>
 #include <dt-bindings/power/imx8mn-power.h>
@@ -32,6 +33,12 @@ struct imx8m_blk_ctrl {
 	struct regmap *regmap;
 	struct imx8m_blk_ctrl_domain *domains;
 	struct genpd_onecell_data onecell_data;
+	/*
+	 * Serializes the blk-ctrl reset/clock sequence across sibling domains;
+	 * their transitions interact through the shared VPUMIX bus domain,
+	 * VPU_NOC and the not-ack-verified ADB400 handshake (ERR050531).
+	 */
+	struct mutex power_lock;
 };
 
 struct imx8m_blk_ctrl_domain_data {
@@ -87,6 +94,8 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
 	struct imx8m_blk_ctrl *bc = domain->bc;
 	int ret;
 
+	guard(mutex)(&bc->power_lock);
+
 	/* make sure bus domain is awake */
 	ret = pm_runtime_get_sync(bc->bus_power_dev);
 	if (ret < 0) {
@@ -146,6 +155,8 @@ static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd)
 	const struct imx8m_blk_ctrl_domain_data *data = domain->data;
 	struct imx8m_blk_ctrl *bc = domain->bc;
 
+	guard(mutex)(&bc->power_lock);
+
 	/* put devices into reset and disable clocks */
 	if (data->mipi_phy_rst_mask)
 		regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
@@ -184,6 +195,10 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 
 	bc->dev = dev;
 
+	ret = devm_mutex_init(dev, &bc->power_lock);
+	if (ret)
+		return ret;
+
 	bc_data = of_device_get_match_data(dev);
 
 	base = devm_platform_ioremap_resource(pdev, 0);
Signature · 1 line
2.53.0