* [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding
@ 2026-02-13 4:08 Sherry Sun
2026-02-13 4:08 ` [PATCH V5 01/12] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node Sherry Sun
` (11 more replies)
0 siblings, 12 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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
(currently only reset GPIO descriptor) and add
pci_host_common_parse_ports() to parse Root Port nodes from device tree.
Also add the 'ports' list to struct pci_host_bridge for better maintain
parsed Root Port information.
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 V5:
1. Add the Root Port list(pci_host_port) to struct pci_host_bridge for better
maintain parsed Root Port information.
2. Delete the pci_host_common_delete_ports() as now the Root Port list in
pci_host_bridge can be cleared by pci_release_host_bridge_dev().
3. Change the common API pci_host_common_parse_ports() pass down struct
pci_host_bridge *.
4. Modify dw_pcie_host_init() to allow drivers to pre-allocate pci_host_bridge
struct when needed.
5. Allocate bridge early in imx_pcie_probe() to parse Root Ports.
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 (12):
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: dwc: Allow external allocation of pci_host_bridge
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 | 81 +++++++++++++++----
.../pci/controller/dwc/pcie-designware-host.c | 12 ++-
drivers/pci/controller/pci-host-common.c | 58 +++++++++++++
drivers/pci/controller/pci-host-common.h | 15 ++++
drivers/pci/probe.c | 2 +
include/linux/pci.h | 1 +
28 files changed, 390 insertions(+), 18 deletions(-)
--
2.37.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH V5 01/12] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties Sherry Sun
` (10 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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] 23+ messages in thread
* [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
2026-02-13 4:08 ` [PATCH V5 01/12] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-16 16:21 ` Manivannan Sadhasivam
2026-02-13 4:08 ` [PATCH V5 03/12] PCI: dwc: Allow external allocation of pci_host_bridge Sherry Sun
` (9 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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
(currently only reset GPIO descriptor) and add
pci_host_common_parse_ports() to parse Root Port nodes from device tree.
Also add the 'ports' list to struct pci_host_bridge for better maintain
parsed Root Port information.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
drivers/pci/controller/pci-host-common.c | 58 ++++++++++++++++++++++++
drivers/pci/controller/pci-host-common.h | 15 ++++++
drivers/pci/probe.c | 2 +
include/linux/pci.h | 1 +
4 files changed, 76 insertions(+)
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index d6258c1cffe5..0c35907a5076 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,63 @@
#include "pci-host-common.h"
+/**
+ * pci_host_common_parse_port - Parse a single Root Port node
+ * @bridge: PCI host bridge
+ * @node: Device tree node of the Root Port
+ *
+ * Returns: 0 on success, negative error code on failure
+ */
+static int pci_host_common_parse_port(struct pci_host_bridge *bridge,
+ struct device_node *node)
+{
+ struct device *dev = &bridge->dev;
+ 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, &bridge->ports);
+
+ return 0;
+}
+
+/**
+ * pci_host_common_parse_ports - Parse Root Port nodes from device tree
+ * @bridge: PCI host bridge
+ *
+ * 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 pci_host_bridge *bridge)
+{
+ struct device *dev = &bridge->dev;
+ 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(bridge, of_port);
+ if (ret)
+ 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..25d808319836 100644
--- a/drivers/pci/controller/pci-host-common.h
+++ b/drivers/pci/controller/pci-host-common.h
@@ -12,6 +12,21 @@
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;
+};
+
+int pci_host_common_parse_ports(struct pci_host_bridge *bridge);
+
int pci_host_common_probe(struct platform_device *pdev);
int pci_host_common_init(struct platform_device *pdev,
struct pci_host_bridge *bridge,
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2975974f35e8..007a3fb8da86 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -647,6 +647,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
pci_free_resource_list(&bridge->windows);
pci_free_resource_list(&bridge->dma_ranges);
+ pci_free_resource_list(&bridge->ports);
/* Host bridges only have domain_nr set in the emulation case */
if (bridge->domain_nr != PCI_DOMAIN_NR_NOT_SET)
@@ -671,6 +672,7 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
{
INIT_LIST_HEAD(&bridge->windows);
INIT_LIST_HEAD(&bridge->dma_ranges);
+ INIT_LIST_HEAD(&bridge->ports);
/*
* We assume we can manage these PCIe features. Some systems may
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1c270f1d5123..b05482355abc 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -634,6 +634,7 @@ struct pci_host_bridge {
int domain_nr;
struct list_head windows; /* resource_entry */
struct list_head dma_ranges; /* dma ranges resource list */
+ struct list_head ports; /* Root Port list (pci_host_port) */
#ifdef CONFIG_PCI_IDE
u16 nr_ide_streams; /* Max streams possibly active in @ide_stream_ida */
struct ida ide_stream_ida;
--
2.37.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH V5 03/12] PCI: dwc: Allow external allocation of pci_host_bridge
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
2026-02-13 4:08 ` [PATCH V5 01/12] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node Sherry Sun
2026-02-13 4:08 ` [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 15:29 ` Frank Li
2026-02-13 4:08 ` [PATCH V5 04/12] PCI: imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (8 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
linux-kernel
Currently, dw_pcie_host_init() always allocates a new pci_host_bridge
structure internally using devm_pci_alloc_host_bridge(). This prevents
drivers from pre-allocating the bridge structure when needed.
Modify dw_pcie_host_init() to check if pp->bridge is already set. If
set, use the pre-allocated bridge instead of allocating a new one. This
maintains backward compatibility with existing drivers that don't set
pp->bridge, while allowing new drivers to pre-allocate when needed.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 6ae6189e9b8a..c2de9830e1e9 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -575,11 +575,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
raw_spin_lock_init(&pp->lock);
- bridge = devm_pci_alloc_host_bridge(dev, 0);
- if (!bridge)
- return -ENOMEM;
+ if (!pp->bridge) {
+ bridge = devm_pci_alloc_host_bridge(dev, 0);
+ if (!bridge)
+ return -ENOMEM;
- pp->bridge = bridge;
+ pp->bridge = bridge;
+ } else {
+ bridge = pp->bridge;
+ }
ret = dw_pcie_host_get_resources(pp);
if (ret)
--
2.37.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH V5 04/12] PCI: imx6: Add support for parsing the reset property in new Root Port binding
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (2 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 03/12] PCI: dwc: Allow external allocation of pci_host_bridge Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 15:32 ` Frank Li
2026-02-13 4:08 ` [PATCH V5 05/12] arm: dts: imx6qdl: Add Root Port node and PERST property Sherry Sun
` (7 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
Cc: imx, kernel, linux-pci, linux-arm-kernel, devicetree,
linux-kernel
The current DT binding for pci-imx6 specifies the 'reset-gpios' property
in the host bridge node. However, the PERST# signal logically belongs to
individual Root Ports rather than the host bridge itself. This becomes
important when supporting PCIe KeyE connector and PCI power control
framework for pci-imx6 driver, which requires properties to be specified
in Root Port nodes.
Add support for parsing 'reset-gpios' from Root Port child nodes using
the common helper pci_host_common_parse_ports(). The parsed reset GPIOs
are stored in the bridge's ports list and accessed during core reset
operations. Pre-allocate pci_host_bridge in imx_pcie_probe() for RC mode
to enable early Root Port parsing.
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 | 81 ++++++++++++++++++++++-----
1 file changed, 67 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index a5b8d0b71677..75afd56dad50 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,7 +151,6 @@ struct imx_lut_data {
struct imx_pcie {
struct dw_pcie *pci;
- struct gpio_desc *reset_gpiod;
struct clk_bulk_data *clks;
int num_clks;
bool supports_clkreq;
@@ -897,29 +897,40 @@ 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 dw_pcie *pci = imx_pcie->pci;
+ struct pci_host_bridge *bridge = pci->pp.bridge;
+ 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);
+ if (bridge)
+ list_for_each_entry(port, &bridge->ports, list)
+ gpiod_set_value_cansleep(port->reset, 1);
}
static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
{
+ struct dw_pcie *pci = imx_pcie->pci;
+ struct pci_host_bridge *bridge = pci->pp.bridge;
+ 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);
- }
+ if (bridge)
+ list_for_each_entry(port, &bridge->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,11 +1653,39 @@ 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_bridge *bridge = pcie->pci->pp.bridge;
+ struct pci_host_port *port;
+ struct gpio_desc *reset;
+
+ if (!bridge) {
+ dev_err(dev, "Bridge not allocated yet\n");
+ return -EINVAL;
+ }
+
+ 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, &bridge->ports);
+
+ return 0;
+}
+
static int imx_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dw_pcie *pci;
struct imx_pcie *imx_pcie;
+ struct pci_host_bridge *bridge;
struct device_node *np;
struct device_node *node = dev->of_node;
int i, ret, domain;
@@ -1688,12 +1727,26 @@ 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");
+ /* For RC mode, allocate bridge early so we can parse Root Ports. */
+ if (imx_pcie->drvdata->mode != DW_PCIE_EP_TYPE) {
+ bridge = devm_pci_alloc_host_bridge(dev, 0);
+ if (!bridge)
+ return -ENOMEM;
+
+ pci->pp.bridge = bridge;
+
+ /* Parse Root Port nodes */
+ ret = pci_host_common_parse_ports(bridge);
+ if (ret) {
+ if (ret != -ENOENT)
+ return dev_err_probe(dev, ret, "Failed to parse Root Port\n");
+
+ /* Fallback to legacy binding for DT backwards compatibility */
+ ret = imx_pcie_parse_legacy_binding(imx_pcie);
+ if (ret)
+ return dev_err_probe(dev, ret, "Unable to get reset gpio\n");
+ }
+ }
/* Fetch clocks */
imx_pcie->num_clks = devm_clk_bulk_get_all(dev, &imx_pcie->clks);
--
2.37.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH V5 05/12] arm: dts: imx6qdl: Add Root Port node and PERST property
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (3 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 04/12] PCI: imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 06/12] arm: dts: imx6sx: " Sherry Sun
` (6 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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 = <®_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] 23+ messages in thread
* [PATCH V5 06/12] arm: dts: imx6sx: Add Root Port node and PERST property
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (4 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 05/12] arm: dts: imx6qdl: Add Root Port node and PERST property Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 07/12] arm: dts: imx7d: " Sherry Sun
` (5 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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 = <®_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] 23+ messages in thread
* [PATCH V5 07/12] arm: dts: imx7d: Add Root Port node and PERST property
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (5 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 06/12] arm: dts: imx6sx: " Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 08/12] arm64: dts: imx8mm: " Sherry Sun
` (4 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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>;
+};
+
®_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] 23+ messages in thread
* [PATCH V5 08/12] arm64: dts: imx8mm: Add Root Port node and PERST property
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (6 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 07/12] arm: dts: imx7d: " Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 09/12] arm64: dts: imx8mp: " Sherry Sun
` (3 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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] 23+ messages in thread
* [PATCH V5 09/12] arm64: dts: imx8mp: Add Root Port node and PERST property
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (7 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 08/12] arm64: dts: imx8mm: " Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 10/12] arm64: dts: imx8mq: " Sherry Sun
` (2 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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 = <®_pcie0>;
vpcie3v3aux-supply = <®_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] 23+ messages in thread
* [PATCH V5 10/12] arm64: dts: imx8mq: Add Root Port node and PERST property
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (8 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 09/12] arm64: dts: imx8mp: " Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 11/12] arm64: dts: imx8dxl/qm/qxp: " Sherry Sun
2026-02-13 4:08 ` [PATCH V5 12/12] arm64: dts: imx95: " Sherry Sun
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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] 23+ messages in thread
* [PATCH V5 11/12] arm64: dts: imx8dxl/qm/qxp: Add Root Port node and PERST property
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (9 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 10/12] arm64: dts: imx8mq: " Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 12/12] arm64: dts: imx95: " Sherry Sun
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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 = <®_pcieb>;
vpcie3v3aux-supply = <®_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 = <®_pciea>;
vpcie3v3aux-supply = <®_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 = <®_pcieb>;
vpcie3v3aux-supply = <®_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] 23+ messages in thread
* [PATCH V5 12/12] arm64: dts: imx95: Add Root Port node and PERST property
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
` (10 preceding siblings ...)
2026-02-13 4:08 ` [PATCH V5 11/12] arm64: dts: imx8dxl/qm/qxp: " Sherry Sun
@ 2026-02-13 4:08 ` Sherry Sun
11 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-13 4:08 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, krzk+dt, conor+dt, s.hauer, festevam
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 = <®_m2_pwr>;
vpcie3v3aux-supply = <®_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 = <®_pcie0>;
vpcie3v3aux-supply = <®_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 = <®_slot_pwr>;
vpcie3v3aux-supply = <®_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] 23+ messages in thread
* Re: [PATCH V5 03/12] PCI: dwc: Allow external allocation of pci_host_bridge
2026-02-13 4:08 ` [PATCH V5 03/12] PCI: dwc: Allow external allocation of pci_host_bridge Sherry Sun
@ 2026-02-13 15:29 ` Frank Li
2026-02-16 16:25 ` Manivannan Sadhasivam
0 siblings, 1 reply; 23+ messages in thread
From: Frank Li @ 2026-02-13 15:29 UTC (permalink / raw)
To: Sherry Sun
Cc: hongxing.zhu, l.stach, bhelgaas, lpieralisi, kwilczynski, mani,
robh, krzk+dt, conor+dt, s.hauer, festevam, imx, kernel,
linux-pci, linux-arm-kernel, devicetree, linux-kernel
On Fri, Feb 13, 2026 at 12:08:43PM +0800, Sherry Sun wrote:
> Currently, dw_pcie_host_init() always allocates a new pci_host_bridge
> structure internally using devm_pci_alloc_host_bridge(). This prevents
> drivers from pre-allocating the bridge structure when needed.
>
> Modify dw_pcie_host_init() to check if pp->bridge is already set. If
> set, use the pre-allocated bridge instead of allocating a new one. This
> maintains backward compatibility with existing drivers that don't set
> pp->bridge, while allowing new drivers to pre-allocate when needed.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
> drivers/pci/controller/dwc/pcie-designware-host.c | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 6ae6189e9b8a..c2de9830e1e9 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -575,11 +575,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>
> raw_spin_lock_init(&pp->lock);
>
> - bridge = devm_pci_alloc_host_bridge(dev, 0);
> - if (!bridge)
> - return -ENOMEM;
> + if (!pp->bridge) {
> + bridge = devm_pci_alloc_host_bridge(dev, 0);
It'd better call parse port here, or in devm_pci_alloc_host_bridge().
If that, needn't check pp->bridge.
Frank
> + if (!bridge)
> + return -ENOMEM;
>
> - pp->bridge = bridge;
> + pp->bridge = bridge;
> + } else {
> + bridge = pp->bridge;
> + }
>
> ret = dw_pcie_host_get_resources(pp);
> if (ret)
> --
> 2.37.1
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH V5 04/12] PCI: imx6: Add support for parsing the reset property in new Root Port binding
2026-02-13 4:08 ` [PATCH V5 04/12] PCI: imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
@ 2026-02-13 15:32 ` Frank Li
0 siblings, 0 replies; 23+ messages in thread
From: Frank Li @ 2026-02-13 15:32 UTC (permalink / raw)
To: Sherry Sun
Cc: hongxing.zhu, l.stach, bhelgaas, lpieralisi, kwilczynski, mani,
robh, krzk+dt, conor+dt, s.hauer, festevam, imx, kernel,
linux-pci, linux-arm-kernel, devicetree, linux-kernel
On Fri, Feb 13, 2026 at 12:08:44PM +0800, Sherry Sun wrote:
> The current DT binding for pci-imx6 specifies the 'reset-gpios' property
> in the host bridge node. However, the PERST# signal logically belongs to
> individual Root Ports rather than the host bridge itself. This becomes
> important when supporting PCIe KeyE connector and PCI power control
> framework for pci-imx6 driver, which requires properties to be specified
> in Root Port nodes.
>
> Add support for parsing 'reset-gpios' from Root Port child nodes using
> the common helper pci_host_common_parse_ports(). The parsed reset GPIOs
> are stored in the bridge's ports list and accessed during core reset
> operations. Pre-allocate pci_host_bridge in imx_pcie_probe() for RC mode
> to enable early Root Port parsing.
>
> 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 | 81 ++++++++++++++++++++++-----
> 1 file changed, 67 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index a5b8d0b71677..75afd56dad50 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,7 +151,6 @@ struct imx_lut_data {
>
> struct imx_pcie {
> struct dw_pcie *pci;
> - struct gpio_desc *reset_gpiod;
> struct clk_bulk_data *clks;
> int num_clks;
> bool supports_clkreq;
> @@ -897,29 +897,40 @@ 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 dw_pcie *pci = imx_pcie->pci;
> + struct pci_host_bridge *bridge = pci->pp.bridge;
> + 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);
> + if (bridge)
> + list_for_each_entry(port, &bridge->ports, list)
> + gpiod_set_value_cansleep(port->reset, 1);
> }
>
> static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
> {
> + struct dw_pcie *pci = imx_pcie->pci;
> + struct pci_host_bridge *bridge = pci->pp.bridge;
> + 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);
> - }
> + if (bridge)
> + list_for_each_entry(port, &bridge->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,11 +1653,39 @@ 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_bridge *bridge = pcie->pci->pp.bridge;
> + struct pci_host_port *port;
> + struct gpio_desc *reset;
> +
> + if (!bridge) {
> + dev_err(dev, "Bridge not allocated yet\n");
> + return -EINVAL;
> + }
> +
> + 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, &bridge->ports);
> +
> + return 0;
> +}
> +
> static int imx_pcie_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> struct dw_pcie *pci;
> struct imx_pcie *imx_pcie;
> + struct pci_host_bridge *bridge;
> struct device_node *np;
> struct device_node *node = dev->of_node;
> int i, ret, domain;
> @@ -1688,12 +1727,26 @@ 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");
> + /* For RC mode, allocate bridge early so we can parse Root Ports. */
> + if (imx_pcie->drvdata->mode != DW_PCIE_EP_TYPE) {
> + bridge = devm_pci_alloc_host_bridge(dev, 0);
> + if (!bridge)
> + return -ENOMEM;
> +
> + pci->pp.bridge = bridge;
> +
> + /* Parse Root Port nodes */
> + ret = pci_host_common_parse_ports(bridge);
> + if (ret) {
> + if (ret != -ENOENT)
> + return dev_err_probe(dev, ret, "Failed to parse Root Port\n");
> +
> + /* Fallback to legacy binding for DT backwards compatibility */
> + ret = imx_pcie_parse_legacy_binding(imx_pcie);
> + if (ret)
> + return dev_err_probe(dev, ret, "Unable to get reset gpio\n");
> + }
> + }
if parse in dwc or in devm_pci_alloc_host_bridge(), needn't these code
here.
Frank
>
> /* Fetch clocks */
> imx_pcie->num_clks = devm_clk_bulk_get_all(dev, &imx_pcie->clks);
> --
> 2.37.1
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
2026-02-13 4:08 ` [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties Sherry Sun
@ 2026-02-16 16:21 ` Manivannan Sadhasivam
2026-02-24 10:24 ` Sherry Sun
0 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-16 16:21 UTC (permalink / raw)
To: Sherry Sun
Cc: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, robh, krzk+dt, conor+dt, s.hauer, festevam, imx,
kernel, linux-pci, linux-arm-kernel, devicetree, linux-kernel
On Fri, Feb 13, 2026 at 12:08:42PM +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
> (currently only reset GPIO descriptor) and add
> pci_host_common_parse_ports() to parse Root Port nodes from device tree.
>
> Also add the 'ports' list to struct pci_host_bridge for better maintain
> parsed Root Port information.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
> drivers/pci/controller/pci-host-common.c | 58 ++++++++++++++++++++++++
> drivers/pci/controller/pci-host-common.h | 15 ++++++
> drivers/pci/probe.c | 2 +
> include/linux/pci.h | 1 +
> 4 files changed, 76 insertions(+)
>
> diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
> index d6258c1cffe5..0c35907a5076 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,63 @@
>
> #include "pci-host-common.h"
>
> +/**
> + * pci_host_common_parse_port - Parse a single Root Port node
> + * @bridge: PCI host bridge
> + * @node: Device tree node of the Root Port
> + *
> + * Returns: 0 on success, negative error code on failure
> + */
> +static int pci_host_common_parse_port(struct pci_host_bridge *bridge,
> + struct device_node *node)
> +{
> + struct device *dev = &bridge->dev;
> + struct pci_host_port *port;
> + struct gpio_desc *reset;
> +
> + reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> + "reset", GPIOD_OUT_HIGH, "PERST#");
For usecases like link retention from bootloader to kernel, this could be
requested as GPIOD_ASIS:
https://lore.kernel.org/linux-pci/20260109-link_retain-v1-3-7e6782230f4b@oss.qualcomm.com/
- Mani
> + 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, &bridge->ports);
> +
> + return 0;
> +}
> +
> +/**
> + * pci_host_common_parse_ports - Parse Root Port nodes from device tree
> + * @bridge: PCI host bridge
> + *
> + * 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 pci_host_bridge *bridge)
> +{
> + struct device *dev = &bridge->dev;
> + 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(bridge, of_port);
> + if (ret)
> + 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..25d808319836 100644
> --- a/drivers/pci/controller/pci-host-common.h
> +++ b/drivers/pci/controller/pci-host-common.h
> @@ -12,6 +12,21 @@
>
> 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;
> +};
> +
> +int pci_host_common_parse_ports(struct pci_host_bridge *bridge);
> +
> int pci_host_common_probe(struct platform_device *pdev);
> int pci_host_common_init(struct platform_device *pdev,
> struct pci_host_bridge *bridge,
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 2975974f35e8..007a3fb8da86 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -647,6 +647,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
>
> pci_free_resource_list(&bridge->windows);
> pci_free_resource_list(&bridge->dma_ranges);
> + pci_free_resource_list(&bridge->ports);
>
> /* Host bridges only have domain_nr set in the emulation case */
> if (bridge->domain_nr != PCI_DOMAIN_NR_NOT_SET)
> @@ -671,6 +672,7 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
> {
> INIT_LIST_HEAD(&bridge->windows);
> INIT_LIST_HEAD(&bridge->dma_ranges);
> + INIT_LIST_HEAD(&bridge->ports);
>
> /*
> * We assume we can manage these PCIe features. Some systems may
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 1c270f1d5123..b05482355abc 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -634,6 +634,7 @@ struct pci_host_bridge {
> int domain_nr;
> struct list_head windows; /* resource_entry */
> struct list_head dma_ranges; /* dma ranges resource list */
> + struct list_head ports; /* Root Port list (pci_host_port) */
> #ifdef CONFIG_PCI_IDE
> u16 nr_ide_streams; /* Max streams possibly active in @ide_stream_ida */
> struct ida ide_stream_ida;
> --
> 2.37.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH V5 03/12] PCI: dwc: Allow external allocation of pci_host_bridge
2026-02-13 15:29 ` Frank Li
@ 2026-02-16 16:25 ` Manivannan Sadhasivam
2026-02-24 10:34 ` Sherry Sun
0 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-16 16:25 UTC (permalink / raw)
To: Frank Li
Cc: Sherry Sun, hongxing.zhu, l.stach, bhelgaas, lpieralisi,
kwilczynski, robh, krzk+dt, conor+dt, s.hauer, festevam, imx,
kernel, linux-pci, linux-arm-kernel, devicetree, linux-kernel
On Fri, Feb 13, 2026 at 10:29:12AM -0500, Frank Li wrote:
> On Fri, Feb 13, 2026 at 12:08:43PM +0800, Sherry Sun wrote:
> > Currently, dw_pcie_host_init() always allocates a new pci_host_bridge
> > structure internally using devm_pci_alloc_host_bridge(). This prevents
> > drivers from pre-allocating the bridge structure when needed.
> >
> > Modify dw_pcie_host_init() to check if pp->bridge is already set. If
> > set, use the pre-allocated bridge instead of allocating a new one. This
> > maintains backward compatibility with existing drivers that don't set
> > pp->bridge, while allowing new drivers to pre-allocate when needed.
> >
> > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > ---
> > drivers/pci/controller/dwc/pcie-designware-host.c | 12 ++++++++----
> > 1 file changed, 8 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 6ae6189e9b8a..c2de9830e1e9 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -575,11 +575,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> >
> > raw_spin_lock_init(&pp->lock);
> >
> > - bridge = devm_pci_alloc_host_bridge(dev, 0);
> > - if (!bridge)
> > - return -ENOMEM;
> > + if (!pp->bridge) {
> > + bridge = devm_pci_alloc_host_bridge(dev, 0);
>
> It'd better call parse port here, or in devm_pci_alloc_host_bridge().
>
Agree. We should try to avoid calling devm_pci_alloc_host_bridge() from glue
drivers.
- Mani
> If that, needn't check pp->bridge.
>
> Frank
> > + if (!bridge)
> > + return -ENOMEM;
> >
> > - pp->bridge = bridge;
> > + pp->bridge = bridge;
> > + } else {
> > + bridge = pp->bridge;
> > + }
> >
> > ret = dw_pcie_host_get_resources(pp);
> > if (ret)
> > --
> > 2.37.1
> >
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
2026-02-16 16:21 ` Manivannan Sadhasivam
@ 2026-02-24 10:24 ` Sherry Sun
2026-02-25 13:15 ` Manivannan Sadhasivam
0 siblings, 1 reply; 23+ messages in thread
From: Sherry Sun @ 2026-02-24 10:24 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Hongxing Zhu, l.stach@pengutronix.de, Frank Li,
bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com,
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 V5 02/12] PCI: host-generic: Add common helpers for
> parsing Root Port properties
>
> On Fri, Feb 13, 2026 at 12:08:42PM +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
> > (currently only reset GPIO descriptor) and add
> > pci_host_common_parse_ports() to parse Root Port nodes from device
> tree.
> >
> > Also add the 'ports' list to struct pci_host_bridge for better
> > maintain parsed Root Port information.
> >
> > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > ---
> > drivers/pci/controller/pci-host-common.c | 58
> > ++++++++++++++++++++++++ drivers/pci/controller/pci-host-common.h |
> 15 ++++++
> > drivers/pci/probe.c | 2 +
> > include/linux/pci.h | 1 +
> > 4 files changed, 76 insertions(+)
> >
> > diff --git a/drivers/pci/controller/pci-host-common.c
> > b/drivers/pci/controller/pci-host-common.c
> > index d6258c1cffe5..0c35907a5076 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,63 @@
> >
> > #include "pci-host-common.h"
> >
> > +/**
> > + * pci_host_common_parse_port - Parse a single Root Port node
> > + * @bridge: PCI host bridge
> > + * @node: Device tree node of the Root Port
> > + *
> > + * Returns: 0 on success, negative error code on failure */ static
> > +int pci_host_common_parse_port(struct pci_host_bridge *bridge,
> > + struct device_node *node)
> > +{
> > + struct device *dev = &bridge->dev;
> > + struct pci_host_port *port;
> > + struct gpio_desc *reset;
> > +
> > + reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> > + "reset", GPIOD_OUT_HIGH, "PERST#");
>
> For usecases like link retention from bootloader to kernel, this could be
> requested as GPIOD_ASIS:
> https://lore.ke/
> rnel.org%2Flinux-pci%2F20260109-link_retain-v1-3-
> 7e6782230f4b%40oss.qualcomm.com%2F&data=05%7C02%7Csherry.sun%40
> nxp.com%7C55c78c3dde694150dd1408de6d778ccd%7C686ea1d3bc2b4c6fa9
> 2cd99c5c301635%7C0%7C0%7C639068557422583280%7CUnknown%7CTWFp
> bGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
> MiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zZAzwcH
> U2y8kH4YP0OoTVN66tUlCEq6m2aAKkWCFeTM%3D&reserved=0
>
Hi Manivannan,
I understand the concern about supporting use‑cases where the PCIe link is
intentionally retained from bootloader to kernel. However, relying on GPIOD_ASIS
may introduces a practical problem: it removes any guarantee about the PERST#
level during the early power‑on window.
According to the PCIe initialization requirements, PERST# must remain asserted
until power rails and REFCLK are valid. If we request the GPIO as GPIOD_ASIS, the
kernel no longer controls or even knows the actual state of PERST# at probe time,
which means the device may observe a deassert reset before power/clock stable,
it is risky even xx_pcie_host_init() asserts/deasserts PERST# again after enable
power rails hoping to reset the device cleanly. Once PERST# is released before
power or clock rails are fully valid, the device may already have entered undefined
or partially‑initialized states. Even if the driver asserts PERST# later, this does not
guarantee that all internal domains return to a well‑defined reset state. Some
implementations do not route PERST# to all functional blocks, or early deassert
during unstable power/clock conditions can leave the PCIe controller or endpoint
PHY/LTSSM in inconsistent conditions. Consequently, such a sequence can still lead
to undefined device state, failed link training, or inconsistent enumeration behavior.
In contrast, explicitly requesting the GPIO as GPIOD_OUT_HIGH ensures that PERST#
remains asserted until the driver is ready to perform the proper bring‑up sequence,
keeping the behavior deterministic and compliant with the PCIe reset‑ordering
expectations for this hardware.
If link retention from bootloader is a desired scenario for some systems, maybe we
can consider adding a DT property or quirk. But making GPIOD_ASIS the default
would compromise correct power‑on reset handling on platforms that require
PERST# to be actively driven.
Best Regards
Sherry
>
> > + 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, &bridge->ports);
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * pci_host_common_parse_ports - Parse Root Port nodes from device
> > +tree
> > + * @bridge: PCI host bridge
> > + *
> > + * 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 pci_host_bridge *bridge) {
> > + struct device *dev = &bridge->dev;
> > + 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(bridge, of_port);
> > + if (ret)
> > + 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..25d808319836 100644
> > --- a/drivers/pci/controller/pci-host-common.h
> > +++ b/drivers/pci/controller/pci-host-common.h
> > @@ -12,6 +12,21 @@
> >
> > 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;
> > +};
> > +
> > +int pci_host_common_parse_ports(struct pci_host_bridge *bridge);
> > +
> > int pci_host_common_probe(struct platform_device *pdev); int
> > pci_host_common_init(struct platform_device *pdev,
> > struct pci_host_bridge *bridge,
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index
> > 2975974f35e8..007a3fb8da86 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -647,6 +647,7 @@ static void pci_release_host_bridge_dev(struct
> > device *dev)
> >
> > pci_free_resource_list(&bridge->windows);
> > pci_free_resource_list(&bridge->dma_ranges);
> > + pci_free_resource_list(&bridge->ports);
> >
> > /* Host bridges only have domain_nr set in the emulation case */
> > if (bridge->domain_nr != PCI_DOMAIN_NR_NOT_SET) @@ -671,6
> +672,7 @@
> > static void pci_init_host_bridge(struct pci_host_bridge *bridge) {
> > INIT_LIST_HEAD(&bridge->windows);
> > INIT_LIST_HEAD(&bridge->dma_ranges);
> > + INIT_LIST_HEAD(&bridge->ports);
> >
> > /*
> > * We assume we can manage these PCIe features. Some systems
> may
> > diff --git a/include/linux/pci.h b/include/linux/pci.h index
> > 1c270f1d5123..b05482355abc 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -634,6 +634,7 @@ struct pci_host_bridge {
> > int domain_nr;
> > struct list_head windows; /* resource_entry */
> > struct list_head dma_ranges; /* dma ranges resource list */
> > + struct list_head ports; /* Root Port list (pci_host_port) */
> > #ifdef CONFIG_PCI_IDE
> > u16 nr_ide_streams; /* Max streams possibly active in
> @ide_stream_ida */
> > struct ida ide_stream_ida;
> > --
> > 2.37.1
> >
>
> --
> மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH V5 03/12] PCI: dwc: Allow external allocation of pci_host_bridge
2026-02-16 16:25 ` Manivannan Sadhasivam
@ 2026-02-24 10:34 ` Sherry Sun
0 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2026-02-24 10:34 UTC (permalink / raw)
To: Manivannan Sadhasivam, Frank Li
Cc: Hongxing Zhu, l.stach@pengutronix.de, bhelgaas@google.com,
lpieralisi@kernel.org, kwilczynski@kernel.org, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, s.hauer@pengutronix.de,
festevam@gmail.com, 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 V5 03/12] PCI: dwc: Allow external allocation of
> pci_host_bridge
>
> On Fri, Feb 13, 2026 at 10:29:12AM -0500, Frank Li wrote:
> > On Fri, Feb 13, 2026 at 12:08:43PM +0800, Sherry Sun wrote:
> > > Currently, dw_pcie_host_init() always allocates a new
> > > pci_host_bridge structure internally using
> > > devm_pci_alloc_host_bridge(). This prevents drivers from pre-allocating
> the bridge structure when needed.
> > >
> > > Modify dw_pcie_host_init() to check if pp->bridge is already set. If
> > > set, use the pre-allocated bridge instead of allocating a new one.
> > > This maintains backward compatibility with existing drivers that
> > > don't set
> > > pp->bridge, while allowing new drivers to pre-allocate when needed.
> > >
> > > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > > ---
> > > drivers/pci/controller/dwc/pcie-designware-host.c | 12 ++++++++----
> > > 1 file changed, 8 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > index 6ae6189e9b8a..c2de9830e1e9 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -575,11 +575,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> > >
> > > raw_spin_lock_init(&pp->lock);
> > >
> > > - bridge = devm_pci_alloc_host_bridge(dev, 0);
> > > - if (!bridge)
> > > - return -ENOMEM;
> > > + if (!pp->bridge) {
> > > + bridge = devm_pci_alloc_host_bridge(dev, 0);
> >
> > It'd better call parse port here, or in devm_pci_alloc_host_bridge().
> >
>
> Agree. We should try to avoid calling devm_pci_alloc_host_bridge() from glue
> drivers.
>
> - Mani
>
> > If that, needn't check pp->bridge.
> >
Ok, thanks Frank and Mani for the suggestion here, will improve it in next version.
Best Regards
Sherry
> > Frank
> > > + if (!bridge)
> > > + return -ENOMEM;
> > >
> > > - pp->bridge = bridge;
> > > + pp->bridge = bridge;
> > > + } else {
> > > + bridge = pp->bridge;
> > > + }
> > >
> > > ret = dw_pcie_host_get_resources(pp);
> > > if (ret)
> > > --
> > > 2.37.1
> > >
>
> --
> மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
2026-02-24 10:24 ` Sherry Sun
@ 2026-02-25 13:15 ` Manivannan Sadhasivam
2026-02-26 3:40 ` Sherry Sun
0 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-25 13:15 UTC (permalink / raw)
To: Sherry Sun
Cc: Hongxing Zhu, l.stach@pengutronix.de, Frank Li,
bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com,
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
On Tue, Feb 24, 2026 at 10:24:41AM +0000, Sherry Sun wrote:
> > Subject: Re: [PATCH V5 02/12] PCI: host-generic: Add common helpers for
> > parsing Root Port properties
> >
> > On Fri, Feb 13, 2026 at 12:08:42PM +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
> > > (currently only reset GPIO descriptor) and add
> > > pci_host_common_parse_ports() to parse Root Port nodes from device
> > tree.
> > >
> > > Also add the 'ports' list to struct pci_host_bridge for better
> > > maintain parsed Root Port information.
> > >
> > > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > > ---
> > > drivers/pci/controller/pci-host-common.c | 58
> > > ++++++++++++++++++++++++ drivers/pci/controller/pci-host-common.h |
> > 15 ++++++
> > > drivers/pci/probe.c | 2 +
> > > include/linux/pci.h | 1 +
> > > 4 files changed, 76 insertions(+)
> > >
> > > diff --git a/drivers/pci/controller/pci-host-common.c
> > > b/drivers/pci/controller/pci-host-common.c
> > > index d6258c1cffe5..0c35907a5076 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,63 @@
> > >
> > > #include "pci-host-common.h"
> > >
> > > +/**
> > > + * pci_host_common_parse_port - Parse a single Root Port node
> > > + * @bridge: PCI host bridge
> > > + * @node: Device tree node of the Root Port
> > > + *
> > > + * Returns: 0 on success, negative error code on failure */ static
> > > +int pci_host_common_parse_port(struct pci_host_bridge *bridge,
> > > + struct device_node *node)
> > > +{
> > > + struct device *dev = &bridge->dev;
> > > + struct pci_host_port *port;
> > > + struct gpio_desc *reset;
> > > +
> > > + reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> > > + "reset", GPIOD_OUT_HIGH, "PERST#");
> >
> > For usecases like link retention from bootloader to kernel, this could be
> > requested as GPIOD_ASIS:
> > https://lore.ke/
> > rnel.org%2Flinux-pci%2F20260109-link_retain-v1-3-
> > 7e6782230f4b%40oss.qualcomm.com%2F&data=05%7C02%7Csherry.sun%40
> > nxp.com%7C55c78c3dde694150dd1408de6d778ccd%7C686ea1d3bc2b4c6fa9
> > 2cd99c5c301635%7C0%7C0%7C639068557422583280%7CUnknown%7CTWFp
> > bGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
> > MiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zZAzwcH
> > U2y8kH4YP0OoTVN66tUlCEq6m2aAKkWCFeTM%3D&reserved=0
> >
>
> Hi Manivannan,
>
> I understand the concern about supporting use‑cases where the PCIe link is
> intentionally retained from bootloader to kernel. However, relying on GPIOD_ASIS
> may introduces a practical problem: it removes any guarantee about the PERST#
> level during the early power‑on window.
>
> According to the PCIe initialization requirements, PERST# must remain asserted
> until power rails and REFCLK are valid. If we request the GPIO as GPIOD_ASIS, the
> kernel no longer controls or even knows the actual state of PERST# at probe time,
> which means the device may observe a deassert reset before power/clock stable,
> it is risky even xx_pcie_host_init() asserts/deasserts PERST# again after enable
> power rails hoping to reset the device cleanly. Once PERST# is released before
> power or clock rails are fully valid, the device may already have entered undefined
> or partially‑initialized states. Even if the driver asserts PERST# later, this does not
> guarantee that all internal domains return to a well‑defined reset state. Some
> implementations do not route PERST# to all functional blocks, or early deassert
> during unstable power/clock conditions can leave the PCIe controller or endpoint
> PHY/LTSSM in inconsistent conditions. Consequently, such a sequence can still lead
> to undefined device state, failed link training, or inconsistent enumeration behavior.
>
I don't think this is true. Even if you request PERST# as GPIOD_ASIS, if you
explicitly assert it *before* doing the controller initialization, net result
would be the same.
Like,
devm_fwnode_gpiod_get(GPIOD_ASIS)
...
assert_perst()
(perform controller initialization and enable resources)
deassert_perst()
So if you request PERST# as GPIOD_OUT_HIGH, the first assert_perst() becomes a
NOP, otherwise, the endpoint gets asserted right before the controller
initialization.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
2026-02-25 13:15 ` Manivannan Sadhasivam
@ 2026-02-26 3:40 ` Sherry Sun
2026-02-28 1:58 ` Hongxing Zhu
0 siblings, 1 reply; 23+ messages in thread
From: Sherry Sun @ 2026-02-26 3:40 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Hongxing Zhu, l.stach@pengutronix.de, Frank Li,
bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com,
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 V5 02/12] PCI: host-generic: Add common helpers for
> parsing Root Port properties
>
> On Tue, Feb 24, 2026 at 10:24:41AM +0000, Sherry Sun wrote:
> > > Subject: Re: [PATCH V5 02/12] PCI: host-generic: Add common helpers
> > > for parsing Root Port properties
> > >
> > > On Fri, Feb 13, 2026 at 12:08:42PM +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
> > > > (currently only reset GPIO descriptor) and add
> > > > pci_host_common_parse_ports() to parse Root Port nodes from device
> > > tree.
> > > >
> > > > Also add the 'ports' list to struct pci_host_bridge for better
> > > > maintain parsed Root Port information.
> > > >
> > > > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > > > ---
> > > > drivers/pci/controller/pci-host-common.c | 58
> > > > ++++++++++++++++++++++++ drivers/pci/controller/pci-host-common.h
> > > > ++++++++++++++++++++++++ |
> > > 15 ++++++
> > > > drivers/pci/probe.c | 2 +
> > > > include/linux/pci.h | 1 +
> > > > 4 files changed, 76 insertions(+)
> > > >
> > > > diff --git a/drivers/pci/controller/pci-host-common.c
> > > > b/drivers/pci/controller/pci-host-common.c
> > > > index d6258c1cffe5..0c35907a5076 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,63 @@
> > > >
> > > > #include "pci-host-common.h"
> > > >
> > > > +/**
> > > > + * pci_host_common_parse_port - Parse a single Root Port node
> > > > + * @bridge: PCI host bridge
> > > > + * @node: Device tree node of the Root Port
> > > > + *
> > > > + * Returns: 0 on success, negative error code on failure */
> > > > +static int pci_host_common_parse_port(struct pci_host_bridge *bridge,
> > > > + struct device_node *node) {
> > > > + struct device *dev = &bridge->dev;
> > > > + struct pci_host_port *port;
> > > > + struct gpio_desc *reset;
> > > > +
> > > > + reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> > > > + "reset", GPIOD_OUT_HIGH,
> > > > + "PERST#");
> > >
> > > For usecases like link retention from bootloader to kernel, this
> > > could be requested as GPIOD_ASIS:
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flo
> > >
> re.ke%2F&data=05%7C02%7Csherry.sun%40nxp.com%7C7957eace8620494e
> da250
> > >
> 8de74700adc%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63907
> 622173
> > >
> 6969266%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiO
> iIwLjAu
> > >
> MDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%
> 7C%7
> > >
> C&sdata=S6ME9QOAFR5OC8w5WRjFeHW46t4OAxVkVz6E3pCJWQk%3D&rese
> rved=0
> > > rnel.org%2Flinux-pci%2F20260109-link_retain-v1-3-
> > >
> 7e6782230f4b%40oss.qualcomm.com%2F&data=05%7C02%7Csherry.sun%40
> > >
> nxp.com%7C55c78c3dde694150dd1408de6d778ccd%7C686ea1d3bc2b4c6fa9
> > >
> 2cd99c5c301635%7C0%7C0%7C639068557422583280%7CUnknown%7CTWFp
> > >
> bGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
> > >
> MiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zZAzwcH
> > > U2y8kH4YP0OoTVN66tUlCEq6m2aAKkWCFeTM%3D&reserved=0
> > >
> >
> > Hi Manivannan,
> >
> > I understand the concern about supporting use‑cases where the PCIe
> > link is intentionally retained from bootloader to kernel. However,
> > relying on GPIOD_ASIS may introduces a practical problem: it removes
> > any guarantee about the PERST# level during the early power‑on window.
> >
> > According to the PCIe initialization requirements, PERST# must remain
> > asserted until power rails and REFCLK are valid. If we request the
> > GPIO as GPIOD_ASIS, the kernel no longer controls or even knows the
> > actual state of PERST# at probe time, which means the device may
> > observe a deassert reset before power/clock stable, it is risky even
> > xx_pcie_host_init() asserts/deasserts PERST# again after enable power
> > rails hoping to reset the device cleanly. Once PERST# is released
> > before power or clock rails are fully valid, the device may already
> > have entered undefined or partially‑initialized states. Even if the
> > driver asserts PERST# later, this does not guarantee that all internal
> > domains return to a well‑defined reset state. Some implementations do
> > not route PERST# to all functional blocks, or early deassert during
> > unstable power/clock conditions can leave the PCIe controller or endpoint
> PHY/LTSSM in inconsistent conditions. Consequently, such a sequence can still
> lead to undefined device state, failed link training, or inconsistent
> enumeration behavior.
> >
>
> I don't think this is true. Even if you request PERST# as GPIOD_ASIS, if you
> explicitly assert it *before* doing the controller initialization, net result would
> be the same.
>
> Like,
> devm_fwnode_gpiod_get(GPIOD_ASIS)
> ...
> assert_perst()
> (perform controller initialization and enable resources)
> deassert_perst()
>
> So if you request PERST# as GPIOD_OUT_HIGH, the first assert_perst()
> becomes a NOP, otherwise, the endpoint gets asserted right before the
> controller initialization.
>
Hi Manivannan,
Got your point, seems there are some issues in the order of assert/deassert
and power/clk enable in pci-imx6 driver. Maybe I need to readjust the sequence
internal imx_pcie_host_init().
Thanks, will change to use GPIOD_ASIS in next version.
Best Regards
Sherry
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
2026-02-26 3:40 ` Sherry Sun
@ 2026-02-28 1:58 ` Hongxing Zhu
2026-02-28 15:05 ` Manivannan Sadhasivam
0 siblings, 1 reply; 23+ messages in thread
From: Hongxing Zhu @ 2026-02-28 1:58 UTC (permalink / raw)
To: Sherry Sun, Manivannan Sadhasivam
Cc: l.stach@pengutronix.de, Frank Li, bhelgaas@google.com,
lpieralisi@kernel.org, kwilczynski@kernel.org, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, s.hauer@pengutronix.de,
festevam@gmail.com, 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
> -----Original Message-----
> From: Sherry Sun <sherry.sun@nxp.com>
> Sent: 2026年2月26日 11:40
> To: Manivannan Sadhasivam <mani@kernel.org>
> Cc: Hongxing Zhu <hongxing.zhu@nxp.com>; l.stach@pengutronix.de; Frank
> Li <frank.li@nxp.com>; bhelgaas@google.com; lpieralisi@kernel.org;
> kwilczynski@kernel.org; robh@kernel.org; krzk+dt@kernel.org;
> conor+dt@kernel.org; s.hauer@pengutronix.de; festevam@gmail.com;
> 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 V5 02/12] PCI: host-generic: Add common helpers for
> parsing Root Port properties
>
> > Subject: Re: [PATCH V5 02/12] PCI: host-generic: Add common helpers
> > for parsing Root Port properties
> >
> > On Tue, Feb 24, 2026 at 10:24:41AM +0000, Sherry Sun wrote:
> > > > Subject: Re: [PATCH V5 02/12] PCI: host-generic: Add common
> > > > helpers for parsing Root Port properties
> > > >
> > > > On Fri, Feb 13, 2026 at 12:08:42PM +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
> > > > > (currently only reset GPIO descriptor) and add
> > > > > pci_host_common_parse_ports() to parse Root Port nodes from
> > > > > device
> > > > tree.
> > > > >
> > > > > Also add the 'ports' list to struct pci_host_bridge for better
> > > > > maintain parsed Root Port information.
> > > > >
> > > > > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > > > > ---
> > > > > drivers/pci/controller/pci-host-common.c | 58
> > > > > ++++++++++++++++++++++++
> > > > > ++++++++++++++++++++++++ drivers/pci/controller/pci-host-common.
> > > > > ++++++++++++++++++++++++ h
> > > > > ++++++++++++++++++++++++ |
> > > > 15 ++++++
> > > > > drivers/pci/probe.c | 2 +
> > > > > include/linux/pci.h | 1 +
> > > > > 4 files changed, 76 insertions(+)
> > > > >
> > > > > diff --git a/drivers/pci/controller/pci-host-common.c
> > > > > b/drivers/pci/controller/pci-host-common.c
> > > > > index d6258c1cffe5..0c35907a5076 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,63 @@
> > > > >
> > > > > #include "pci-host-common.h"
> > > > >
> > > > > +/**
> > > > > + * pci_host_common_parse_port - Parse a single Root Port node
> > > > > + * @bridge: PCI host bridge
> > > > > + * @node: Device tree node of the Root Port
> > > > > + *
> > > > > + * Returns: 0 on success, negative error code on failure */
> > > > > +static int pci_host_common_parse_port(struct pci_host_bridge
> *bridge,
> > > > > + struct device_node *node) {
> > > > > + struct device *dev = &bridge->dev;
> > > > > + struct pci_host_port *port;
> > > > > + struct gpio_desc *reset;
> > > > > +
> > > > > + reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> > > > > + "reset", GPIOD_OUT_HIGH,
> > > > > + "PERST#");
> > > >
> > > > For usecases like link retention from bootloader to kernel, this
> > > > could be requested as GPIOD_ASIS:
> > > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2F
> > > > lo
> > > >
> > re.ke%2F&data=05%7C02%7Csherry.sun%40nxp.com%7C7957eace8620494e
> > da250
> > > >
> >
> 8de74700adc%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63907
> > 622173
> > > >
> >
> 6969266%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiO
> > iIwLjAu
> > > >
> >
> MDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%
> > 7C%7
> > > >
> >
> C&sdata=S6ME9QOAFR5OC8w5WRjFeHW46t4OAxVkVz6E3pCJWQk%3D&rese
> > rved=0
> > > > rnel.org%2Flinux-pci%2F20260109-link_retain-v1-3-
> > > >
> >
> 7e6782230f4b%40oss.qualcomm.com%2F&data=05%7C02%7Csherry.sun%40
> > > >
> >
> nxp.com%7C55c78c3dde694150dd1408de6d778ccd%7C686ea1d3bc2b4c6fa9
> > > >
> >
> 2cd99c5c301635%7C0%7C0%7C639068557422583280%7CUnknown%7CTWFp
> > > >
> >
> bGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
> > > >
> > MiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zZAzwcH
> > > > U2y8kH4YP0OoTVN66tUlCEq6m2aAKkWCFeTM%3D&reserved=0
> > > >
> > >
> > > Hi Manivannan,
> > >
> > > I understand the concern about supporting use‑cases where the PCIe
> > > link is intentionally retained from bootloader to kernel. However,
> > > relying on GPIOD_ASIS may introduces a practical problem: it removes
> > > any guarantee about the PERST# level during the early power‑on
> window.
> > >
> > > According to the PCIe initialization requirements, PERST# must
> > > remain asserted until power rails and REFCLK are valid. If we
> > > request the GPIO as GPIOD_ASIS, the kernel no longer controls or
> > > even knows the actual state of PERST# at probe time, which means the
> > > device may observe a deassert reset before power/clock stable, it is
> > > risky even
> > > xx_pcie_host_init() asserts/deasserts PERST# again after enable
> > > power rails hoping to reset the device cleanly. Once PERST# is
> > > released before power or clock rails are fully valid, the device may
> > > already have entered undefined or partially‑initialized states. Even
> > > if the driver asserts PERST# later, this does not guarantee that all
> > > internal domains return to a well‑defined reset state. Some
> > > implementations do not route PERST# to all functional blocks, or
> > > early deassert during unstable power/clock conditions can leave the
> > > PCIe controller or endpoint
> > PHY/LTSSM in inconsistent conditions. Consequently, such a sequence
> > can still lead to undefined device state, failed link training, or
> > inconsistent enumeration behavior.
> > >
> >
> > I don't think this is true. Even if you request PERST# as GPIOD_ASIS,
> > if you explicitly assert it *before* doing the controller
> > initialization, net result would be the same.
> >
> > Like,
> > devm_fwnode_gpiod_get(GPIOD_ASIS)
> > ...
> > assert_perst()
> > (perform controller initialization and enable resources)
> > deassert_perst()
> >
> > So if you request PERST# as GPIOD_OUT_HIGH, the first assert_perst()
> > becomes a NOP, otherwise, the endpoint gets asserted right before the
> > controller initialization.
> >
> Hi Manivannan,
> Got your point, seems there are some issues in the order of assert/deassert
> and power/clk enable in pci-imx6 driver. Maybe I need to readjust the
> sequence internal imx_pcie_host_init().
>
> Thanks, will change to use GPIOD_ASIS in next version.
If the GPIOD_ASIS is used, the PERST# should be asserted before vpcie3v3
or vpcie3v3aux is turned on.
That's the reason why GPIOD_OUT_HIGH is set in the probe of pci-imx6.c
driver currently.
Best Regards
Richard Zhu
>
> Best Regards
> Sherry
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
2026-02-28 1:58 ` Hongxing Zhu
@ 2026-02-28 15:05 ` Manivannan Sadhasivam
0 siblings, 0 replies; 23+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-28 15:05 UTC (permalink / raw)
To: Hongxing Zhu
Cc: Sherry Sun, l.stach@pengutronix.de, Frank Li, bhelgaas@google.com,
lpieralisi@kernel.org, kwilczynski@kernel.org, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, s.hauer@pengutronix.de,
festevam@gmail.com, 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
On Sat, Feb 28, 2026 at 01:58:43AM +0000, Hongxing Zhu wrote:
> > -----Original Message-----
> > From: Sherry Sun <sherry.sun@nxp.com>
> > Sent: 2026年2月26日 11:40
> > To: Manivannan Sadhasivam <mani@kernel.org>
> > Cc: Hongxing Zhu <hongxing.zhu@nxp.com>; l.stach@pengutronix.de; Frank
> > Li <frank.li@nxp.com>; bhelgaas@google.com; lpieralisi@kernel.org;
> > kwilczynski@kernel.org; robh@kernel.org; krzk+dt@kernel.org;
> > conor+dt@kernel.org; s.hauer@pengutronix.de; festevam@gmail.com;
> > 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 V5 02/12] PCI: host-generic: Add common helpers for
> > parsing Root Port properties
> >
> > > Subject: Re: [PATCH V5 02/12] PCI: host-generic: Add common helpers
> > > for parsing Root Port properties
> > >
> > > On Tue, Feb 24, 2026 at 10:24:41AM +0000, Sherry Sun wrote:
> > > > > Subject: Re: [PATCH V5 02/12] PCI: host-generic: Add common
> > > > > helpers for parsing Root Port properties
> > > > >
> > > > > On Fri, Feb 13, 2026 at 12:08:42PM +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
> > > > > > (currently only reset GPIO descriptor) and add
> > > > > > pci_host_common_parse_ports() to parse Root Port nodes from
> > > > > > device
> > > > > tree.
> > > > > >
> > > > > > Also add the 'ports' list to struct pci_host_bridge for better
> > > > > > maintain parsed Root Port information.
> > > > > >
> > > > > > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > > > > > ---
> > > > > > drivers/pci/controller/pci-host-common.c | 58
> > > > > > ++++++++++++++++++++++++
> > > > > > ++++++++++++++++++++++++ drivers/pci/controller/pci-host-common.
> > > > > > ++++++++++++++++++++++++ h
> > > > > > ++++++++++++++++++++++++ |
> > > > > 15 ++++++
> > > > > > drivers/pci/probe.c | 2 +
> > > > > > include/linux/pci.h | 1 +
> > > > > > 4 files changed, 76 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/pci/controller/pci-host-common.c
> > > > > > b/drivers/pci/controller/pci-host-common.c
> > > > > > index d6258c1cffe5..0c35907a5076 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,63 @@
> > > > > >
> > > > > > #include "pci-host-common.h"
> > > > > >
> > > > > > +/**
> > > > > > + * pci_host_common_parse_port - Parse a single Root Port node
> > > > > > + * @bridge: PCI host bridge
> > > > > > + * @node: Device tree node of the Root Port
> > > > > > + *
> > > > > > + * Returns: 0 on success, negative error code on failure */
> > > > > > +static int pci_host_common_parse_port(struct pci_host_bridge
> > *bridge,
> > > > > > + struct device_node *node) {
> > > > > > + struct device *dev = &bridge->dev;
> > > > > > + struct pci_host_port *port;
> > > > > > + struct gpio_desc *reset;
> > > > > > +
> > > > > > + reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> > > > > > + "reset", GPIOD_OUT_HIGH,
> > > > > > + "PERST#");
> > > > >
> > > > > For usecases like link retention from bootloader to kernel, this
> > > > > could be requested as GPIOD_ASIS:
> > > > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2F
> > > > > lo
> > > > >
> > > re.ke%2F&data=05%7C02%7Csherry.sun%40nxp.com%7C7957eace8620494e
> > > da250
> > > > >
> > >
> > 8de74700adc%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63907
> > > 622173
> > > > >
> > >
> > 6969266%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiO
> > > iIwLjAu
> > > > >
> > >
> > MDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%
> > > 7C%7
> > > > >
> > >
> > C&sdata=S6ME9QOAFR5OC8w5WRjFeHW46t4OAxVkVz6E3pCJWQk%3D&rese
> > > rved=0
> > > > > rnel.org%2Flinux-pci%2F20260109-link_retain-v1-3-
> > > > >
> > >
> > 7e6782230f4b%40oss.qualcomm.com%2F&data=05%7C02%7Csherry.sun%40
> > > > >
> > >
> > nxp.com%7C55c78c3dde694150dd1408de6d778ccd%7C686ea1d3bc2b4c6fa9
> > > > >
> > >
> > 2cd99c5c301635%7C0%7C0%7C639068557422583280%7CUnknown%7CTWFp
> > > > >
> > >
> > bGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
> > > > >
> > > MiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zZAzwcH
> > > > > U2y8kH4YP0OoTVN66tUlCEq6m2aAKkWCFeTM%3D&reserved=0
> > > > >
> > > >
> > > > Hi Manivannan,
> > > >
> > > > I understand the concern about supporting use‑cases where the PCIe
> > > > link is intentionally retained from bootloader to kernel. However,
> > > > relying on GPIOD_ASIS may introduces a practical problem: it removes
> > > > any guarantee about the PERST# level during the early power‑on
> > window.
> > > >
> > > > According to the PCIe initialization requirements, PERST# must
> > > > remain asserted until power rails and REFCLK are valid. If we
> > > > request the GPIO as GPIOD_ASIS, the kernel no longer controls or
> > > > even knows the actual state of PERST# at probe time, which means the
> > > > device may observe a deassert reset before power/clock stable, it is
> > > > risky even
> > > > xx_pcie_host_init() asserts/deasserts PERST# again after enable
> > > > power rails hoping to reset the device cleanly. Once PERST# is
> > > > released before power or clock rails are fully valid, the device may
> > > > already have entered undefined or partially‑initialized states. Even
> > > > if the driver asserts PERST# later, this does not guarantee that all
> > > > internal domains return to a well‑defined reset state. Some
> > > > implementations do not route PERST# to all functional blocks, or
> > > > early deassert during unstable power/clock conditions can leave the
> > > > PCIe controller or endpoint
> > > PHY/LTSSM in inconsistent conditions. Consequently, such a sequence
> > > can still lead to undefined device state, failed link training, or
> > > inconsistent enumeration behavior.
> > > >
> > >
> > > I don't think this is true. Even if you request PERST# as GPIOD_ASIS,
> > > if you explicitly assert it *before* doing the controller
> > > initialization, net result would be the same.
> > >
> > > Like,
> > > devm_fwnode_gpiod_get(GPIOD_ASIS)
> > > ...
> > > assert_perst()
> > > (perform controller initialization and enable resources)
> > > deassert_perst()
> > >
> > > So if you request PERST# as GPIOD_OUT_HIGH, the first assert_perst()
> > > becomes a NOP, otherwise, the endpoint gets asserted right before the
> > > controller initialization.
> > >
> > Hi Manivannan,
> > Got your point, seems there are some issues in the order of assert/deassert
> > and power/clk enable in pci-imx6 driver. Maybe I need to readjust the
> > sequence internal imx_pcie_host_init().
> >
> > Thanks, will change to use GPIOD_ASIS in next version.
> If the GPIOD_ASIS is used, the PERST# should be asserted before vpcie3v3
> or vpcie3v3aux is turned on.
> That's the reason why GPIOD_OUT_HIGH is set in the probe of pci-imx6.c
> driver currently.
That's fine. We can add a separate PERST# assert before enabling 3.3v
regulator.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-02-28 15:05 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-13 4:08 [PATCH V5 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
2026-02-13 4:08 ` [PATCH V5 01/12] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node Sherry Sun
2026-02-13 4:08 ` [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties Sherry Sun
2026-02-16 16:21 ` Manivannan Sadhasivam
2026-02-24 10:24 ` Sherry Sun
2026-02-25 13:15 ` Manivannan Sadhasivam
2026-02-26 3:40 ` Sherry Sun
2026-02-28 1:58 ` Hongxing Zhu
2026-02-28 15:05 ` Manivannan Sadhasivam
2026-02-13 4:08 ` [PATCH V5 03/12] PCI: dwc: Allow external allocation of pci_host_bridge Sherry Sun
2026-02-13 15:29 ` Frank Li
2026-02-16 16:25 ` Manivannan Sadhasivam
2026-02-24 10:34 ` Sherry Sun
2026-02-13 4:08 ` [PATCH V5 04/12] PCI: imx6: Add support for parsing the reset property in new Root Port binding Sherry Sun
2026-02-13 15:32 ` Frank Li
2026-02-13 4:08 ` [PATCH V5 05/12] arm: dts: imx6qdl: Add Root Port node and PERST property Sherry Sun
2026-02-13 4:08 ` [PATCH V5 06/12] arm: dts: imx6sx: " Sherry Sun
2026-02-13 4:08 ` [PATCH V5 07/12] arm: dts: imx7d: " Sherry Sun
2026-02-13 4:08 ` [PATCH V5 08/12] arm64: dts: imx8mm: " Sherry Sun
2026-02-13 4:08 ` [PATCH V5 09/12] arm64: dts: imx8mp: " Sherry Sun
2026-02-13 4:08 ` [PATCH V5 10/12] arm64: dts: imx8mq: " Sherry Sun
2026-02-13 4:08 ` [PATCH V5 11/12] arm64: dts: imx8dxl/qm/qxp: " Sherry Sun
2026-02-13 4:08 ` [PATCH V5 12/12] 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