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: Manivannan Sadhasivam <mani@kernel.org>
Date: 2026-02-25 13:16:08
Also in: imx, linux-devicetree, linux-pci, lkml

On Tue, Feb 24, 2026 at 10:24:41AM +0000, Sherry Sun wrote:
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.

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,
+                                 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

-- 
மணிவண்ணன் சதாசிவம்
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help