public inbox for linux-arm-kernel@lists.infradead.org 
 help / color / mirror / Atom feed
* [PATCH v3 0/5] phy: fsl-imx8mq-usb: few improvements
@ 2026-06-03  5:37 Xu Yang
  2026-06-03  5:37 ` [PATCH v3 1/5] phy: fsl-imx8mq-usb: fix typec switch leak on probe error path Xu Yang
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Xu Yang @ 2026-06-03  5:37 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Jun Li
  Cc: linux-phy, imx, linux-arm-kernel, linux-kernel, Felix Gu, stable,
	Xu Yang

This patchset is a continuous of v2, it mainly resolves some concerns
reported by sashiko-bot.

Patch #1 fix Type-C switch resource leak if probe() fails.
Patch #3 add runtime PM support to avoid register access issue if the
      USB controller enters into runtime suspended state, in this state
      accessing USB PHY register may lack some resources. This will also
      avoid regulator leak if power_on() fails.
Patch #4 add debug control register regmap
Patch #5 correct i.MX8MP USB runtime wakeup issue after introduce runtime
      PM support.

Link to v2:
 - https://lore.kernel.org/linux-phy/20260512101046.1498096-1-xu.yang_2@nxp.com/
 - https://lore.kernel.org/linux-phy/20260512101212.1498223-1-xu.yang_2@nxp.com/

---
Felix Gu (1):
      phy: fsl-imx8mq-usb: fix typec switch leak on probe error path

Xu Yang (4):
      phy: fsl-imx8mq-usb: set usb phy to be wakeup capable
      phy: fsl-imx8mq-usb: add runtime PM support
      phy: fsl-imx8mq-usb: add control register regmap
      phy: fsl-imx8mq-usb: keep PHY power domain runtime always-on for i.MX8MP

 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 125 ++++++++++++++++++++---------
 1 file changed, 88 insertions(+), 37 deletions(-)
---
base-commit: 08484c504b55a98bd100527fbe10a3caf55ff3ff
change-id: 20260602-imx8mp-usb-phy-improvement-4272d308d862

Best regards,
--  
Xu Yang <xu.yang_2@nxp•com>



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v3 1/5] phy: fsl-imx8mq-usb: fix typec switch leak on probe error path
  2026-06-03  5:37 [PATCH v3 0/5] phy: fsl-imx8mq-usb: few improvements Xu Yang
@ 2026-06-03  5:37 ` Xu Yang
  2026-06-03 18:25   ` Frank Li
  2026-06-03  5:37 ` [PATCH v3 2/5] phy: fsl-imx8mq-usb: set usb phy to be wakeup capable Xu Yang
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Xu Yang @ 2026-06-03  5:37 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Jun Li
  Cc: linux-phy, imx, linux-arm-kernel, linux-kernel, Felix Gu, stable,
	Xu Yang

From: Felix Gu <ustc.gu@gmail•com>

If probe fails after imx95_usb_phy_get_tca() succeeds, the typec
switch leaks because the only cleanup path was in .remove, which
never runs on probe failure.

Use devm_add_action_or_reset() so the switch is cleaned up on both
probe failure and driver removal.  The .remove callback and
imx95_usb_phy_put_tca() are no longer needed.

Fixes: b58f0f86fd61 ("phy: fsl-imx8mq-usb: add tca function driver for imx95")
Cc: stable@vger•kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp•com>
Reviewed-by: Xu Yang <xu.yang_2@nxp•com>
Signed-off-by: Felix Gu <ustc.gu@gmail•com>

---
Changes in v3:
 - add R-b tag
 - cc statble
 - drop "sw = data" conversion
---
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 27 +++++++--------------------
 1 file changed, 7 insertions(+), 20 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index b05d80e849a1..88b804b2c982 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -173,9 +173,9 @@ static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device
 	return sw;
 }
 
-static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
+static void tca_blk_put_typec_switch(void *data)
 {
-	typec_switch_unregister(sw);
+	typec_switch_unregister(data);
 }
 
 static void tca_blk_orientation_set(struct tca_blk *tca,
@@ -248,6 +248,7 @@ static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
 	struct device *dev = &pdev->dev;
 	struct resource *res;
 	struct tca_blk *tca;
+	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (!res)
@@ -266,17 +267,11 @@ static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
 	tca->orientation = TYPEC_ORIENTATION_NORMAL;
 	tca->sw = tca_blk_get_typec_switch(pdev, imx_phy);
 
-	return tca;
-}
-
-static void imx95_usb_phy_put_tca(struct imx8mq_usb_phy *imx_phy)
-{
-	struct tca_blk *tca = imx_phy->tca;
-
-	if (!tca)
-		return;
+	ret = devm_add_action_or_reset(&pdev->dev, tca_blk_put_typec_switch, tca->sw);
+	if (ret)
+		return ERR_PTR(ret);
 
-	tca_blk_put_typec_switch(tca->sw);
+	return tca;
 }
 
 static u32 phy_tx_vref_tune_from_property(u32 percent)
@@ -739,16 +734,8 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	return PTR_ERR_OR_ZERO(phy_provider);
 }
 
-static void imx8mq_usb_phy_remove(struct platform_device *pdev)
-{
-	struct imx8mq_usb_phy *imx_phy = platform_get_drvdata(pdev);
-
-	imx95_usb_phy_put_tca(imx_phy);
-}
-
 static struct platform_driver imx8mq_usb_phy_driver = {
 	.probe	= imx8mq_usb_phy_probe,
-	.remove = imx8mq_usb_phy_remove,
 	.driver = {
 		.name	= "imx8mq-usb-phy",
 		.of_match_table	= imx8mq_usb_phy_of_match,

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 2/5] phy: fsl-imx8mq-usb: set usb phy to be wakeup capable
  2026-06-03  5:37 [PATCH v3 0/5] phy: fsl-imx8mq-usb: few improvements Xu Yang
  2026-06-03  5:37 ` [PATCH v3 1/5] phy: fsl-imx8mq-usb: fix typec switch leak on probe error path Xu Yang
@ 2026-06-03  5:37 ` Xu Yang
  2026-06-03 18:26   ` Frank Li
  2026-06-03  5:37 ` [PATCH v3 3/5] phy: fsl-imx8mq-usb: add runtime PM support Xu Yang
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Xu Yang @ 2026-06-03  5:37 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Jun Li
  Cc: linux-phy, imx, linux-arm-kernel, linux-kernel, Xu Yang

From: Xu Yang <xu.yang_2@nxp•com>

Set PHY wakeup capable because this PHY supports remote wakeup function.

Signed-off-by: Xu Yang <xu.yang_2@nxp•com>

---
Changes in v3:
 - no changes
Changes in v2:
 - no changes
---
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index 88b804b2c982..591ddf346061 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -728,6 +728,7 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 					"failed to get tca\n");
 
 	imx8m_get_phy_tuning_data(imx_phy);
+	device_set_wakeup_capable(dev, true);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 3/5] phy: fsl-imx8mq-usb: add runtime PM support
  2026-06-03  5:37 [PATCH v3 0/5] phy: fsl-imx8mq-usb: few improvements Xu Yang
  2026-06-03  5:37 ` [PATCH v3 1/5] phy: fsl-imx8mq-usb: fix typec switch leak on probe error path Xu Yang
  2026-06-03  5:37 ` [PATCH v3 2/5] phy: fsl-imx8mq-usb: set usb phy to be wakeup capable Xu Yang
@ 2026-06-03  5:37 ` Xu Yang
  2026-06-03 18:36   ` Frank Li
  2026-06-03  5:37 ` [PATCH v3 4/5] phy: fsl-imx8mq-usb: add control register regmap Xu Yang
  2026-06-03  5:37 ` [PATCH v3 5/5] phy: fsl-imx8mq-usb: keep PHY power domain runtime always-on for i.MX8MP Xu Yang
  4 siblings, 1 reply; 13+ messages in thread
From: Xu Yang @ 2026-06-03  5:37 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Jun Li
  Cc: linux-phy, imx, linux-arm-kernel, linux-kernel, Xu Yang

From: Xu Yang <xu.yang_2@nxp•com>

Add runtime PM to ensure the PHY is properly powered and clocked during
register access, preventing potential system hangs.

It guards register access in the following scenarios:
- PHY operations: init() and power_on/off() callbacks are guarded by
  phy core
- Type-C orientation switching when PHY/Controller are suspended which
  needs explicitly care
- Future PHY control port register regmap debugfs access

Signed-off-by: Xu Yang <xu.yang_2@nxp•com>

---
Changes in v3:
 - new patch
---
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 60 ++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 19 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index 591ddf346061..b0092c34416e 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -9,6 +9,7 @@
 #include <linux/of.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/usb/typec_mux.h>
 
@@ -136,17 +137,13 @@ static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
 {
 	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
 	struct tca_blk *tca = imx_phy->tca;
-	int ret;
 
 	if (tca->orientation == orientation)
 		return 0;
 
-	ret = clk_prepare_enable(imx_phy->clk);
-	if (ret)
-		return ret;
+	guard(pm_runtime_active)(&imx_phy->phy->dev);
 
 	tca_blk_orientation_set(tca, orientation);
-	clk_disable_unprepare(imx_phy->clk);
 
 	return 0;
 }
@@ -620,16 +617,6 @@ static int imx8mq_phy_power_on(struct phy *phy)
 	if (ret)
 		return ret;
 
-	ret = clk_prepare_enable(imx_phy->clk);
-	if (ret)
-		return ret;
-
-	ret = clk_prepare_enable(imx_phy->alt_clk);
-	if (ret) {
-		clk_disable_unprepare(imx_phy->clk);
-		return ret;
-	}
-
 	/* Disable rx term override */
 	value = readl(imx_phy->base + PHY_CTRL6);
 	value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL;
@@ -648,8 +635,6 @@ static int imx8mq_phy_power_off(struct phy *phy)
 	value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL;
 	writel(value, imx_phy->base + PHY_CTRL6);
 
-	clk_disable_unprepare(imx_phy->alt_clk);
-	clk_disable_unprepare(imx_phy->clk);
 	regulator_disable(imx_phy->vbus);
 
 	return 0;
@@ -686,6 +671,7 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct imx8mq_usb_phy *imx_phy;
 	const struct phy_ops *phy_ops;
+	int ret;
 
 	imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL);
 	if (!imx_phy)
@@ -693,13 +679,13 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, imx_phy);
 
-	imx_phy->clk = devm_clk_get(dev, "phy");
+	imx_phy->clk = devm_clk_get_enabled(dev, "phy");
 	if (IS_ERR(imx_phy->clk)) {
 		dev_err(dev, "failed to get imx8mq usb phy clock\n");
 		return PTR_ERR(imx_phy->clk);
 	}
 
-	imx_phy->alt_clk = devm_clk_get_optional(dev, "alt");
+	imx_phy->alt_clk = devm_clk_get_optional_enabled(dev, "alt");
 	if (IS_ERR(imx_phy->alt_clk))
 		return dev_err_probe(dev, PTR_ERR(imx_phy->alt_clk),
 				    "Failed to get alt clk\n");
@@ -708,6 +694,10 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(imx_phy->base))
 		return PTR_ERR(imx_phy->base);
 
+	ret = devm_pm_runtime_set_active_enabled(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
+
 	phy_ops = of_device_get_match_data(dev);
 	if (!phy_ops)
 		return -EINVAL;
@@ -735,11 +725,43 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	return PTR_ERR_OR_ZERO(phy_provider);
 }
 
+static int imx8mq_usb_phy_runtime_suspend(struct device *dev)
+{
+	struct imx8mq_usb_phy *imx_phy = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(imx_phy->alt_clk);
+	clk_disable_unprepare(imx_phy->clk);
+
+	return 0;
+}
+
+static int imx8mq_usb_phy_runtime_resume(struct device *dev)
+{
+	struct imx8mq_usb_phy *imx_phy = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(imx_phy->clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(imx_phy->alt_clk);
+	if (ret) {
+		clk_disable_unprepare(imx_phy->clk);
+		return ret;
+	}
+
+	return 0;
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(imx8mq_usb_phy_pm_ops, imx8mq_usb_phy_runtime_suspend,
+				 imx8mq_usb_phy_runtime_resume, NULL);
+
 static struct platform_driver imx8mq_usb_phy_driver = {
 	.probe	= imx8mq_usb_phy_probe,
 	.driver = {
 		.name	= "imx8mq-usb-phy",
 		.of_match_table	= imx8mq_usb_phy_of_match,
+		.pm = pm_ptr(&imx8mq_usb_phy_pm_ops),
 		.suppress_bind_attrs = true,
 	}
 };

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 4/5] phy: fsl-imx8mq-usb: add control register regmap
  2026-06-03  5:37 [PATCH v3 0/5] phy: fsl-imx8mq-usb: few improvements Xu Yang
                   ` (2 preceding siblings ...)
  2026-06-03  5:37 ` [PATCH v3 3/5] phy: fsl-imx8mq-usb: add runtime PM support Xu Yang
@ 2026-06-03  5:37 ` Xu Yang
  2026-06-03  7:21   ` Bough Chen
  2026-06-03  5:37 ` [PATCH v3 5/5] phy: fsl-imx8mq-usb: keep PHY power domain runtime always-on for i.MX8MP Xu Yang
  4 siblings, 1 reply; 13+ messages in thread
From: Xu Yang @ 2026-06-03  5:37 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Jun Li
  Cc: linux-phy, imx, linux-arm-kernel, linux-kernel, Xu Yang

From: Xu Yang <xu.yang_2@nxp•com>

The CR port is a simple 16-bit data/address parallel port that is
provided for on-chip access to the control registers inside the
USB 3.0 femtoPHY. Add control register regmap and export these
registers by debugfs to help PHY's diagnostic.

Signed-off-by: Xu Yang <xu.yang_2@nxp•com>

---
Changes in v3:
 - drop Frank's tag because it includes other changes
 - new patch
---
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index b0092c34416e..cda88ea1f12d 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0+
-/* Copyright (c) 2017 NXP. */
+/* Copyright 2017-2026 NXP. */
 
 #include <linux/bitfield.h>
 #include <linux/clk.h>
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/regmap.h>
 #include <linux/usb/typec_mux.h>
 
 #define PHY_CTRL0			0x0
@@ -56,6 +57,8 @@
 #define PHY_CTRL6_ALT_CLK_EN		BIT(1)
 #define PHY_CTRL6_ALT_CLK_SEL		BIT(0)
 
+#define PHY_CRCTL			0x30
+
 #define PHY_TUNE_DEFAULT		0xffffffff
 
 #define TCA_CLK_RST			0x00
@@ -119,6 +122,7 @@ struct imx8mq_usb_phy {
 	void __iomem *base;
 	struct regulator *vbus;
 	struct tca_blk *tca;
+	struct regmap *cr_regmap;
 	u32 pcs_tx_swing_full;
 	u32 pcs_tx_deemph_3p5db;
 	u32 tx_vref_tune;
@@ -665,6 +669,14 @@ static const struct of_device_id imx8mq_usb_phy_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
 
+static const struct regmap_config imx_cr_regmap_config = {
+	.name = "cr",
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = 0x7,
+};
+
 static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
@@ -694,6 +706,13 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(imx_phy->base))
 		return PTR_ERR(imx_phy->base);
 
+	imx_phy->cr_regmap = devm_regmap_init_mmio(dev, imx_phy->base + PHY_CRCTL,
+						   &imx_cr_regmap_config);
+	if (IS_ERR(imx_phy->cr_regmap)) {
+		dev_warn(dev, "Fail to init debug register regmap\n");
+		imx_phy->cr_regmap = NULL;
+	}
+
 	ret = devm_pm_runtime_set_active_enabled(dev);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
@@ -729,6 +748,9 @@ static int imx8mq_usb_phy_runtime_suspend(struct device *dev)
 {
 	struct imx8mq_usb_phy *imx_phy = dev_get_drvdata(dev);
 
+	if (imx_phy->cr_regmap)
+		regcache_cache_only(imx_phy->cr_regmap, true);
+
 	clk_disable_unprepare(imx_phy->alt_clk);
 	clk_disable_unprepare(imx_phy->clk);
 
@@ -750,6 +772,9 @@ static int imx8mq_usb_phy_runtime_resume(struct device *dev)
 		return ret;
 	}
 
+	if (imx_phy->cr_regmap)
+		regcache_cache_only(imx_phy->cr_regmap, false);
+
 	return 0;
 }
 

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 5/5] phy: fsl-imx8mq-usb: keep PHY power domain runtime always-on for i.MX8MP
  2026-06-03  5:37 [PATCH v3 0/5] phy: fsl-imx8mq-usb: few improvements Xu Yang
                   ` (3 preceding siblings ...)
  2026-06-03  5:37 ` [PATCH v3 4/5] phy: fsl-imx8mq-usb: add control register regmap Xu Yang
@ 2026-06-03  5:37 ` Xu Yang
  4 siblings, 0 replies; 13+ messages in thread
From: Xu Yang @ 2026-06-03  5:37 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Jun Li
  Cc: linux-phy, imx, linux-arm-kernel, linux-kernel, Xu Yang

From: Xu Yang <xu.yang_2@nxp•com>

On i.MX8MP, the USB PHY has a dedicated power domain that was previously
never powered off at runtime. With the introduction of runtime PM support,
the power domain will be powered off if the device is runtime suspended,
which breaks USB wakeup functionality.

To preserve wakeup functionality, mark the PHY power domain as runtime
always-on for i.MX8MP platform. To limit the behavior to i.MX8MP, add a
new imx95_usb_phy_ops for i.MX95 and introduce usb_phy_is_imx8mp() helper
to identify i.MX8MP PHY instance.

Signed-off-by: Xu Yang <xu.yang_2@nxp•com>

---
Changes in v3:
 - new patch
---
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index cda88ea1f12d..2c3c22c6c66d 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -9,6 +9,7 @@
 #include <linux/of.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
@@ -658,13 +659,20 @@ static const struct phy_ops imx8mp_usb_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static const struct phy_ops imx95_usb_phy_ops = {
+	.init		= imx8mp_usb_phy_init,
+	.power_on	= imx8mq_phy_power_on,
+	.power_off	= imx8mq_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
 static const struct of_device_id imx8mq_usb_phy_of_match[] = {
 	{.compatible = "fsl,imx8mq-usb-phy",
 	 .data = &imx8mq_usb_phy_ops,},
 	{.compatible = "fsl,imx8mp-usb-phy",
 	 .data = &imx8mp_usb_phy_ops,},
 	{.compatible = "fsl,imx95-usb-phy",
-	 .data = &imx8mp_usb_phy_ops,},
+	 .data = &imx95_usb_phy_ops,},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
@@ -677,6 +685,11 @@ static const struct regmap_config imx_cr_regmap_config = {
 	.max_register = 0x7,
 };
 
+static bool usb_phy_is_imx8mp(const void *data)
+{
+	return data == &imx8mp_usb_phy_ops;
+}
+
 static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
@@ -721,6 +734,9 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	if (!phy_ops)
 		return -EINVAL;
 
+	if (usb_phy_is_imx8mp(phy_ops))
+		dev_pm_genpd_rpm_always_on(dev, true);
+
 	imx_phy->phy = devm_phy_create(dev, NULL, phy_ops);
 	if (IS_ERR(imx_phy->phy))
 		return PTR_ERR(imx_phy->phy);

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 4/5] phy: fsl-imx8mq-usb: add control register regmap
  2026-06-03  5:37 ` [PATCH v3 4/5] phy: fsl-imx8mq-usb: add control register regmap Xu Yang
@ 2026-06-03  7:21   ` Bough Chen
  2026-06-04  2:34     ` Xu Yang
  0 siblings, 1 reply; 13+ messages in thread
From: Bough Chen @ 2026-06-03  7:21 UTC (permalink / raw)
  To: Xu Yang
  Cc: Vinod Koul, Neil Armstrong, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Jun Li, linux-phy, imx,
	linux-arm-kernel, linux-kernel, Xu Yang

On Wed, Jun 03, 2026 at 01:37:17PM +0800, Xu Yang wrote:
> From: Xu Yang <xu.yang_2@nxp•com>
> 
> The CR port is a simple 16-bit data/address parallel port that is
> provided for on-chip access to the control registers inside the
> USB 3.0 femtoPHY. Add control register regmap and export these
> registers by debugfs to help PHY's diagnostic.
> 
> Signed-off-by: Xu Yang <xu.yang_2@nxp•com>
> 
> ---
> Changes in v3:
>  - drop Frank's tag because it includes other changes
>  - new patch
> ---
>  drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> index b0092c34416e..cda88ea1f12d 100644
> --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> @@ -1,5 +1,5 @@
>  // SPDX-License-Identifier: GPL-2.0+
> -/* Copyright (c) 2017 NXP. */
> +/* Copyright 2017-2026 NXP. */

Should be : Copyright 2017, 2026 NXP.

>  
>  #include <linux/bitfield.h>
>  #include <linux/clk.h>
> @@ -11,6 +11,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/regulator/consumer.h>
> +#include <linux/regmap.h>
>  #include <linux/usb/typec_mux.h>
>  
>  #define PHY_CTRL0			0x0
> @@ -56,6 +57,8 @@
>  #define PHY_CTRL6_ALT_CLK_EN		BIT(1)
>  #define PHY_CTRL6_ALT_CLK_SEL		BIT(0)
>  
> +#define PHY_CRCTL			0x30
> +
>  #define PHY_TUNE_DEFAULT		0xffffffff
>  
>  #define TCA_CLK_RST			0x00
> @@ -119,6 +122,7 @@ struct imx8mq_usb_phy {
>  	void __iomem *base;
>  	struct regulator *vbus;
>  	struct tca_blk *tca;
> +	struct regmap *cr_regmap;
>  	u32 pcs_tx_swing_full;
>  	u32 pcs_tx_deemph_3p5db;
>  	u32 tx_vref_tune;
> @@ -665,6 +669,14 @@ static const struct of_device_id imx8mq_usb_phy_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
>  
> +static const struct regmap_config imx_cr_regmap_config = {
> +	.name = "cr",
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.max_register = 0x7,
> +};
> +

Your commit message says: The CR port is a simple 16-bit data/address parallel port
But here you use 32 bit mmio, which is a bit confuse to reader. 
Maybe you can add the following comment before the regmap config:

/*
 * CR Port MMIO Register Map
 * 
 * The CR (Control Register) port uses a 16-bit data/address protocol,
 * but is accessed through 32-bit MMIO registers:
 * 
 * Offset 0x0: CR Control Register
 *   [31:16] - Control/Status flags
 *   [15:0]  - 16-bit CR Address
 * 
 * Offset 0x4: CR Data Register
 *   [31:16] - Reserved/Status
 *   [15:0]  - 16-bit CR Data
 */

Or change your commit log like this:

The CR port is a 16-bit data/address parallel port protocol that is
accessed through 32-bit MMIO registers for on-chip access to the
control registers inside the USB 3.0 femtoPHY. Add control register
regmap and export these registers by debugfs to help PHY's diagnostic.

Regards
Haibo Chen

>  static int imx8mq_usb_phy_probe(struct platform_device *pdev)
>  {
>  	struct phy_provider *phy_provider;
> @@ -694,6 +706,13 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
>  	if (IS_ERR(imx_phy->base))
>  		return PTR_ERR(imx_phy->base);
>  
> +	imx_phy->cr_regmap = devm_regmap_init_mmio(dev, imx_phy->base + PHY_CRCTL,
> +						   &imx_cr_regmap_config);
> +	if (IS_ERR(imx_phy->cr_regmap)) {
> +		dev_warn(dev, "Fail to init debug register regmap\n");
> +		imx_phy->cr_regmap = NULL;
> +	}
> +
>  	ret = devm_pm_runtime_set_active_enabled(dev);
>  	if (ret)
>  		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
> @@ -729,6 +748,9 @@ static int imx8mq_usb_phy_runtime_suspend(struct device *dev)
>  {
>  	struct imx8mq_usb_phy *imx_phy = dev_get_drvdata(dev);
>  
> +	if (imx_phy->cr_regmap)
> +		regcache_cache_only(imx_phy->cr_regmap, true);
> +
>  	clk_disable_unprepare(imx_phy->alt_clk);
>  	clk_disable_unprepare(imx_phy->clk);
>  
> @@ -750,6 +772,9 @@ static int imx8mq_usb_phy_runtime_resume(struct device *dev)
>  		return ret;
>  	}
>  
> +	if (imx_phy->cr_regmap)
> +		regcache_cache_only(imx_phy->cr_regmap, false);
> +
>  	return 0;
>  }
>  
> 
> -- 
> 2.34.1
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 1/5] phy: fsl-imx8mq-usb: fix typec switch leak on probe error path
  2026-06-03  5:37 ` [PATCH v3 1/5] phy: fsl-imx8mq-usb: fix typec switch leak on probe error path Xu Yang
@ 2026-06-03 18:25   ` Frank Li
  2026-06-04  2:29     ` Xu Yang
  0 siblings, 1 reply; 13+ messages in thread
From: Frank Li @ 2026-06-03 18:25 UTC (permalink / raw)
  To: Xu Yang
  Cc: Vinod Koul, Neil Armstrong, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Jun Li, linux-phy, imx, linux-arm-kernel,
	linux-kernel, Felix Gu, stable, Xu Yang

On Wed, Jun 03, 2026 at 01:37:14PM +0800, Xu Yang wrote:
> From: Felix Gu <ustc.gu@gmail•com>
>
> If probe fails after imx95_usb_phy_get_tca() succeeds, the typec
> switch leaks because the only cleanup path was in .remove, which
> never runs on probe failure.
>
> Use devm_add_action_or_reset() so the switch is cleaned up on both
> probe failure and driver removal.  The .remove callback and
> imx95_usb_phy_put_tca() are no longer needed.
>
> Fixes: b58f0f86fd61 ("phy: fsl-imx8mq-usb: add tca function driver for imx95")
> Cc: stable@vger•kernel.org
> Reviewed-by: Frank Li <Frank.Li@nxp•com>
> Reviewed-by: Xu Yang <xu.yang_2@nxp•com>
> Signed-off-by: Felix Gu <ustc.gu@gmail•com>

Xu yang, if you send out patch, need your s-o-b tag

Frank

>
> ---
> Changes in v3:
>  - add R-b tag
>  - cc statble
>  - drop "sw = data" conversion
> ---
>  drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 27 +++++++--------------------
>  1 file changed, 7 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> index b05d80e849a1..88b804b2c982 100644
> --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> @@ -173,9 +173,9 @@ static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device
>  	return sw;
>  }
>
> -static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
> +static void tca_blk_put_typec_switch(void *data)
>  {
> -	typec_switch_unregister(sw);
> +	typec_switch_unregister(data);
>  }
>
>  static void tca_blk_orientation_set(struct tca_blk *tca,
> @@ -248,6 +248,7 @@ static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
>  	struct device *dev = &pdev->dev;
>  	struct resource *res;
>  	struct tca_blk *tca;
> +	int ret;
>
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>  	if (!res)
> @@ -266,17 +267,11 @@ static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
>  	tca->orientation = TYPEC_ORIENTATION_NORMAL;
>  	tca->sw = tca_blk_get_typec_switch(pdev, imx_phy);
>
> -	return tca;
> -}
> -
> -static void imx95_usb_phy_put_tca(struct imx8mq_usb_phy *imx_phy)
> -{
> -	struct tca_blk *tca = imx_phy->tca;
> -
> -	if (!tca)
> -		return;
> +	ret = devm_add_action_or_reset(&pdev->dev, tca_blk_put_typec_switch, tca->sw);
> +	if (ret)
> +		return ERR_PTR(ret);
>
> -	tca_blk_put_typec_switch(tca->sw);
> +	return tca;
>  }
>
>  static u32 phy_tx_vref_tune_from_property(u32 percent)
> @@ -739,16 +734,8 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
>  	return PTR_ERR_OR_ZERO(phy_provider);
>  }
>
> -static void imx8mq_usb_phy_remove(struct platform_device *pdev)
> -{
> -	struct imx8mq_usb_phy *imx_phy = platform_get_drvdata(pdev);
> -
> -	imx95_usb_phy_put_tca(imx_phy);
> -}
> -
>  static struct platform_driver imx8mq_usb_phy_driver = {
>  	.probe	= imx8mq_usb_phy_probe,
> -	.remove = imx8mq_usb_phy_remove,
>  	.driver = {
>  		.name	= "imx8mq-usb-phy",
>  		.of_match_table	= imx8mq_usb_phy_of_match,
>
> --
> 2.34.1
>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/5] phy: fsl-imx8mq-usb: set usb phy to be wakeup capable
  2026-06-03  5:37 ` [PATCH v3 2/5] phy: fsl-imx8mq-usb: set usb phy to be wakeup capable Xu Yang
@ 2026-06-03 18:26   ` Frank Li
  0 siblings, 0 replies; 13+ messages in thread
From: Frank Li @ 2026-06-03 18:26 UTC (permalink / raw)
  To: Xu Yang
  Cc: Vinod Koul, Neil Armstrong, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Jun Li, linux-phy, imx, linux-arm-kernel,
	linux-kernel, Xu Yang

On Wed, Jun 03, 2026 at 01:37:15PM +0800, Xu Yang wrote:
> From: Xu Yang <xu.yang_2@nxp•com>
>
> Set PHY wakeup capable because this PHY supports remote wakeup function.
>
> Signed-off-by: Xu Yang <xu.yang_2@nxp•com>
>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp•com>

> Changes in v3:
>  - no changes
> Changes in v2:
>  - no changes
> ---
>  drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> index 88b804b2c982..591ddf346061 100644
> --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> @@ -728,6 +728,7 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
>  					"failed to get tca\n");
>
>  	imx8m_get_phy_tuning_data(imx_phy);
> +	device_set_wakeup_capable(dev, true);
>
>  	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
>
>
> --
> 2.34.1
>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 3/5] phy: fsl-imx8mq-usb: add runtime PM support
  2026-06-03  5:37 ` [PATCH v3 3/5] phy: fsl-imx8mq-usb: add runtime PM support Xu Yang
@ 2026-06-03 18:36   ` Frank Li
  2026-06-04  2:31     ` Xu Yang
  0 siblings, 1 reply; 13+ messages in thread
From: Frank Li @ 2026-06-03 18:36 UTC (permalink / raw)
  To: Xu Yang
  Cc: Vinod Koul, Neil Armstrong, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Jun Li, linux-phy, imx, linux-arm-kernel,
	linux-kernel, Xu Yang

On Wed, Jun 03, 2026 at 01:37:16PM +0800, Xu Yang wrote:
> From: Xu Yang <xu.yang_2@nxp•com>
>
> Add runtime PM to ensure the PHY is properly powered and clocked during
> register access, preventing potential system hangs.
>
> It guards register access in the following scenarios:
> - PHY operations: init() and power_on/off() callbacks are guarded by
>   phy core
> - Type-C orientation switching when PHY/Controller are suspended which
>   needs explicitly care
> - Future PHY control port register regmap debugfs access
>
> Signed-off-by: Xu Yang <xu.yang_2@nxp•com>
>
> ---
> Changes in v3:
>  - new patch
> ---
>  drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 60 ++++++++++++++++++++----------
>  1 file changed, 41 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> index 591ddf346061..b0092c34416e 100644
> --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> @@ -9,6 +9,7 @@
>  #include <linux/of.h>
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/usb/typec_mux.h>
>
> @@ -136,17 +137,13 @@ static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
>  {
>  	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
>  	struct tca_blk *tca = imx_phy->tca;
> -	int ret;
>
>  	if (tca->orientation == orientation)
>  		return 0;
>
> -	ret = clk_prepare_enable(imx_phy->clk);
> -	if (ret)
> -		return ret;
> +	guard(pm_runtime_active)(&imx_phy->phy->dev);

use PM_RUNTIME_ACQUIRE macro

>
>  	tca_blk_orientation_set(tca, orientation);
> -	clk_disable_unprepare(imx_phy->clk);
>
>  	return 0;
>  }
> @@ -620,16 +617,6 @@ static int imx8mq_phy_power_on(struct phy *phy)
>  	if (ret)
>  		return ret;
>
> -	ret = clk_prepare_enable(imx_phy->clk);
> -	if (ret)
> -		return ret;
> -
> -	ret = clk_prepare_enable(imx_phy->alt_clk);
> -	if (ret) {
> -		clk_disable_unprepare(imx_phy->clk);
> -		return ret;
> -	}
> -
>  	/* Disable rx term override */
>  	value = readl(imx_phy->base + PHY_CTRL6);
>  	value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL;
> @@ -648,8 +635,6 @@ static int imx8mq_phy_power_off(struct phy *phy)
>  	value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL;
>  	writel(value, imx_phy->base + PHY_CTRL6);
>
> -	clk_disable_unprepare(imx_phy->alt_clk);
> -	clk_disable_unprepare(imx_phy->clk);
>  	regulator_disable(imx_phy->vbus);
>
>  	return 0;
> @@ -686,6 +671,7 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct imx8mq_usb_phy *imx_phy;
>  	const struct phy_ops *phy_ops;
> +	int ret;
>
>  	imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL);
>  	if (!imx_phy)
> @@ -693,13 +679,13 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
>
>  	platform_set_drvdata(pdev, imx_phy);
>
> -	imx_phy->clk = devm_clk_get(dev, "phy");
> +	imx_phy->clk = devm_clk_get_enabled(dev, "phy");
>  	if (IS_ERR(imx_phy->clk)) {
>  		dev_err(dev, "failed to get imx8mq usb phy clock\n");
>  		return PTR_ERR(imx_phy->clk);
>  	}
>
> -	imx_phy->alt_clk = devm_clk_get_optional(dev, "alt");
> +	imx_phy->alt_clk = devm_clk_get_optional_enabled(dev, "alt");
>  	if (IS_ERR(imx_phy->alt_clk))
>  		return dev_err_probe(dev, PTR_ERR(imx_phy->alt_clk),
>  				    "Failed to get alt clk\n");
> @@ -708,6 +694,10 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
>  	if (IS_ERR(imx_phy->base))
>  		return PTR_ERR(imx_phy->base);
>
> +	ret = devm_pm_runtime_set_active_enabled(dev);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
> +

you enable runtime pm here, when runtimes suspend

Frank

>  	phy_ops = of_device_get_match_data(dev);
>  	if (!phy_ops)
>  		return -EINVAL;
> @@ -735,11 +725,43 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
>  	return PTR_ERR_OR_ZERO(phy_provider);
>  }
>
> +static int imx8mq_usb_phy_runtime_suspend(struct device *dev)
> +{
> +	struct imx8mq_usb_phy *imx_phy = dev_get_drvdata(dev);
> +
> +	clk_disable_unprepare(imx_phy->alt_clk);
> +	clk_disable_unprepare(imx_phy->clk);
> +
> +	return 0;
> +}
> +
> +static int imx8mq_usb_phy_runtime_resume(struct device *dev)
> +{
> +	struct imx8mq_usb_phy *imx_phy = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = clk_prepare_enable(imx_phy->clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(imx_phy->alt_clk);
> +	if (ret) {
> +		clk_disable_unprepare(imx_phy->clk);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static DEFINE_RUNTIME_DEV_PM_OPS(imx8mq_usb_phy_pm_ops, imx8mq_usb_phy_runtime_suspend,
> +				 imx8mq_usb_phy_runtime_resume, NULL);
> +
>  static struct platform_driver imx8mq_usb_phy_driver = {
>  	.probe	= imx8mq_usb_phy_probe,
>  	.driver = {
>  		.name	= "imx8mq-usb-phy",
>  		.of_match_table	= imx8mq_usb_phy_of_match,
> +		.pm = pm_ptr(&imx8mq_usb_phy_pm_ops),
>  		.suppress_bind_attrs = true,
>  	}
>  };
>
> --
> 2.34.1
>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 1/5] phy: fsl-imx8mq-usb: fix typec switch leak on probe error path
  2026-06-03 18:25   ` Frank Li
@ 2026-06-04  2:29     ` Xu Yang
  0 siblings, 0 replies; 13+ messages in thread
From: Xu Yang @ 2026-06-04  2:29 UTC (permalink / raw)
  To: Frank Li
  Cc: Vinod Koul, Neil Armstrong, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Jun Li, linux-phy, imx, linux-arm-kernel,
	linux-kernel, Felix Gu, stable, Xu Yang

On Wed, Jun 03, 2026 at 02:25:46PM -0400, Frank Li wrote:
> On Wed, Jun 03, 2026 at 01:37:14PM +0800, Xu Yang wrote:
> > From: Felix Gu <ustc.gu@gmail•com>
> >
> > If probe fails after imx95_usb_phy_get_tca() succeeds, the typec
> > switch leaks because the only cleanup path was in .remove, which
> > never runs on probe failure.
> >
> > Use devm_add_action_or_reset() so the switch is cleaned up on both
> > probe failure and driver removal.  The .remove callback and
> > imx95_usb_phy_put_tca() are no longer needed.
> >
> > Fixes: b58f0f86fd61 ("phy: fsl-imx8mq-usb: add tca function driver for imx95")
> > Cc: stable@vger•kernel.org
> > Reviewed-by: Frank Li <Frank.Li@nxp•com>
> > Reviewed-by: Xu Yang <xu.yang_2@nxp•com>
> > Signed-off-by: Felix Gu <ustc.gu@gmail•com>
> 
> Xu yang, if you send out patch, need your s-o-b tag

OK. Will add it in v2.

Thanks,
Xu Yang


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 3/5] phy: fsl-imx8mq-usb: add runtime PM support
  2026-06-03 18:36   ` Frank Li
@ 2026-06-04  2:31     ` Xu Yang
  0 siblings, 0 replies; 13+ messages in thread
From: Xu Yang @ 2026-06-04  2:31 UTC (permalink / raw)
  To: Frank Li
  Cc: Vinod Koul, Neil Armstrong, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Jun Li, linux-phy, imx, linux-arm-kernel,
	linux-kernel, Xu Yang

On Wed, Jun 03, 2026 at 02:36:18PM -0400, Frank Li wrote:
> On Wed, Jun 03, 2026 at 01:37:16PM +0800, Xu Yang wrote:
> > From: Xu Yang <xu.yang_2@nxp•com>
> >
> > Add runtime PM to ensure the PHY is properly powered and clocked during
> > register access, preventing potential system hangs.
> >
> > It guards register access in the following scenarios:
> > - PHY operations: init() and power_on/off() callbacks are guarded by
> >   phy core
> > - Type-C orientation switching when PHY/Controller are suspended which
> >   needs explicitly care
> > - Future PHY control port register regmap debugfs access
> >
> > Signed-off-by: Xu Yang <xu.yang_2@nxp•com>
> >
> > ---
> > Changes in v3:
> >  - new patch
> > ---
> >  drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 60 ++++++++++++++++++++----------
> >  1 file changed, 41 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > index 591ddf346061..b0092c34416e 100644
> > --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > @@ -9,6 +9,7 @@
> >  #include <linux/of.h>
> >  #include <linux/phy/phy.h>
> >  #include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> >  #include <linux/regulator/consumer.h>
> >  #include <linux/usb/typec_mux.h>
> >
> > @@ -136,17 +137,13 @@ static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
> >  {
> >  	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
> >  	struct tca_blk *tca = imx_phy->tca;
> > -	int ret;
> >
> >  	if (tca->orientation == orientation)
> >  		return 0;
> >
> > -	ret = clk_prepare_enable(imx_phy->clk);
> > -	if (ret)
> > -		return ret;
> > +	guard(pm_runtime_active)(&imx_phy->phy->dev);
> 
> use PM_RUNTIME_ACQUIRE macro

OK

> 
> >
> >  	tca_blk_orientation_set(tca, orientation);
> > -	clk_disable_unprepare(imx_phy->clk);
> >
> >  	return 0;
> >  }
> > @@ -620,16 +617,6 @@ static int imx8mq_phy_power_on(struct phy *phy)
> >  	if (ret)
> >  		return ret;
> >
> > -	ret = clk_prepare_enable(imx_phy->clk);
> > -	if (ret)
> > -		return ret;
> > -
> > -	ret = clk_prepare_enable(imx_phy->alt_clk);
> > -	if (ret) {
> > -		clk_disable_unprepare(imx_phy->clk);
> > -		return ret;
> > -	}
> > -
> >  	/* Disable rx term override */
> >  	value = readl(imx_phy->base + PHY_CTRL6);
> >  	value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL;
> > @@ -648,8 +635,6 @@ static int imx8mq_phy_power_off(struct phy *phy)
> >  	value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL;
> >  	writel(value, imx_phy->base + PHY_CTRL6);
> >
> > -	clk_disable_unprepare(imx_phy->alt_clk);
> > -	clk_disable_unprepare(imx_phy->clk);
> >  	regulator_disable(imx_phy->vbus);
> >
> >  	return 0;
> > @@ -686,6 +671,7 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
> >  	struct device *dev = &pdev->dev;
> >  	struct imx8mq_usb_phy *imx_phy;
> >  	const struct phy_ops *phy_ops;
> > +	int ret;
> >
> >  	imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL);
> >  	if (!imx_phy)
> > @@ -693,13 +679,13 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
> >
> >  	platform_set_drvdata(pdev, imx_phy);
> >
> > -	imx_phy->clk = devm_clk_get(dev, "phy");
> > +	imx_phy->clk = devm_clk_get_enabled(dev, "phy");
> >  	if (IS_ERR(imx_phy->clk)) {
> >  		dev_err(dev, "failed to get imx8mq usb phy clock\n");
> >  		return PTR_ERR(imx_phy->clk);
> >  	}
> >
> > -	imx_phy->alt_clk = devm_clk_get_optional(dev, "alt");
> > +	imx_phy->alt_clk = devm_clk_get_optional_enabled(dev, "alt");
> >  	if (IS_ERR(imx_phy->alt_clk))
> >  		return dev_err_probe(dev, PTR_ERR(imx_phy->alt_clk),
> >  				    "Failed to get alt clk\n");
> > @@ -708,6 +694,10 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
> >  	if (IS_ERR(imx_phy->base))
> >  		return PTR_ERR(imx_phy->base);
> >
> > +	ret = devm_pm_runtime_set_active_enabled(dev);
> > +	if (ret)
> > +		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
> > +
> 
> you enable runtime pm here, when runtimes suspend

devm_pm_runtime_set_active_enabled() will firstly change status as runtime active,
then enable runtime PM. So it's already not in suspend state.

Thanks,
Xu Yang


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 4/5] phy: fsl-imx8mq-usb: add control register regmap
  2026-06-03  7:21   ` Bough Chen
@ 2026-06-04  2:34     ` Xu Yang
  0 siblings, 0 replies; 13+ messages in thread
From: Xu Yang @ 2026-06-04  2:34 UTC (permalink / raw)
  To: Bough Chen
  Cc: Vinod Koul, Neil Armstrong, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Jun Li, linux-phy, imx,
	linux-arm-kernel, linux-kernel, Xu Yang

On Wed, Jun 03, 2026 at 03:21:07PM +0800, Bough Chen wrote:
> On Wed, Jun 03, 2026 at 01:37:17PM +0800, Xu Yang wrote:
> > From: Xu Yang <xu.yang_2@nxp•com>
> > 
> > The CR port is a simple 16-bit data/address parallel port that is
> > provided for on-chip access to the control registers inside the
> > USB 3.0 femtoPHY. Add control register regmap and export these
> > registers by debugfs to help PHY's diagnostic.
> > 
> > Signed-off-by: Xu Yang <xu.yang_2@nxp•com>
> > 
> > ---
> > Changes in v3:
> >  - drop Frank's tag because it includes other changes
> >  - new patch
> > ---
> >  drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 27 ++++++++++++++++++++++++++-
> >  1 file changed, 26 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > index b0092c34416e..cda88ea1f12d 100644
> > --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > @@ -1,5 +1,5 @@
> >  // SPDX-License-Identifier: GPL-2.0+
> > -/* Copyright (c) 2017 NXP. */
> > +/* Copyright 2017-2026 NXP. */
> 
> Should be : Copyright 2017, 2026 NXP.

The Copyright hasn't been updated in a long time. So I want to extend the
period here.

> 
> >  
> >  #include <linux/bitfield.h>
> >  #include <linux/clk.h>
> > @@ -11,6 +11,7 @@
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_runtime.h>
> >  #include <linux/regulator/consumer.h>
> > +#include <linux/regmap.h>
> >  #include <linux/usb/typec_mux.h>
> >  
> >  #define PHY_CTRL0			0x0
> > @@ -56,6 +57,8 @@
> >  #define PHY_CTRL6_ALT_CLK_EN		BIT(1)
> >  #define PHY_CTRL6_ALT_CLK_SEL		BIT(0)
> >  
> > +#define PHY_CRCTL			0x30
> > +
> >  #define PHY_TUNE_DEFAULT		0xffffffff
> >  
> >  #define TCA_CLK_RST			0x00
> > @@ -119,6 +122,7 @@ struct imx8mq_usb_phy {
> >  	void __iomem *base;
> >  	struct regulator *vbus;
> >  	struct tca_blk *tca;
> > +	struct regmap *cr_regmap;
> >  	u32 pcs_tx_swing_full;
> >  	u32 pcs_tx_deemph_3p5db;
> >  	u32 tx_vref_tune;
> > @@ -665,6 +669,14 @@ static const struct of_device_id imx8mq_usb_phy_of_match[] = {
> >  };
> >  MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
> >  
> > +static const struct regmap_config imx_cr_regmap_config = {
> > +	.name = "cr",
> > +	.reg_bits = 32,
> > +	.val_bits = 32,
> > +	.reg_stride = 4,
> > +	.max_register = 0x7,
> > +};
> > +
> 
> Your commit message says: The CR port is a simple 16-bit data/address parallel port
> But here you use 32 bit mmio, which is a bit confuse to reader. 
> Maybe you can add the following comment before the regmap config:
> 
> /*
>  * CR Port MMIO Register Map
>  * 
>  * The CR (Control Register) port uses a 16-bit data/address protocol,
>  * but is accessed through 32-bit MMIO registers:
>  * 
>  * Offset 0x0: CR Control Register
>  *   [31:16] - Control/Status flags
>  *   [15:0]  - 16-bit CR Address
>  * 
>  * Offset 0x4: CR Data Register
>  *   [31:16] - Reserved/Status
>  *   [15:0]  - 16-bit CR Data
>  */
> 
> Or change your commit log like this:
> 
> The CR port is a 16-bit data/address parallel port protocol that is
> accessed through 32-bit MMIO registers for on-chip access to the
> control registers inside the USB 3.0 femtoPHY. Add control register
> regmap and export these registers by debugfs to help PHY's diagnostic.

OK. Thanks for the suggestion.

Thanks,
Xu Yang


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-06-04  2:35 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-03  5:37 [PATCH v3 0/5] phy: fsl-imx8mq-usb: few improvements Xu Yang
2026-06-03  5:37 ` [PATCH v3 1/5] phy: fsl-imx8mq-usb: fix typec switch leak on probe error path Xu Yang
2026-06-03 18:25   ` Frank Li
2026-06-04  2:29     ` Xu Yang
2026-06-03  5:37 ` [PATCH v3 2/5] phy: fsl-imx8mq-usb: set usb phy to be wakeup capable Xu Yang
2026-06-03 18:26   ` Frank Li
2026-06-03  5:37 ` [PATCH v3 3/5] phy: fsl-imx8mq-usb: add runtime PM support Xu Yang
2026-06-03 18:36   ` Frank Li
2026-06-04  2:31     ` Xu Yang
2026-06-03  5:37 ` [PATCH v3 4/5] phy: fsl-imx8mq-usb: add control register regmap Xu Yang
2026-06-03  7:21   ` Bough Chen
2026-06-04  2:34     ` Xu Yang
2026-06-03  5:37 ` [PATCH v3 5/5] phy: fsl-imx8mq-usb: keep PHY power domain runtime always-on for i.MX8MP Xu Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox