Skip to content

FROMLIST: PCI: qcom: Only check bridge nodes for PERST# GPIOs - #1758

Draft
Christopher Obbard (obbardc) wants to merge 1 commit into
qualcomm-linux:tech/bus/pci/allfrom
obbardc:wip/obbardc/pci-qcom-rb3gen2-usb-fix
Draft

FROMLIST: PCI: qcom: Only check bridge nodes for PERST# GPIOs#1758
Christopher Obbard (obbardc) wants to merge 1 commit into
qualcomm-linux:tech/bus/pci/allfrom
obbardc:wip/obbardc/pci-qcom-rb3gen2-usb-fix

Conversation

@obbardc

Copy link
Copy Markdown

qcom_pcie_parse_perst() walks the PCIe hierarchy described in the device tree below its root port and collects the PERST# GPIOs from each bridge node so all PERST# lines can be driven in unison during controller bring-up, reset and power sequencing.

However, the recursive device tree walk currently visits every available child node without checking that it is a PCI bridge. This allows the walk to leave the PCI hierarchy and collect reset lines from children of PCI enfpoitn nodes, where those reset lines belong to other drivers.

This is reproducible on the Qualcomm RB3Gen2, where a Renesas uPD720201 USB host controller sits behind a PCIe switch downstream port. A Genesys GL3590 USB hub connected to that controller is described as a child of the PCI endpoint:

pcie@2,0 {
	device_type = "pci";

	usb-controller@0,0 {
		compatible = "pci1912,0014";

		hub@1 {
			compatible = "usb5e3,610";
			reset-gpios = <&tlmm 162 GPIO_ACTIVE_HIGH>;
		};
	};
};

The USB controller is a PCI endpoint, and not a bridge, but the PERST# walk descends through it and incorrectly claims the hub's reset GPIO:

$ gpioinfo
line 162: unnamed output consumer=PERST#

As a result, the onboard-usb-dev driver cannot acquire its reset GPIO during probe:

onboard-usb-dev 1c08000.pcie:...:usb-controller@0,0:hub@1: \
  error -EBUSY: failed to get reset GPIO
onboard-usb-dev 1c08000.pcie:...:usb-controller@0,0:hub@1: \
  probe with driver onboard-usb-dev failed with error -16

The GPIO is also added to the root port's PERST# list and is asserted and deasserted as part of PCIe reset sequencing. On the RB3Gen2 this causes the USB hub to repeatedly re-enumerate:

[  116.479598] hub 2-1:1.0: USB hub found
[  116.488601] hub 2-1:1.0: USB hub found
[  116.496971] hub 2-1:1.0: USB hub found
...

This disrupts the hub and devices connected to it.

Restrict the recursive walk to children with device_type "pci", so PERST# GPIOs are collected only from PCI bridge nodes and the walk does not descend through endpoints.

qocm_pcie_parse_ports() has made the same distinction since commit 45df229 ("PCI: qcom: Restrict port parsing only to PCIe bridge child nodes"), but the PERST# walk added later did not carry over that check.

This bug is distinct from commit 3edb3a0 ("PCI: qcom: Skip PERST# GPIOs provided by downstream PCIe devices"), which filters PERST# GPIOs based on their provider. Here the GPIO is provided by the SoC TLMM; the bug is that reset-gpios is consumed from a non-bridge node at all.

Fixes: 2fd60a2 ("PCI: qcom: Parse PERST# from all PCIe bridge nodes")
Cc: stable@vger.kernel.org
Reviewed-by: Krishna Chaitanya Chundru krishna.chundru@oss.qualcomm.com

Link: https://lore.kernel.org/linux-arm-msm/20260829-wip-obbardc-drivers-pcie-qcom-rb3gen2-usb-fix-v1-1-337821131a99@oss.qualcomm.com/

qcom_pcie_parse_perst() walks the PCIe hierarchy described in the device
tree below its root port and collects the PERST# GPIOs from each bridge
node so all PERST# lines can be driven in unison during controller
bring-up, reset and power sequencing.

However, the recursive device tree walk currently visits every available
child node without checking that it is a PCI bridge. This allows the walk
to leave the PCI hierarchy and collect reset lines from children of PCI
enfpoitn nodes, where those reset lines belong to other drivers.

This is reproducible on the Qualcomm RB3Gen2, where a Renesas uPD720201
USB host controller sits behind a PCIe switch downstream port. A Genesys
GL3590 USB hub connected to that controller is described as a child of
the PCI endpoint:

	pcie@2,0 {
		device_type = "pci";

		usb-controller@0,0 {
			compatible = "pci1912,0014";

			hub@1 {
				compatible = "usb5e3,610";
				reset-gpios = <&tlmm 162 GPIO_ACTIVE_HIGH>;
			};
		};
	};

The USB controller is a PCI endpoint, and not a bridge, but the PERST#
walk descends through it and incorrectly claims the hub's reset GPIO:

	$ gpioinfo
	line 162: unnamed output consumer=PERST#

As a result, the onboard-usb-dev driver cannot acquire its reset GPIO
during probe:

	onboard-usb-dev 1c08000.pcie:...:usb-controller@0,0:hub@1: \
	  error -EBUSY: failed to get reset GPIO
	onboard-usb-dev 1c08000.pcie:...:usb-controller@0,0:hub@1: \
	  probe with driver onboard-usb-dev failed with error -16

The GPIO is also added to the root port's PERST# list and is asserted
and deasserted as part of PCIe reset sequencing. On the RB3Gen2 this
causes the USB hub to repeatedly re-enumerate:

	[  116.479598] hub 2-1:1.0: USB hub found
	[  116.488601] hub 2-1:1.0: USB hub found
	[  116.496971] hub 2-1:1.0: USB hub found
	...

This disrupts the hub and devices connected to it.

Restrict the recursive walk to children with device_type "pci", so
PERST# GPIOs are collected only from PCI bridge nodes and the walk
does not descend through endpoints.

qocm_pcie_parse_ports() has made the same distinction since
commit 45df229 ("PCI: qcom: Restrict port parsing only to PCIe
bridge child nodes"), but the PERST# walk added later did not carry over
that check.

This bug is distinct from commit 3edb3a0 ("PCI: qcom: Skip PERST#
GPIOs provided by downstream PCIe devices"), which filters PERST# GPIOs
based on their provider. Here the GPIO is provided by the SoC TLMM; the
bug is that reset-gpios is consumed from a non-bridge node at all.

Fixes: 2fd60a2 ("PCI: qcom: Parse PERST# from all PCIe bridge nodes")
Cc: stable@vger.kernel.org
Reviewed-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
Link: https://lore.kernel.org/linux-arm-msm/20260829-wip-obbardc-drivers-pcie-qcom-rb3gen2-usb-fix-v1-1-337821131a99@oss.qualcomm.com/
Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
@qcomlnxci
qcomlnxci requested review from a team, krishnachaitanya-linux and Matthew Leung (meleung) and removed request for a team August 31, 2026 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant