Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH 0/2] PCI: of: Skip config reads for disabled bridges
@ 2026-10-09  7:25 Xilin Wu
  2026-10-09  7:25 ` [PATCH 1/2] PCI: of: Correct pci_set_of_node() return value documentation Xilin Wu
  2026-10-09  7:25 ` [PATCH 2/2] PCI: of: Avoid config reads for disabled bridge nodes Xilin Wu
  0 siblings, 2 replies; 5+ messages in thread
From: Xilin Wu @ 2026-10-09  7:25 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Manivannan Sadhasivam, Rob Herring, linux-pci, devicetree,
	linux-arm-msm, linux-kernel, Stephen Chen, Junhao Xie,
	Daniele Briguglio, dragon, Xilin Wu, Manivannan Sadhasivam

Hi,

This series extracts the PCI change from the Radxa Dragon Q8B board
support series for review and application through the PCI tree, as
requested by Manivannan Sadhasivam.

The TC9563 PCI power-control driver powers off downstream ports marked
disabled in the device tree. Probing these port functions on the Dragon
Q8B causes a Completion Timeout, which the Root Complex reports as an AXI
bus error, triggering an Arm SError and preventing boot. The Root Port
to switch upstream link remains up, so a config-access blocker triggered
by Root Port link-down does not address this case.

Patch 1 corrects the stale return value documentation for
pci_set_of_node(). Patch 2 skips Vendor ID reads for unavailable
DT-described PCI bridges before any config access. Disabled endpoints
remain discoverable so that PCI fixups can run, with driver binding
suppressed as before.

Compared with the PCI patch in the original board support series:
- Split the unrelated kernel-doc correction into a separate patch.
- Explain the Completion Timeout and SError path in the commit message.
- Retain the generic PCI implementation, since the issue is not specific
  to Qualcomm hosts.

The functional change is required by the Dragon Q8B device tree, but this
series has no dependency on the board or display patches.

Previous posting:
https://lore.kernel.org/all/20260901-q8b-dts-v1-1-7de0b6a73d08@radxa.com/
Review discussion:
https://lore.kernel.org/all/fsrr5xg4plfknfcvv5co4ciklz5pywa5bbfxbthwsnjevysr5v@myghuxblnend/
https://lore.kernel.org/all/r22to3joold7ugzwolni4qahyumcekbyugrl2bms3xmiysqtgo@hu5s3dnyqwsj/

Signed-off-by: Xilin Wu <sophon@radxa.com>
---
Xilin Wu (2):
      PCI: of: Correct pci_set_of_node() return value documentation
      PCI: of: Avoid config reads for disabled bridge nodes

 drivers/pci/of.c    | 27 +++++++++++++++++++++++++--
 drivers/pci/pci.h   |  5 +++++
 drivers/pci/probe.c |  5 +++++
 3 files changed, 35 insertions(+), 2 deletions(-)
---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
change-id: 20261009-pci-of-disabled-bridges-8406f7c92de2

Best regards,
--  
Xilin Wu <sophon@radxa.com>


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

* [PATCH 1/2] PCI: of: Correct pci_set_of_node() return value documentation
  2026-10-09  7:25 [PATCH 0/2] PCI: of: Skip config reads for disabled bridges Xilin Wu
@ 2026-10-09  7:25 ` Xilin Wu
  2026-10-09  7:33   ` sashiko-bot
  2026-10-09  7:25 ` [PATCH 2/2] PCI: of: Avoid config reads for disabled bridge nodes Xilin Wu
  1 sibling, 1 reply; 5+ messages in thread
From: Xilin Wu @ 2026-10-09  7:25 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Manivannan Sadhasivam, Rob Herring, linux-pci, devicetree,
	linux-arm-msm, linux-kernel, Stephen Chen, Junhao Xie,
	Daniele Briguglio, dragon, Xilin Wu

Commit 1a8c251cff20 ("PCI: move OF status = "disabled" detection to
dev->match_driver") removed the availability check from pci_set_of_node().
The function now returns 0 even when the device is disabled in the device
tree, but its kernel-doc still says that it can return -ENODEV.

Remove the stale -ENODEV description and use the kernel-doc Return:
heading for the return value.

Signed-off-by: Xilin Wu <sophon@radxa.com>
---
 drivers/pci/of.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index a51dff91b196..9e82c79be3d8 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -24,8 +24,8 @@
  * pci_set_of_node - Find and set device's DT device_node
  * @dev: the PCI device structure to fill
  *
- * Returns 0 on success with of_node set or when no device is described in the
- * DT. Returns -ENODEV if the device is present, but disabled in the DT.
+ * Return: 0 on success with of_node set or when no device is described in the
+ * DT.
  */
 int pci_set_of_node(struct pci_dev *dev)
 {

-- 
2.56.0


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

* [PATCH 2/2] PCI: of: Avoid config reads for disabled bridge nodes
  2026-10-09  7:25 [PATCH 0/2] PCI: of: Skip config reads for disabled bridges Xilin Wu
  2026-10-09  7:25 ` [PATCH 1/2] PCI: of: Correct pci_set_of_node() return value documentation Xilin Wu
@ 2026-10-09  7:25 ` Xilin Wu
  2026-10-09  7:33   ` sashiko-bot
  1 sibling, 1 reply; 5+ messages in thread
From: Xilin Wu @ 2026-10-09  7:25 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Manivannan Sadhasivam, Rob Herring, linux-pci, devicetree,
	linux-arm-msm, linux-kernel, Stephen Chen, Junhao Xie,
	Daniele Briguglio, dragon, Xilin Wu, Manivannan Sadhasivam

The TC9563 PCI power-control driver powers off external downstream ports
whose device tree nodes have status = "disabled". On the Radxa Dragon Q8B,
reading the Vendor ID of one of these powered-off port functions during
PCI enumeration raises an Arm SError and prevents the board from booting.

A Configuration Read request to an unavailable port receives no
completion and results in a Completion Timeout. The PCIe Root Complex
reports that timeout as an AXI bus error, which triggers an SError on the
CPU. The link between the Root Port and the switch upstream port remains
up, so blocking config accesses only when the Root Port link is down
does not prevent these accesses.

Commit 1a8c251cff20 ("PCI: move OF status = "disabled" detection to
dev->match_driver") kept disabled PCI functions discoverable so that PCI
fixups could still run, while suppressing driver binding later. Preserve
that behavior for endpoint functions.

For an unavailable device tree node with device_type = "pci", skip the
Vendor ID read and return a PCI error response without accessing config
space. This prevents enumeration of the disabled bridge and its
subordinate bus. Perform the check in the generic PCI enumeration path
because probing unavailable bridges is not specific to Qualcomm hosts.

Functions without a device tree node and disabled endpoint functions
remain discoverable.

Link: https://lore.kernel.org/all/fsrr5xg4plfknfcvv5co4ciklz5pywa5bbfxbthwsnjevysr5v@myghuxblnend/
Link: https://lore.kernel.org/all/r22to3joold7ugzwolni4qahyumcekbyugrl2bms3xmiysqtgo@hu5s3dnyqwsj/
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Daniele Briguglio <hello@superkali.me>
Signed-off-by: Xilin Wu <sophon@radxa.com>
---
 drivers/pci/of.c    | 23 +++++++++++++++++++++++
 drivers/pci/pci.h   |  5 +++++
 drivers/pci/probe.c |  5 +++++
 3 files changed, 33 insertions(+)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 9e82c79be3d8..37e9062065d7 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -46,6 +46,29 @@ int pci_set_of_node(struct pci_dev *dev)
 	return 0;
 }
 
+/**
+ * pci_of_device_skip_config_read - check whether to skip probing a PCI device
+ * @bus: PCI bus to scan
+ * @devfn: device/function number to check
+ *
+ * Return: true only when firmware explicitly describes an unavailable PCI
+ * bridge/port node. Disabled endpoints remain discoverable so fixups still run,
+ * while driver binding is suppressed later in pci_bus_add_device().
+ */
+bool pci_of_device_skip_config_read(struct pci_bus *bus, unsigned int devfn)
+{
+	if (!bus->dev.of_node)
+		return false;
+
+	struct device_node *node __free(device_node) =
+		of_pci_find_child_device(bus->dev.of_node, devfn);
+
+	if (!node || of_device_is_available(node))
+		return false;
+
+	return of_node_is_type(node, "pci");
+}
+
 void pci_release_of_node(struct pci_dev *dev)
 {
 	of_node_put(dev->dev.of_node);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index ba3c3fddddc2..7cb1d04d947d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1244,6 +1244,7 @@ u32 of_pci_get_slot_power_limit(struct device_node *node,
 				u8 *slot_power_limit_scale);
 bool of_pci_preserve_config(struct device_node *node);
 int pci_set_of_node(struct pci_dev *dev);
+bool pci_of_device_skip_config_read(struct pci_bus *bus, unsigned int devfn);
 void pci_release_of_node(struct pci_dev *dev);
 void pci_set_bus_of_node(struct pci_bus *bus);
 void pci_release_bus_of_node(struct pci_bus *bus);
@@ -1284,6 +1285,10 @@ static inline bool of_pci_preserve_config(struct device_node *node)
 }
 
 static inline int pci_set_of_node(struct pci_dev *dev) { return 0; }
+static inline bool pci_of_device_skip_config_read(struct pci_bus *bus, unsigned int devfn)
+{
+	return false;
+}
 static inline void pci_release_of_node(struct pci_dev *dev) { }
 static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
 static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 27008e2ea5af..ce29bf78a6f7 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2586,6 +2586,11 @@ bool pci_bus_generic_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
 bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
 				int timeout)
 {
+	if (pci_of_device_skip_config_read(bus, devfn)) {
+		PCI_SET_ERROR_RESPONSE(l);
+		return false;
+	}
+
 	return pci_bus_generic_read_dev_vendor_id(bus, devfn, l, timeout);
 }
 EXPORT_SYMBOL(pci_bus_read_dev_vendor_id);

-- 
2.56.0


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

* Re: [PATCH 2/2] PCI: of: Avoid config reads for disabled bridge nodes
  2026-10-09  7:25 ` [PATCH 2/2] PCI: of: Avoid config reads for disabled bridge nodes Xilin Wu
@ 2026-10-09  7:33   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-10-09  7:33 UTC (permalink / raw)
  To: Xilin Wu; +Cc: devicetree, linux-pci, robh, conor+dt

> The TC9563 PCI power-control driver powers off external downstream ports
> whose device tree nodes have status = "disabled". On the Radxa Dragon Q8B,
> reading the Vendor ID of one of these powered-off port functions during
> PCI enumeration raises an Arm SError and prevents the board from booting.
> 
> A Configuration Read request to an unavailable port receives no
> completion and results in a Completion Timeout. The PCIe Root Complex
> reports that timeout as an AXI bus error, which triggers an SError on the
> CPU. The link between the Root Port and the switch upstream port remains
> up, so blocking config accesses only when the Root Port link is down
> does not prevent these accesses.
> 
> Commit 1a8c251cff20 ("PCI: move OF status = "disabled" detection to
> dev->match_driver") kept disabled PCI functions discoverable so that PCI
> fixups could still run, while suppressing driver binding later. Preserve
> [ ... ]
> Link: https://lore.kernel.org/all/fsrr5xg4plfknfcvv5co4ciklz5pywa5bbfxbthwsnjevysr5v@myghuxblnend/
> Link: https://lore.kernel.org/all/r22to3joold7ugzwolni4qahyumcekbyugrl2bms3xmiysqtgo@hu5s3dnyqwsj/
> Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> Tested-by: Daniele Briguglio <hello@superkali.me>
> Signed-off-by: Xilin Wu <sophon@radxa.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261009-pci-of-disabled-bridges-v1-0-08708f9e1802@radxa.com?part=2


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

* Re: [PATCH 1/2] PCI: of: Correct pci_set_of_node() return value documentation
  2026-10-09  7:25 ` [PATCH 1/2] PCI: of: Correct pci_set_of_node() return value documentation Xilin Wu
@ 2026-10-09  7:33   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-10-09  7:33 UTC (permalink / raw)
  To: Xilin Wu; +Cc: linux-pci, robh, conor+dt, devicetree

> Commit 1a8c251cff20 ("PCI: move OF status = "disabled" detection to
> dev->match_driver") removed the availability check from pci_set_of_node().
> The function now returns 0 even when the device is disabled in the device
> tree, but its kernel-doc still says that it can return -ENODEV.
> 
> Remove the stale -ENODEV description and use the kernel-doc Return:
> heading for the return value.
> 
> Signed-off-by: Xilin Wu <sophon@radxa.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261009-pci-of-disabled-bridges-v1-0-08708f9e1802@radxa.com?part=1


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

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

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-09  7:25 [PATCH 0/2] PCI: of: Skip config reads for disabled bridges Xilin Wu
2026-10-09  7:25 ` [PATCH 1/2] PCI: of: Correct pci_set_of_node() return value documentation Xilin Wu
2026-10-09  7:33   ` sashiko-bot
2026-10-09  7:25 ` [PATCH 2/2] PCI: of: Avoid config reads for disabled bridge nodes Xilin Wu
2026-10-09  7:33   ` sashiko-bot

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