Thread (23 messages) 23 messages, 4 authors, 2026-02-28

RE: [PATCH V5 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties

From: Hongxing Zhu <hongxing.zhu@nxp.com>
Date: 2026-02-28 01:58:47
Also in: imx, linux-devicetree, linux-pci, lkml

-----Original Message-----
From: Sherry Sun <redacted>
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 [off-list ref]; 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
quoted
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:
quoted
quoted
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:
quoted
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.
quoted
quoted
quoted
quoted
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.
quoted
Also add the 'ports' list to struct pci_host_bridge for better
maintain parsed Root Port information.

Signed-off-by: Sherry Sun <redacted>
---
 drivers/pci/controller/pci-host-common.c | 58
++++++++++++++++++++++++
++++++++++++++++++++++++ drivers/pci/controller/pci-host-common.
++++++++++++++++++++++++ h
++++++++++++++++++++++++ |
15 ++++++
quoted
 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,
quoted
quoted
quoted
quoted
+                                 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
quoted
quoted
8de74700adc%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63907
quoted
622173
quoted
quoted
6969266%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiO
quoted
iIwLjAu
quoted
quoted
MDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%
quoted
7C%7
quoted
quoted
C&sdata=S6ME9QOAFR5OC8w5WRjFeHW46t4OAxVkVz6E3pCJWQk%3D&rese
quoted
rved=0
quoted
quoted
rnel.org%2Flinux-pci%2F20260109-link_retain-v1-3-
7e6782230f4b%40oss.qualcomm.com%2F&data=05%7C02%7Csherry.sun%40
quoted
quoted
quoted
nxp.com%7C55c78c3dde694150dd1408de6d778ccd%7C686ea1d3bc2b4c6fa9
quoted
quoted
quoted
2cd99c5c301635%7C0%7C0%7C639068557422583280%7CUnknown%7CTWFp
quoted
quoted
quoted
bGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
quoted
quoted
quoted
MiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zZAzwcH
quoted
quoted
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.
quoted
quoted
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.
quoted
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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help