Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding
@ 2026-02-09  8:24 Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 01/11] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node Sherry Sun
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

This patch set adds support for parsing the reset property in new Root Port
binding in pci-imx6 driver, similar to the implementation in the qcom pcie
driver[1].

Also introduce generic helper functions to parse Root Port device tree
nodes and extract common properties like reset GPIOs. This allows multiple
PCI host controller drivers to share the same parsing logic.

Define struct pci_host_port to hold common Root Port properties and add
pci_host_common_parse_ports() to parse Root Port nodes from device tree,
pci_host_common_delete_ports() to cleanup the port lists.

The plan is to add the wake-gpio property to the root port in subsequent
patches. Also, the vpcie-supply property will be moved to the root port
node later based on the refactoring patch set for the PCI pwrctrl
framework[2]. 

The initial idea is to adopt the Manivannan’s recent PCIe M.2 KeyE
connector support patch set[3] and PCI power control framework patches[2],
and extend them to the pcie-imx6 driver. Since the new M.2/pwrctrl model is
implemented based on Root Ports and requires the pwrctrl driver to bind to
a Root Port device, we need to introduce a Root Port child node on i.MX
boards that provide an M.2 connector.

To follow a more standardized DT structure, it also makes sense to move
the reset-gpios and wake-gpios properties into the Root Port node. These
signals logically belong to the Root Port rather than the host bridge,
and placing them there aligns with the new M.2/pwrctrl model.

Regarding backward compatibility, as Frank suggested, I will not remove
the old reset-gpio property from existing DTS files to avoid function
break.

For new i.MX platforms — such as the upcoming i.MX952-evk will add
vpcie-supply, reset-gpios, and wake-gpios directly under the Root Port
node.
Therefore, driver updates are needed to support both the legacy
properties and the new standardized Root Port based layout.

[1] https://lore.kernel.org/linux-pci/20250702-perst-v5-0-920b3d1f6ee1@qti.qualcomm.com/
[2] https://lore.kernel.org/linux-pci/20260115-pci-pwrctrl-rework-v5-0-9d26da3ce903@oss.qualcomm.com/
[3] https://lore.kernel.org/linux-pci/20260112-pci-m2-e-v4-0-eff84d2c6d26@oss.qualcomm.com/

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
Changes in V4:
1. Add common helpers for parsing Root Port properties in pci-host-common.c in
   patch#2.
2. Call common pci_host_common_parse_ports() and pci_host_common_delete_ports()
   in pci-imx6 driver.
3. Use PCIE_T_PVPERL_MS and PCIE_RESET_CONFIG_WAIT_MS instead of magic number
   100 in patch#3 as Manivannan suggested.
4. Use "PERST#" instead of "PCIe reset" for the reset gpio lable in patch#3.

Changes in V3:
1. Improve the patch#2 commit message as Frank suggested.
2. Add Reviewed-by tag for patch#1.

Changes in V2:
1. Improve the patch#1 commit message as Frank suggested.
2. Also mark the reset-gpio-active-high property as deprecated in
   imx6q-pcie DT binding as Rob suggested.
3. The imx_pcie_delete_ports() has been moved up so that the
   imx_pcie_parse_ports() can call this helper function in error handling.
4. Keep the old reset-gpio property in the host bridge node for the
   existing dts files and add comments to avoid confusion.
---

Sherry Sun (11):
  dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node
  PCI: host-generic: Add common helpers for parsing Root Port properties
  PCI: imx6: Add support for parsing the reset property in new Root Port
    binding
  arm: dts: imx6qdl: Add Root Port node and PERST property
  arm: dts: imx6sx: Add Root Port node and PERST property
  arm: dts: imx7d: Add Root Port node and PERST property
  arm64: dts: imx8mm: Add Root Port node and PERST property
  arm64: dts: imx8mp: Add Root Port node and PERST property
  arm64: dts: imx8mq: Add Root Port node and PERST property
  arm64: dts: imx8dxl/qm/qxp: Add Root Port node and PERST property
  arm64: dts: imx95: Add Root Port node and PERST property

 .../bindings/pci/fsl,imx6q-pcie.yaml          | 32 ++++++++
 .../arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi |  5 ++
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi        | 11 +++
 .../arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts |  5 ++
 arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi     |  5 ++
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi         | 11 +++
 arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts       |  5 ++
 arch/arm/boot/dts/nxp/imx/imx7d.dtsi          | 11 +++
 .../boot/dts/freescale/imx8-ss-hsio.dtsi      | 11 +++
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts |  5 ++
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi |  5 ++
 arch/arm64/boot/dts/freescale/imx8mm.dtsi     | 11 +++
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts  |  5 ++
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     | 11 +++
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts  | 10 +++
 arch/arm64/boot/dts/freescale/imx8mq.dtsi     | 22 ++++++
 arch/arm64/boot/dts/freescale/imx8qm-mek.dts  | 10 +++
 .../boot/dts/freescale/imx8qm-ss-hsio.dtsi    | 22 ++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |  5 ++
 .../boot/dts/freescale/imx95-15x15-evk.dts    |  5 ++
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 10 +++
 arch/arm64/boot/dts/freescale/imx95.dtsi      | 22 ++++++
 drivers/pci/controller/dwc/pci-imx6.c         | 69 +++++++++++++----
 drivers/pci/controller/pci-host-common.c      | 75 +++++++++++++++++++
 drivers/pci/controller/pci-host-common.h      | 17 +++++
 25 files changed, 386 insertions(+), 14 deletions(-)

-- 
2.37.1



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

* [PATCH V4 01/11] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 02/11] PCI: host-generic: Add common helpers for parsing Root Port properties Sherry Sun
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Update fsl,imx6q-pcie.yaml to include the standard reset-gpios property
for the Root Port node.

The reset-gpios property is already defined in pci-bus-common.yaml for
PERST#, so use it instead of the local reset-gpio property. Keep the
existing reset-gpio property in the bridge node for backward
compatibility, but mark it as deprecated.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
---
 .../bindings/pci/fsl,imx6q-pcie.yaml          | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index 12a01f7a5744..d1a2526f43dc 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -59,16 +59,34 @@ properties:
       - const: dma
 
   reset-gpio:
+    deprecated: true
     description: Should specify the GPIO for controlling the PCI bus device
       reset signal. It's not polarity aware and defaults to active-low reset
       sequence (L=reset state, H=operation state) (optional required).
+      This property is deprecated, instead of referencing this property from the
+      host bridge node, use the reset-gpios property from the root port node.
 
   reset-gpio-active-high:
+    deprecated: true
     description: If present then the reset sequence using the GPIO
       specified in the "reset-gpio" property is reversed (H=reset state,
       L=operation state) (optional required).
+      This property is deprecated along with the reset-gpio property above, use
+      the reset-gpios property from the root port node.
     type: boolean
 
+  pcie@0:
+    description:
+      Describe the i.MX6 PCIe Root Port.
+    type: object
+    $ref: /schemas/pci/pci-pci-bridge.yaml#
+
+    properties:
+      reg:
+        maxItems: 1
+
+    unevaluatedProperties: false
+
 required:
   - compatible
   - reg
@@ -229,6 +247,7 @@ unevaluatedProperties: false
 examples:
   - |
     #include <dt-bindings/clock/imx6qdl-clock.h>
+    #include <dt-bindings/gpio/gpio.h>
     #include <dt-bindings/interrupt-controller/arm-gic.h>
 
     pcie: pcie@1ffc000 {
@@ -255,5 +274,18 @@ examples:
                 <&clks IMX6QDL_CLK_LVDS1_GATE>,
                 <&clks IMX6QDL_CLK_PCIE_REF_125M>;
         clock-names = "pcie", "pcie_bus", "pcie_phy";
+
+        pcie_port0: pcie@0 {
+            compatible = "pciclass,0604";
+            device_type = "pci";
+            reg = <0x0 0x0 0x0 0x0 0x0>;
+            bus-range = <0x01 0xff>;
+
+            #address-cells = <3>;
+            #size-cells = <2>;
+            ranges;
+
+            reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+        };
     };
 ...
-- 
2.37.1



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

* [PATCH V4 02/11] PCI: host-generic: Add common helpers for parsing Root Port properties
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 01/11] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09 16:33   ` Frank Li
  2026-02-09  8:24 ` [PATCH V4 03/11] PCI: imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Introduce generic helper functions to parse Root Port device tree nodes
and extract common properties like reset GPIOs. This allows multiple
PCI host controller drivers to share the same parsing logic.

Define struct pci_host_port to hold common Root Port properties and add
pci_host_common_parse_ports() to parse Root Port nodes from device tree,
pci_host_common_delete_ports() to cleanup the port lists.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 drivers/pci/controller/pci-host-common.c | 75 ++++++++++++++++++++++++
 drivers/pci/controller/pci-host-common.h | 17 ++++++
 2 files changed, 92 insertions(+)

diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index c473e7c03bac..287e92df0092 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
@@ -17,6 +18,80 @@
 
 #include "pci-host-common.h"
 
+/**
+ * pci_host_common_delete_ports - Cleanup function for port list
+ * @data: Pointer to the port list head
+ */
+void pci_host_common_delete_ports(void *data)
+{
+	struct list_head *ports = data;
+	struct pci_host_port *port, *tmp;
+
+	list_for_each_entry_safe(port, tmp, ports, list)
+		list_del(&port->list);
+}
+EXPORT_SYMBOL_GPL(pci_host_common_delete_ports);
+
+/**
+ * pci_host_common_parse_port - Parse a single Root Port node
+ * @dev: Device pointer
+ * @node: Device tree node of the Root Port
+ * @ports: List head to add the parsed port to
+ *
+ * Returns: 0 on success, negative error code on failure
+ */
+static int pci_host_common_parse_port(struct device *dev,
+				      struct device_node *node,
+				      struct list_head *ports)
+{
+	struct pci_host_port *port;
+	struct gpio_desc *reset;
+
+	reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
+				      "reset", GPIOD_OUT_HIGH, "PERST#");
+	if (IS_ERR(reset))
+		return PTR_ERR(reset);
+
+	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	port->reset = reset;
+	INIT_LIST_HEAD(&port->list);
+	list_add_tail(&port->list, ports);
+
+	return 0;
+}
+
+/**
+ * pci_host_common_parse_ports - Parse Root Port nodes from device tree
+ * @dev: Device pointer
+ * @ports: List head to store parsed ports
+ *
+ * This function iterates through child nodes of the host bridge and parses
+ * Root Port properties (currently only reset GPIO).
+ *
+ * Returns: 0 on success, -ENOENT if no ports found, other negative error codes
+ * on failure
+ */
+int pci_host_common_parse_ports(struct device *dev, struct list_head *ports)
+{
+	int ret = -ENOENT;
+
+	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
+		if (!of_node_is_type(of_port, "pci"))
+			continue;
+		ret = pci_host_common_parse_port(dev, of_port, ports);
+		if (ret) {
+			pci_host_common_delete_ports(ports);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pci_host_common_parse_ports);
+
 static void gen_pci_unmap_cfg(void *ptr)
 {
 	pci_ecam_free((struct pci_config_window *)ptr);
diff --git a/drivers/pci/controller/pci-host-common.h b/drivers/pci/controller/pci-host-common.h
index b5075d4bd7eb..2c8df230886f 100644
--- a/drivers/pci/controller/pci-host-common.h
+++ b/drivers/pci/controller/pci-host-common.h
@@ -12,6 +12,23 @@
 
 struct pci_ecam_ops;
 
+/**
+ * struct pci_host_port - Generic Root Port properties
+ * @list: List node for linking multiple ports
+ * @reset: GPIO descriptor for PERST# signal
+ *
+ * This structure contains common properties that can be parsed from
+ * Root Port device tree nodes.
+ */
+struct pci_host_port {
+	struct list_head	list;
+	struct gpio_desc	*reset;
+};
+
+void pci_host_common_delete_ports(void *data);
+int pci_host_common_parse_ports(struct device *dev,
+				struct list_head *ports);
+
 int pci_host_common_probe(struct platform_device *pdev);
 int pci_host_common_init(struct platform_device *pdev,
 			 struct pci_host_bridge *bridge,
-- 
2.37.1



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

* [PATCH V4 03/11] PCI: imx6: Add support for parsing the reset property in new Root Port binding
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 01/11] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 02/11] PCI: host-generic: Add common helpers for parsing Root Port properties Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09 16:35   ` Frank Li
  2026-02-09  8:24 ` [PATCH V4 04/11] arm: dts: imx6qdl: Add Root Port node and PERST property Sherry Sun
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

DT binding allows specifying 'reset' property in both host bridge and
Root Port nodes, but specifying in the host bridge node is marked as
deprecated. So add support for parsing the new binding that uses
'reset-gpios' property for PERST#.

The initial idea is to add the PCIe M.2 KeyE connector support and PCI
power control framework to the pcie-imx6 driver. Since the new
M.2/pwrctrl model is implemented based on Root Ports and requires the
pwrctrl driver to bind to a Root Port device, we need to introduce a
Root Port child node on i.MX boards that provide an M.2 connector.

To follow a more standardized DT structure, it also makes sense to move
the reset-gpios and wake-gpios properties into the Root Port node. These
signals logically belong to the Root Port rather than the host bridge,
and placing them there aligns with the new M.2/pwrctrl model.

To maintain DT backwards compatibility, fallback to the legacy method of
parsing the host bridge node if the reset property is not present in the
Root Port node.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 69 +++++++++++++++++++++------
 1 file changed, 55 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index a5b8d0b71677..317a969da96b 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -34,6 +34,7 @@
 #include <linux/pm_runtime.h>
 
 #include "../../pci.h"
+#include "../pci-host-common.h"
 #include "pcie-designware.h"
 
 #define IMX8MQ_GPR_PCIE_REF_USE_PAD		BIT(9)
@@ -150,8 +151,8 @@ struct imx_lut_data {
 
 struct imx_pcie {
 	struct dw_pcie		*pci;
-	struct gpio_desc	*reset_gpiod;
 	struct clk_bulk_data	*clks;
+	struct list_head	ports;
 	int			num_clks;
 	bool			supports_clkreq;
 	bool			enable_ext_refclk;
@@ -897,29 +898,34 @@ static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
 
 static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
 {
+	struct pci_host_port *port;
+
 	reset_control_assert(imx_pcie->pciephy_reset);
 
 	if (imx_pcie->drvdata->core_reset)
 		imx_pcie->drvdata->core_reset(imx_pcie, true);
 
 	/* Some boards don't have PCIe reset GPIO. */
-	gpiod_set_value_cansleep(imx_pcie->reset_gpiod, 1);
+	list_for_each_entry(port, &imx_pcie->ports, list)
+		gpiod_set_value_cansleep(port->reset, 1);
 }
 
 static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
 {
+	struct pci_host_port *port;
+
 	reset_control_deassert(imx_pcie->pciephy_reset);
 
 	if (imx_pcie->drvdata->core_reset)
 		imx_pcie->drvdata->core_reset(imx_pcie, false);
 
 	/* Some boards don't have PCIe reset GPIO. */
-	if (imx_pcie->reset_gpiod) {
-		msleep(100);
-		gpiod_set_value_cansleep(imx_pcie->reset_gpiod, 0);
-		/* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
-		msleep(100);
-	}
+	list_for_each_entry(port, &imx_pcie->ports, list)
+		if (port->reset) {
+			msleep(PCIE_T_PVPERL_MS);
+			gpiod_set_value_cansleep(port->reset, 0);
+			msleep(PCIE_RESET_CONFIG_WAIT_MS);
+		}
 
 	return 0;
 }
@@ -1642,6 +1648,27 @@ static const struct dev_pm_ops imx_pcie_pm_ops = {
 				  imx_pcie_resume_noirq)
 };
 
+static int imx_pcie_parse_legacy_binding(struct imx_pcie *pcie)
+{
+	struct device *dev = pcie->pci->dev;
+	struct pci_host_port *port;
+	struct gpio_desc *reset;
+
+	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(reset))
+		return PTR_ERR(reset);
+
+	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	port->reset = reset;
+	INIT_LIST_HEAD(&port->list);
+	list_add_tail(&port->list, &pcie->ports);
+
+	return 0;
+}
+
 static int imx_pcie_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1660,6 +1687,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
 	if (!pci)
 		return -ENOMEM;
 
+	INIT_LIST_HEAD(&imx_pcie->ports);
+
 	pci->dev = dev;
 	pci->ops = &dw_pcie_ops;
 
@@ -1688,12 +1717,24 @@ static int imx_pcie_probe(struct platform_device *pdev)
 			return PTR_ERR(imx_pcie->phy_base);
 	}
 
-	/* Fetch GPIOs */
-	imx_pcie->reset_gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
-	if (IS_ERR(imx_pcie->reset_gpiod))
-		return dev_err_probe(dev, PTR_ERR(imx_pcie->reset_gpiod),
-				     "unable to get reset gpio\n");
-	gpiod_set_consumer_name(imx_pcie->reset_gpiod, "PCIe reset");
+	ret = pci_host_common_parse_ports(dev, &imx_pcie->ports);
+	if (ret) {
+		if (ret != -ENOENT)
+			return dev_err_probe(dev, ret, "Failed to parse Root Port: %d\n", ret);
+
+		/*
+		 * In the case of properties not populated in Root Port node,
+		 * fallback to the legacy method of parsing the Host Bridge
+		 * node. This is to maintain DT backwards compatibility.
+		 */
+		ret = imx_pcie_parse_legacy_binding(imx_pcie);
+		if (ret)
+			return dev_err_probe(dev, ret, "Unable to get reset gpio: %d\n", ret);
+	}
+
+	ret = devm_add_action_or_reset(dev, pci_host_common_delete_ports, &imx_pcie->ports);
+	if (ret)
+		return ret;
 
 	/* Fetch clocks */
 	imx_pcie->num_clks = devm_clk_bulk_get_all(dev, &imx_pcie->clks);
-- 
2.37.1



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

* [PATCH V4 04/11] arm: dts: imx6qdl: Add Root Port node and PERST property
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (2 preceding siblings ...)
  2026-02-09  8:24 ` [PATCH V4 03/11] PCI: imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 05/11] arm: dts: imx6sx: " Sherry Sun
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi |  5 +++++
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi         | 11 +++++++++++
 arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts |  5 +++++
 3 files changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
index ba29720e3f72..fe9046c03ddd 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
@@ -754,11 +754,16 @@ lvds0_out: endpoint {
 &pcie {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie>;
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_pcie>;
 	status = "okay";
 };
 
+&pcie_port0 {
+	reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+};
+
 &pwm1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm1>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
index 76e6043e1f91..eeb376193398 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -289,6 +289,17 @@ pcie: pcie@1ffc000 {
 				 <&clks IMX6QDL_CLK_PCIE_REF_125M>;
 			clock-names = "pcie", "pcie_bus", "pcie_phy";
 			status = "disabled";
+
+			pcie_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 
 		aips1: bus@2000000 { /* AIPS1 */
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts b/arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts
index c5b220aeaefd..6b12cab7175f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts
@@ -45,10 +45,15 @@ MX6QDL_PAD_GPIO_6__ENET_IRQ		0x000b1
 };
 
 &pcie {
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&max7310_c 5 GPIO_ACTIVE_LOW>;
 	status = "okay";
 };
 
+&pcie_port0 {
+	reset-gpios = <&max7310_c 5 GPIO_ACTIVE_LOW>;
+};
+
 &sata {
 	status = "okay";
 };
-- 
2.37.1



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

* [PATCH V4 05/11] arm: dts: imx6sx: Add Root Port node and PERST property
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (3 preceding siblings ...)
  2026-02-09  8:24 ` [PATCH V4 04/11] arm: dts: imx6qdl: Add Root Port node and PERST property Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 06/11] arm: dts: imx7d: " Sherry Sun
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi |  5 +++++
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi     | 11 +++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
index 3e238d8118fa..338de4d144b2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
@@ -282,11 +282,16 @@ codec: wm8962@1a {
 &pcie {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie>;
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&gpio2 0 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_pcie_gpio>;
 	status = "okay";
 };
 
+&pcie_port0 {
+	reset-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+};
+
 &lcdif1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_lcd>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
index 1426f357d474..d42363cb5105 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
@@ -1470,6 +1470,17 @@ pcie: pcie@8ffc000 {
 			power-domains = <&pd_disp>, <&pd_pci>;
 			power-domain-names = "pcie", "pcie_phy";
 			status = "disabled";
+
+			pcie_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 	};
 };
-- 
2.37.1



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

* [PATCH V4 06/11] arm: dts: imx7d: Add Root Port node and PERST property
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (4 preceding siblings ...)
  2026-02-09  8:24 ` [PATCH V4 05/11] arm: dts: imx6sx: " Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 07/11] arm64: dts: imx8mm: " Sherry Sun
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts |  5 +++++
 arch/arm/boot/dts/nxp/imx/imx7d.dtsi    | 11 +++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts b/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts
index a370e868cafe..0046b276b8b9 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts
@@ -456,10 +456,15 @@ display_out: endpoint {
 };
 
 &pcie {
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&extended_io 1 GPIO_ACTIVE_LOW>;
 	status = "okay";
 };
 
+&pcie_port0 {
+	reset-gpios = <&extended_io 1 GPIO_ACTIVE_LOW>;
+};
+
 &reg_1p0d {
 	vin-supply = <&sw2_reg>;
 };
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d.dtsi
index d961c61a93af..3c5c1f2c1460 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7d.dtsi
@@ -155,6 +155,17 @@ pcie: pcie@33800000 {
 			reset-names = "pciephy", "apps", "turnoff";
 			fsl,imx7d-pcie-phy = <&pcie_phy>;
 			status = "disabled";
+
+			pcie_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 	};
 };
-- 
2.37.1



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

* [PATCH V4 07/11] arm64: dts: imx8mm: Add Root Port node and PERST property
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (5 preceding siblings ...)
  2026-02-09  8:24 ` [PATCH V4 06/11] arm: dts: imx7d: " Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 08/11] arm64: dts: imx8mp: " Sherry Sun
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi |  5 +++++
 arch/arm64/boot/dts/freescale/imx8mm.dtsi     | 11 +++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index 6eab8a6001db..060860f24e7a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -533,6 +533,7 @@ &pcie_phy {
 &pcie0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie0>;
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
 	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&pcie0_refclk>,
 		 <&clk IMX8MM_CLK_PCIE1_AUX>;
@@ -559,6 +560,10 @@ &pcie0_ep {
 	status = "disabled";
 };
 
+&pcie0_port0 {
+	reset-gpios = <&gpio4 21 GPIO_ACTIVE_LOW>;
+};
+
 &sai2 {
 	#sound-dai-cells = <0>;
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 9f49c0b386d3..1204cc4d3f37 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -1369,6 +1369,17 @@ pcie0: pcie@33800000 {
 			phys = <&pcie_phy>;
 			phy-names = "pcie-phy";
 			status = "disabled";
+
+			pcie0_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 
 		pcie0_ep: pcie-ep@33800000 {
-- 
2.37.1



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

* [PATCH V4 08/11] arm64: dts: imx8mp: Add Root Port node and PERST property
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (6 preceding siblings ...)
  2026-02-09  8:24 ` [PATCH V4 07/11] arm64: dts: imx8mm: " Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 09/11] arm64: dts: imx8mq: " Sherry Sun
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts |  5 +++++
 arch/arm64/boot/dts/freescale/imx8mp.dtsi    | 11 +++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 50850cb6d287..dfcdcc739ec6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -769,6 +769,7 @@ &pcie_phy {
 &pcie0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie0>;
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&gpio2 7 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_pcie0>;
 	vpcie3v3aux-supply = <&reg_pcie0>;
@@ -782,6 +783,10 @@ &pcie0_ep {
 	status = "disabled";
 };
 
+&pcie0_port0 {
+	reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
+};
+
 &pwm1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm1>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 9b2b3a9bf9e8..f66667735a02 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -2266,6 +2266,17 @@ pcie0: pcie: pcie@33800000 {
 			phys = <&pcie_phy>;
 			phy-names = "pcie-phy";
 			status = "disabled";
+
+			pcie0_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 
 		pcie0_ep: pcie_ep: pcie-ep@33800000 {
-- 
2.37.1



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

* [PATCH V4 09/11] arm64: dts: imx8mq: Add Root Port node and PERST property
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (7 preceding siblings ...)
  2026-02-09  8:24 ` [PATCH V4 08/11] arm64: dts: imx8mp: " Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 10/11] arm64: dts: imx8dxl/qm/qxp: " Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 11/11] arm64: dts: imx95: " Sherry Sun
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts | 10 +++++++++
 arch/arm64/boot/dts/freescale/imx8mq.dtsi    | 22 ++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index d48f901487d4..e7d87ea81b69 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -369,6 +369,7 @@ mipi_dsi_out: endpoint {
 &pcie0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie0>;
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&gpio5 28 GPIO_ACTIVE_LOW>;
 	clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>,
 		 <&pcie0_refclk>,
@@ -389,9 +390,14 @@ &pcie0_ep {
 	status = "disabled";
 };
 
+&pcie0_port0 {
+	reset-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>;
+};
+
 &pcie1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie1>;
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&gpio5 12 GPIO_ACTIVE_LOW>;
 	clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>,
 		 <&pcie0_refclk>,
@@ -414,6 +420,10 @@ &pcie1_ep {
 	status = "disabled";
 };
 
+&pcie1_port0 {
+	reset-gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
+};
+
 &pgc_gpu {
 	power-supply = <&sw1a_reg>;
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 607962f807be..de2ba4ee9da6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1768,6 +1768,17 @@ pcie0: pcie@33800000 {
 			assigned-clock-rates = <250000000>, <100000000>,
 			                       <10000000>;
 			status = "disabled";
+
+			pcie0_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 
 		pcie0_ep: pcie-ep@33800000 {
@@ -1846,6 +1857,17 @@ pcie1: pcie@33c00000 {
 			assigned-clock-rates = <250000000>, <100000000>,
 			                       <10000000>;
 			status = "disabled";
+
+			pcie1_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 
 		pcie1_ep: pcie-ep@33c00000 {
-- 
2.37.1



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

* [PATCH V4 10/11] arm64: dts: imx8dxl/qm/qxp: Add Root Port node and PERST property
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (8 preceding siblings ...)
  2026-02-09  8:24 ` [PATCH V4 09/11] arm64: dts: imx8mq: " Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  2026-02-09  8:24 ` [PATCH V4 11/11] arm64: dts: imx95: " Sherry Sun
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 .../boot/dts/freescale/imx8-ss-hsio.dtsi      | 11 ++++++++++
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts |  5 +++++
 arch/arm64/boot/dts/freescale/imx8qm-mek.dts  | 10 +++++++++
 .../boot/dts/freescale/imx8qm-ss-hsio.dtsi    | 22 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |  5 +++++
 5 files changed, 53 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi
index 469de8b536b5..009990b2e559 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi
@@ -78,6 +78,17 @@ pcieb: pcie@5f010000 {
 		power-domains = <&pd IMX_SC_R_PCIE_B>;
 		fsl,max-link-speed = <3>;
 		status = "disabled";
+
+		pcieb_port0: pcie@0 {
+			compatible = "pciclass,0604";
+			device_type = "pci";
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			bus-range = <0x01 0xff>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+		};
 	};
 
 	pcieb_ep: pcie-ep@5f010000 {
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
index 5c68d33e19f2..8f2c2bd00cde 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
@@ -651,6 +651,7 @@ &pcie0 {
 	phy-names = "pcie-phy";
 	pinctrl-0 = <&pinctrl_pcieb>;
 	pinctrl-names = "default";
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_pcieb>;
 	vpcie3v3aux-supply = <&reg_pcieb>;
@@ -667,6 +668,10 @@ &pcie0_ep {
 	status = "disabled";
 };
 
+&pcieb_port0 {
+	reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
+};
+
 &sai0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sai0>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
index dadc136aec6e..02f7589bd860 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -802,6 +802,7 @@ &pciea {
 	phy-names = "pcie-phy";
 	pinctrl-0 = <&pinctrl_pciea>;
 	pinctrl-names = "default";
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&lsio_gpio4 29 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_pciea>;
 	vpcie3v3aux-supply = <&reg_pciea>;
@@ -809,15 +810,24 @@ &pciea {
 	status = "okay";
 };
 
+&pciea_port0 {
+	reset-gpios = <&lsio_gpio4 29 GPIO_ACTIVE_LOW>;
+};
+
 &pcieb {
 	phys = <&hsio_phy 1 PHY_TYPE_PCIE 1>;
 	phy-names = "pcie-phy";
 	pinctrl-0 = <&pinctrl_pcieb>;
 	pinctrl-names = "default";
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&lsio_gpio5 0 GPIO_ACTIVE_LOW>;
 	status = "disabled";
 };
 
+&pcieb_port0 {
+	reset-gpios = <&lsio_gpio5 0 GPIO_ACTIVE_LOW>;
+};
+
 &qm_pwm_lvds0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm_lvds0>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-hsio.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-hsio.dtsi
index bd6e0aa27efe..48c29c2cfe8b 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-hsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-hsio.dtsi
@@ -40,6 +40,17 @@ pcie0: pciea: pcie@5f000000 {
 		power-domains = <&pd IMX_SC_R_PCIE_A>;
 		fsl,max-link-speed = <3>;
 		status = "disabled";
+
+		pciea_port0: pcie@0 {
+			compatible = "pciclass,0604";
+			device_type = "pci";
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			bus-range = <0x01 0xff>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+		};
 	};
 
 	pcie0_ep: pciea_ep: pcie-ep@5f000000 {
@@ -90,6 +101,17 @@ pcie1: pcieb: pcie@5f010000 {
 		power-domains = <&pd IMX_SC_R_PCIE_B>;
 		fsl,max-link-speed = <3>;
 		status = "disabled";
+
+		pcieb_port0: pcie@0 {
+			compatible = "pciclass,0604";
+			device_type = "pci";
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			bus-range = <0x01 0xff>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+		};
 	};
 
 	sata: sata@5f020000 {
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 40a0bc9f4e84..cd127d0a0a75 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -722,6 +722,7 @@ &pcie0 {
 	phy-names = "pcie-phy";
 	pinctrl-0 = <&pinctrl_pcieb>;
 	pinctrl-names = "default";
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_pcieb>;
 	vpcie3v3aux-supply = <&reg_pcieb>;
@@ -738,6 +739,10 @@ &pcie0_ep {
 	status = "disabled";
 };
 
+&pcieb_port0 {
+	reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
+};
+
 &scu_key {
 	status = "okay";
 };
-- 
2.37.1



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

* [PATCH V4 11/11] arm64: dts: imx95: Add Root Port node and PERST property
  2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
                   ` (9 preceding siblings ...)
  2026-02-09  8:24 ` [PATCH V4 10/11] arm64: dts: imx8dxl/qm/qxp: " Sherry Sun
@ 2026-02-09  8:24 ` Sherry Sun
  10 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-09  8:24 UTC (permalink / raw)
  To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
	kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam,
	will
  Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
	linux-kernel

Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 .../boot/dts/freescale/imx95-15x15-evk.dts    |  5 +++++
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 10 +++++++++
 arch/arm64/boot/dts/freescale/imx95.dtsi      | 22 +++++++++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
index d4184fb8b28c..42bc09e48b80 100644
--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
@@ -554,6 +554,7 @@ &netcmix_blk_ctrl {
 &pcie0 {
 	pinctrl-0 = <&pinctrl_pcie0>;
 	pinctrl-names = "default";
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&gpio5 13 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_m2_pwr>;
 	vpcie3v3aux-supply = <&reg_m2_pwr>;
@@ -568,6 +569,10 @@ &pcie0_ep {
 	status = "disabled";
 };
 
+&pcie0_port0 {
+	reset-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+};
+
 &sai1 {
 	assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
 			  <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index 041fd838fabb..6f193cf04119 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -540,6 +540,7 @@ &netc_timer {
 &pcie0 {
 	pinctrl-0 = <&pinctrl_pcie0>;
 	pinctrl-names = "default";
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&i2c7_pcal6524 5 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_pcie0>;
 	vpcie3v3aux-supply = <&reg_pcie0>;
@@ -554,9 +555,14 @@ &pcie0_ep {
 	status = "disabled";
 };
 
+&pcie0_port0 {
+	reset-gpios = <&i2c7_pcal6524 5 GPIO_ACTIVE_LOW>;
+};
+
 &pcie1 {
 	pinctrl-0 = <&pinctrl_pcie1>;
 	pinctrl-names = "default";
+	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&i2c7_pcal6524 16 GPIO_ACTIVE_LOW>;
 	vpcie-supply = <&reg_slot_pwr>;
 	vpcie3v3aux-supply = <&reg_slot_pwr>;
@@ -570,6 +576,10 @@ &pcie1_ep {
 	status = "disabled";
 };
 
+&pcie1_port0 {
+	reset-gpios = <&i2c7_pcal6524 16 GPIO_ACTIVE_LOW>;
+};
+
 &sai1 {
 	#sound-dai-cells = <0>;
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index 55e2da094c88..7c5f350fe3a4 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -1883,6 +1883,17 @@ pcie0: pcie@4c300000 {
 			iommu-map-mask = <0x1ff>;
 			fsl,max-link-speed = <3>;
 			status = "disabled";
+
+			pcie0_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 
 		pcie0_ep: pcie-ep@4c300000 {
@@ -1960,6 +1971,17 @@ pcie1: pcie@4c380000 {
 			iommu-map-mask = <0x1ff>;
 			fsl,max-link-speed = <3>;
 			status = "disabled";
+
+			pcie1_port0: pcie@0 {
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
 		};
 
 		pcie1_ep: pcie-ep@4c380000 {
-- 
2.37.1



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

* Re: [PATCH V4 02/11] PCI: host-generic: Add common helpers for parsing Root Port properties
  2026-02-09  8:24 ` [PATCH V4 02/11] PCI: host-generic: Add common helpers for parsing Root Port properties Sherry Sun
@ 2026-02-09 16:33   ` Frank Li
  2026-02-10  3:09     ` Sherry Sun
  0 siblings, 1 reply; 15+ messages in thread
From: Frank Li @ 2026-02-09 16:33 UTC (permalink / raw)
  To: Sherry Sun
  Cc: hongxing.zhu, l.stach, bhelgaas, lpieralisi, kwilczynski, mani,
	robh, krzk+dt, conor+dt, s.hauer, festevam, will, imx, kernel,
	linux-pci, linux-arm-kernel, devicetree, linux-kernel

On Mon, Feb 09, 2026 at 04:24:45PM +0800, Sherry Sun wrote:
> Introduce generic helper functions to parse Root Port device tree nodes
> and extract common properties like reset GPIOs. This allows multiple
> PCI host controller drivers to share the same parsing logic.
>
> Define struct pci_host_port to hold common Root Port properties and add
> pci_host_common_parse_ports() to parse Root Port nodes from device tree,
> pci_host_common_delete_ports() to cleanup the port lists.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
>  drivers/pci/controller/pci-host-common.c | 75 ++++++++++++++++++++++++
>  drivers/pci/controller/pci-host-common.h | 17 ++++++
>  2 files changed, 92 insertions(+)
>
> diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
> index c473e7c03bac..287e92df0092 100644
> --- a/drivers/pci/controller/pci-host-common.c
> +++ b/drivers/pci/controller/pci-host-common.c
> @@ -9,6 +9,7 @@
>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/of_pci.h>
> @@ -17,6 +18,80 @@
>
>  #include "pci-host-common.h"
>
> +/**
> + * pci_host_common_delete_ports - Cleanup function for port list
> + * @data: Pointer to the port list head
> + */
> +void pci_host_common_delete_ports(void *data)
> +{
> +	struct list_head *ports = data;
> +	struct pci_host_port *port, *tmp;
> +
> +	list_for_each_entry_safe(port, tmp, ports, list)
> +		list_del(&port->list);
> +}
> +EXPORT_SYMBOL_GPL(pci_host_common_delete_ports);
> +
> +/**
> + * pci_host_common_parse_port - Parse a single Root Port node
> + * @dev: Device pointer
> + * @node: Device tree node of the Root Port
> + * @ports: List head to add the parsed port to
> + *
> + * Returns: 0 on success, negative error code on failure
> + */
> +static int pci_host_common_parse_port(struct device *dev,
> +				      struct device_node *node,
> +				      struct list_head *ports)
> +{
> +	struct pci_host_port *port;
> +	struct gpio_desc *reset;
> +
> +	reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> +				      "reset", GPIOD_OUT_HIGH, "PERST#");
> +	if (IS_ERR(reset))
> +		return PTR_ERR(reset);
> +
> +	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> +	if (!port)
> +		return -ENOMEM;
> +
> +	port->reset = reset;
> +	INIT_LIST_HEAD(&port->list);
> +	list_add_tail(&port->list, ports);

Suppose need spin_lock for link list.

> +
> +	return 0;
> +}
> +
> +/**
> + * pci_host_common_parse_ports - Parse Root Port nodes from device tree
> + * @dev: Device pointer
> + * @ports: List head to store parsed ports
> + *
> + * This function iterates through child nodes of the host bridge and parses
> + * Root Port properties (currently only reset GPIO).
> + *
> + * Returns: 0 on success, -ENOENT if no ports found, other negative error codes
> + * on failure
> + */
> +int pci_host_common_parse_ports(struct device *dev, struct list_head *ports)
> +{
> +	int ret = -ENOENT;
> +
> +	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> +		if (!of_node_is_type(of_port, "pci"))
> +			continue;
> +		ret = pci_host_common_parse_port(dev, of_port, ports);
> +		if (ret) {
> +			pci_host_common_delete_ports(ports);
> +			return ret;
> +		}
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(pci_host_common_parse_ports);
> +
>  static void gen_pci_unmap_cfg(void *ptr)
>  {
>  	pci_ecam_free((struct pci_config_window *)ptr);
> diff --git a/drivers/pci/controller/pci-host-common.h b/drivers/pci/controller/pci-host-common.h
> index b5075d4bd7eb..2c8df230886f 100644
> --- a/drivers/pci/controller/pci-host-common.h
> +++ b/drivers/pci/controller/pci-host-common.h
> @@ -12,6 +12,23 @@
>
>  struct pci_ecam_ops;
>
> +/**
> + * struct pci_host_port - Generic Root Port properties
> + * @list: List node for linking multiple ports
> + * @reset: GPIO descriptor for PERST# signal
> + *
> + * This structure contains common properties that can be parsed from
> + * Root Port device tree nodes.
> + */
> +struct pci_host_port {
> +	struct list_head	list;
> +	struct gpio_desc	*reset;
> +};

I think it should be include/linux/pci.h

struct pci_host_bridge {
	...
	struct list_head ports_header;
}

So all API should pass down struct pci_host_bridge *.

Frank
> +
> +void pci_host_common_delete_ports(void *data);
> +int pci_host_common_parse_ports(struct device *dev,
> +				struct list_head *ports);
> +
>  int pci_host_common_probe(struct platform_device *pdev);
>  int pci_host_common_init(struct platform_device *pdev,
>  			 struct pci_host_bridge *bridge,
> --
> 2.37.1
>


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

* Re: [PATCH V4 03/11] PCI: imx6: Add support for parsing the reset property in new Root Port binding
  2026-02-09  8:24 ` [PATCH V4 03/11] PCI: imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
@ 2026-02-09 16:35   ` Frank Li
  0 siblings, 0 replies; 15+ messages in thread
From: Frank Li @ 2026-02-09 16:35 UTC (permalink / raw)
  To: Sherry Sun
  Cc: hongxing.zhu, l.stach, bhelgaas, lpieralisi, kwilczynski, mani,
	robh, krzk+dt, conor+dt, s.hauer, festevam, will, imx, kernel,
	linux-pci, linux-arm-kernel, devicetree, linux-kernel

On Mon, Feb 09, 2026 at 04:24:46PM +0800, Sherry Sun wrote:
> DT binding allows specifying 'reset' property in both host bridge and
> Root Port nodes, but specifying in the host bridge node is marked as
> deprecated. So add support for parsing the new binding that uses
> 'reset-gpios' property for PERST#.
>
> The initial idea is to add the PCIe M.2 KeyE connector support and PCI
> power control framework to the pcie-imx6 driver. Since the new
> M.2/pwrctrl model is implemented based on Root Ports and requires the
> pwrctrl driver to bind to a Root Port device, we need to introduce a
> Root Port child node on i.MX boards that provide an M.2 connector.
>
> To follow a more standardized DT structure, it also makes sense to move
> the reset-gpios and wake-gpios properties into the Root Port node. These
> signals logically belong to the Root Port rather than the host bridge,
> and placing them there aligns with the new M.2/pwrctrl model.
>
> To maintain DT backwards compatibility, fallback to the legacy method of
> parsing the host bridge node if the reset property is not present in the
> Root Port node.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 69 +++++++++++++++++++++------
>  1 file changed, 55 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index a5b8d0b71677..317a969da96b 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -34,6 +34,7 @@
>  #include <linux/pm_runtime.h>
>
>  #include "../../pci.h"
> +#include "../pci-host-common.h"
>  #include "pcie-designware.h"
>
>  #define IMX8MQ_GPR_PCIE_REF_USE_PAD		BIT(9)
> @@ -150,8 +151,8 @@ struct imx_lut_data {
>
>  struct imx_pcie {
>  	struct dw_pcie		*pci;
> -	struct gpio_desc	*reset_gpiod;
>  	struct clk_bulk_data	*clks;
> +	struct list_head	ports;
>  	int			num_clks;
>  	bool			supports_clkreq;
>  	bool			enable_ext_refclk;
> @@ -897,29 +898,34 @@ static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
>
>  static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
>  {
> +	struct pci_host_port *port;
> +
>  	reset_control_assert(imx_pcie->pciephy_reset);
>
>  	if (imx_pcie->drvdata->core_reset)
>  		imx_pcie->drvdata->core_reset(imx_pcie, true);
>
>  	/* Some boards don't have PCIe reset GPIO. */
> -	gpiod_set_value_cansleep(imx_pcie->reset_gpiod, 1);
> +	list_for_each_entry(port, &imx_pcie->ports, list)
> +		gpiod_set_value_cansleep(port->reset, 1);
>  }
>
>  static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
>  {
> +	struct pci_host_port *port;
> +
>  	reset_control_deassert(imx_pcie->pciephy_reset);
>
>  	if (imx_pcie->drvdata->core_reset)
>  		imx_pcie->drvdata->core_reset(imx_pcie, false);
>
>  	/* Some boards don't have PCIe reset GPIO. */
> -	if (imx_pcie->reset_gpiod) {
> -		msleep(100);
> -		gpiod_set_value_cansleep(imx_pcie->reset_gpiod, 0);
> -		/* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
> -		msleep(100);
> -	}
> +	list_for_each_entry(port, &imx_pcie->ports, list)
> +		if (port->reset) {
> +			msleep(PCIE_T_PVPERL_MS);
> +			gpiod_set_value_cansleep(port->reset, 0);
> +			msleep(PCIE_RESET_CONFIG_WAIT_MS);
> +		}
>
>  	return 0;
>  }
> @@ -1642,6 +1648,27 @@ static const struct dev_pm_ops imx_pcie_pm_ops = {
>  				  imx_pcie_resume_noirq)
>  };
>
> +static int imx_pcie_parse_legacy_binding(struct imx_pcie *pcie)
> +{
> +	struct device *dev = pcie->pci->dev;
> +	struct pci_host_port *port;
> +	struct gpio_desc *reset;
> +
> +	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
> +	if (IS_ERR(reset))
> +		return PTR_ERR(reset);
> +
> +	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> +	if (!port)
> +		return -ENOMEM;
> +
> +	port->reset = reset;
> +	INIT_LIST_HEAD(&port->list);
> +	list_add_tail(&port->list, &pcie->ports);
> +
> +	return 0;
> +}
> +
>  static int imx_pcie_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -1660,6 +1687,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
>  	if (!pci)
>  		return -ENOMEM;
>
> +	INIT_LIST_HEAD(&imx_pcie->ports);
> +
>  	pci->dev = dev;
>  	pci->ops = &dw_pcie_ops;
>
> @@ -1688,12 +1717,24 @@ static int imx_pcie_probe(struct platform_device *pdev)
>  			return PTR_ERR(imx_pcie->phy_base);
>  	}
>
> -	/* Fetch GPIOs */
> -	imx_pcie->reset_gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
> -	if (IS_ERR(imx_pcie->reset_gpiod))
> -		return dev_err_probe(dev, PTR_ERR(imx_pcie->reset_gpiod),
> -				     "unable to get reset gpio\n");
> -	gpiod_set_consumer_name(imx_pcie->reset_gpiod, "PCIe reset");
> +	ret = pci_host_common_parse_ports(dev, &imx_pcie->ports);

if API provided pcim_host_common_parse_ports(), needn't below
devm_add_action_or_reset().

Frank.

> +	if (ret) {
> +		if (ret != -ENOENT)
> +			return dev_err_probe(dev, ret, "Failed to parse Root Port: %d\n", ret);
> +
> +		/*
> +		 * In the case of properties not populated in Root Port node,
> +		 * fallback to the legacy method of parsing the Host Bridge
> +		 * node. This is to maintain DT backwards compatibility.
> +		 */
> +		ret = imx_pcie_parse_legacy_binding(imx_pcie);
> +		if (ret)
> +			return dev_err_probe(dev, ret, "Unable to get reset gpio: %d\n", ret);
> +	}
> +
> +	ret = devm_add_action_or_reset(dev, pci_host_common_delete_ports, &imx_pcie->ports);
> +	if (ret)
> +		return ret;
>
>  	/* Fetch clocks */
>  	imx_pcie->num_clks = devm_clk_bulk_get_all(dev, &imx_pcie->clks);
> --
> 2.37.1
>


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

* RE: [PATCH V4 02/11] PCI: host-generic: Add common helpers for parsing Root Port properties
  2026-02-09 16:33   ` Frank Li
@ 2026-02-10  3:09     ` Sherry Sun
  0 siblings, 0 replies; 15+ messages in thread
From: Sherry Sun @ 2026-02-10  3:09 UTC (permalink / raw)
  To: Frank Li
  Cc: Hongxing Zhu, l.stach@pengutronix.de, bhelgaas@google.com,
	lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org,
	robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	s.hauer@pengutronix.de, festevam@gmail.com, will@kernel.org,
	imx@lists.linux.dev, kernel@pengutronix.de,
	linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org

> Subject: Re: [PATCH V4 02/11] PCI: host-generic: Add common helpers for
> parsing Root Port properties
> 
> On Mon, Feb 09, 2026 at 04:24:45PM +0800, Sherry Sun wrote:
> > Introduce generic helper functions to parse Root Port device tree
> > nodes and extract common properties like reset GPIOs. This allows
> > multiple PCI host controller drivers to share the same parsing logic.
> >
> > Define struct pci_host_port to hold common Root Port properties and
> > add
> > pci_host_common_parse_ports() to parse Root Port nodes from device
> > tree,
> > pci_host_common_delete_ports() to cleanup the port lists.
> >
> > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > ---
> >  drivers/pci/controller/pci-host-common.c | 75
> > ++++++++++++++++++++++++  drivers/pci/controller/pci-host-common.h |
> > 17 ++++++
> >  2 files changed, 92 insertions(+)
> >
> > diff --git a/drivers/pci/controller/pci-host-common.c
> > b/drivers/pci/controller/pci-host-common.c
> > index c473e7c03bac..287e92df0092 100644
> > --- a/drivers/pci/controller/pci-host-common.c
> > +++ b/drivers/pci/controller/pci-host-common.c
> > @@ -9,6 +9,7 @@
> >
> >  #include <linux/kernel.h>
> >  #include <linux/module.h>
> > +#include <linux/gpio/consumer.h>
> >  #include <linux/of.h>
> >  #include <linux/of_address.h>
> >  #include <linux/of_pci.h>
> > @@ -17,6 +18,80 @@
> >
> >  #include "pci-host-common.h"
> >
> > +/**
> > + * pci_host_common_delete_ports - Cleanup function for port list
> > + * @data: Pointer to the port list head  */ void
> > +pci_host_common_delete_ports(void *data) {
> > +	struct list_head *ports = data;
> > +	struct pci_host_port *port, *tmp;
> > +
> > +	list_for_each_entry_safe(port, tmp, ports, list)
> > +		list_del(&port->list);
> > +}
> > +EXPORT_SYMBOL_GPL(pci_host_common_delete_ports);
> > +
> > +/**
> > + * pci_host_common_parse_port - Parse a single Root Port node
> > + * @dev: Device pointer
> > + * @node: Device tree node of the Root Port
> > + * @ports: List head to add the parsed port to
> > + *
> > + * Returns: 0 on success, negative error code on failure  */ static
> > +int pci_host_common_parse_port(struct device *dev,
> > +				      struct device_node *node,
> > +				      struct list_head *ports)
> > +{
> > +	struct pci_host_port *port;
> > +	struct gpio_desc *reset;
> > +
> > +	reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> > +				      "reset", GPIOD_OUT_HIGH, "PERST#");
> > +	if (IS_ERR(reset))
> > +		return PTR_ERR(reset);
> > +
> > +	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> > +	if (!port)
> > +		return -ENOMEM;
> > +
> > +	port->reset = reset;
> > +	INIT_LIST_HEAD(&port->list);
> > +	list_add_tail(&port->list, ports);
> 
> Suppose need spin_lock for link list.

Hi Frank,
I think a spinlock is not necessary in this case for the following reasons:
1. The ports list is private to each device instance, not a globally shared resource.
2. The list is built during the driver probe phase(pci_host_common_parse_ports),
    which is serialized by the driver core. And the list cleanup
    (pci_host_common_delete_ports) is registered as a devm action and only
    called during device removal, which is also serialized by the driver core. There
    should no concurrent access during list construction.
3. Once the ports list is populated during probe, it's not modified during runtime.
    There are no code paths that add/remove ports after initialization completes.
4. There's no scenario where multiple threads would simultaneously access or
     modify this list during normal operation.
So at least currently seems spinlock would not provide any actual protection benefit.

> 
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * pci_host_common_parse_ports - Parse Root Port nodes from device
> > +tree
> > + * @dev: Device pointer
> > + * @ports: List head to store parsed ports
> > + *
> > + * This function iterates through child nodes of the host bridge and
> > +parses
> > + * Root Port properties (currently only reset GPIO).
> > + *
> > + * Returns: 0 on success, -ENOENT if no ports found, other negative
> > +error codes
> > + * on failure
> > + */
> > +int pci_host_common_parse_ports(struct device *dev, struct list_head
> > +*ports) {
> > +	int ret = -ENOENT;
> > +
> > +	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> > +		if (!of_node_is_type(of_port, "pci"))
> > +			continue;
> > +		ret = pci_host_common_parse_port(dev, of_port, ports);
> > +		if (ret) {
> > +			pci_host_common_delete_ports(ports);
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(pci_host_common_parse_ports);
> > +
> >  static void gen_pci_unmap_cfg(void *ptr)  {
> >  	pci_ecam_free((struct pci_config_window *)ptr); diff --git
> > a/drivers/pci/controller/pci-host-common.h
> > b/drivers/pci/controller/pci-host-common.h
> > index b5075d4bd7eb..2c8df230886f 100644
> > --- a/drivers/pci/controller/pci-host-common.h
> > +++ b/drivers/pci/controller/pci-host-common.h
> > @@ -12,6 +12,23 @@
> >
> >  struct pci_ecam_ops;
> >
> > +/**
> > + * struct pci_host_port - Generic Root Port properties
> > + * @list: List node for linking multiple ports
> > + * @reset: GPIO descriptor for PERST# signal
> > + *
> > + * This structure contains common properties that can be parsed from
> > + * Root Port device tree nodes.
> > + */
> > +struct pci_host_port {
> > +	struct list_head	list;
> > +	struct gpio_desc	*reset;
> > +};
> 
> I think it should be include/linux/pci.h
> 
> struct pci_host_bridge {
> 	...
> 	struct list_head ports_header;
> }
> 
> So all API should pass down struct pci_host_bridge *.

Ok, this sounds reasonable,  will try this in V5.

Best Regards
Sherry
> 
> Frank
> > +
> > +void pci_host_common_delete_ports(void *data); int
> > +pci_host_common_parse_ports(struct device *dev,
> > +				struct list_head *ports);
> > +
> >  int pci_host_common_probe(struct platform_device *pdev);  int
> > pci_host_common_init(struct platform_device *pdev,
> >  			 struct pci_host_bridge *bridge,
> > --
> > 2.37.1
> >


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

end of thread, other threads:[~2026-02-10  3:09 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-09  8:24 [PATCH V4 00/11] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
2026-02-09  8:24 ` [PATCH V4 01/11] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node Sherry Sun
2026-02-09  8:24 ` [PATCH V4 02/11] PCI: host-generic: Add common helpers for parsing Root Port properties Sherry Sun
2026-02-09 16:33   ` Frank Li
2026-02-10  3:09     ` Sherry Sun
2026-02-09  8:24 ` [PATCH V4 03/11] PCI: imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
2026-02-09 16:35   ` Frank Li
2026-02-09  8:24 ` [PATCH V4 04/11] arm: dts: imx6qdl: Add Root Port node and PERST property Sherry Sun
2026-02-09  8:24 ` [PATCH V4 05/11] arm: dts: imx6sx: " Sherry Sun
2026-02-09  8:24 ` [PATCH V4 06/11] arm: dts: imx7d: " Sherry Sun
2026-02-09  8:24 ` [PATCH V4 07/11] arm64: dts: imx8mm: " Sherry Sun
2026-02-09  8:24 ` [PATCH V4 08/11] arm64: dts: imx8mp: " Sherry Sun
2026-02-09  8:24 ` [PATCH V4 09/11] arm64: dts: imx8mq: " Sherry Sun
2026-02-09  8:24 ` [PATCH V4 10/11] arm64: dts: imx8dxl/qm/qxp: " Sherry Sun
2026-02-09  8:24 ` [PATCH V4 11/11] arm64: dts: imx95: " Sherry Sun

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