[PATCH V13 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding

Sherry Sun
2026-04-16T11:12:44Z

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 V13:
1. Use of_property_present() instead of of_property_read_bool() in patch#2 as
reviewed by sashiko.
2. Add reset Null check in imx_pcie_parse_legacy_binding() to avoid
unconditional deassert delays on boards without reset GPIO as reviewed by
sashiko.
3. Delete the pcie@0,0 port defined in imx6q-utilite-pro.dts and use the new
pcie_port0 label in imx6qdl.dtsi to avoid to defining the conflicting node as
reviewed by sashiko.

Changes in V12:
1. Improve the pci_host_common_parse_port() to correctly handle three scenarios:
PERST# found in Root Port node & PERST# not in Root Port but found in RC node
& PERST# not found in either node.
2. Add documentation noting for pci_host_common_parse_port().
3. Add err_cleanup handle path for pci_host_common_parse_ports() to clean up any
partially parsed Root Port resources.
4. Optimize imx_pcie_assert_perst() to avoid the linearly increasing deassertion
delay if controller has multiple Root Ports.
5. Use mdelay instead of msleep in imx_pcie_assert_perst() for noirq context
safety.
6. Remove early return in imx_pcie_parse_legacy_binding() when reset is NULL to
align with pci_host_common_parse_port(), allowing port creation even without
PERST# GPIO.

Changes in V11:
1. Call pci_host_common_parse_ports() API from pci-imx6 driver instead of dwc
common layer as Mani suggested.
2. Improve the commit message of patch#3 to avoid confusion as Mani suggested.

Changes in V10:
1. Use gpiod_direction_output() instead of gpiod_set_value_cansleep() to
ensure the reset GPIO is properly configured as output before setting
its value in patch#5 as now the reset GPIO is obtained with
GPIOD_ASIS flag.

Changes in V9:
1. Improve the error handling in pci_host_common_parse_ports() as Mani suggested.
2. Move the list_empty check and the comment to imx_pcie_host_init() to make it
clear that imx_pcie_parse_legacy_binding() is a fallback as Mani suggested.
3. Export pci_host_common_delete_ports() so that it can be called by
imx_pcie_parse_legacy_binding().

Changes in V8:
1. Add back the cleanup function pci_host_common_delete_ports() to properly
handles the ports list instead of simply using pci_free_resource_list().
2. Improve the patch#4 commit message.
3. Remove the irrelevant code change in patch#4.

Changes in V7:
1. Change to use GPIOD_ASIS when requesting perst gpio as Mani suggested.
using bridge->dev.
2. Add a seperate patch to move vpcie3v3aux regulator enable from probe to
imx_pcie_host_init() and move imx_pcie_assert_perst() before regulator and
clock enable for pci-imx6.
3. Add device pointer parameter for pci_host_common_parse_port() instead of

Changes in V6:
1. Drop the pre-allocate pci_host_bridge struct changes in dw_pcie_host_init()
and imx_pcie_probe().
2. Parse Root Port nodes in dw_pcie_host_init() as Frank and Mani suggested.
3. Move the imx_pcie_parse_legacy_binding() from imx_pcie_probe() to
imx_pcie_host_init(), so that dw_pcie_host_init() parse Root Port first, if
no Root Port nodes were parsed(indicated by empty ports list), then parse
legacy binding.
4. Add device pointer parameter for pci_host_common_parse_ports().
5. Add NULL pointer check for reset gpio in imx_pcie_parse_legacy_binding().

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: imx6: Assert PERST# before enabling regulators
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 +++++
.../boot/dts/nxp/imx/imx6q-utilite-pro.dts | 17 +--
.../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 | 120 ++++++++++++++----
drivers/pci/controller/pci-host-common.c | 104 +++++++++++++++
drivers/pci/controller/pci-host-common.h | 16 +++
drivers/pci/probe.c | 1 +
include/linux/pci.h | 1 +
28 files changed, 461 insertions(+), 37 deletions(-)

--
2.37.1