[PATCH AUTOSEL 6.16-5.4] PCI: pnv_php: Work around switches with broken presence detection

Sasha Levin sashal at kernel.org
Sat Aug 9 01:30:48 AEST 2025


From: Timothy Pearson <tpearson at raptorengineering.com>

[ Upstream commit 80f9fc2362797538ebd4fd70a1dfa838cc2c2cdb ]

The Microsemi Switchtec PM8533 PFX 48xG3 [11f8:8533] PCIe switch system
was observed to incorrectly assert the Presence Detect Set bit in its
capabilities when tested on a Raptor Computing Systems Blackbird system,
resulting in the hot insert path never attempting a rescan of the bus
and any downstream devices not being re-detected.

Work around this by additionally checking whether the PCIe data link is
active or not when performing presence detection on downstream switches'
ports, similar to the pciehp_hpc.c driver.

Signed-off-by: Shawn Anastasio <sanastasio at raptorengineering.com>
Signed-off-by: Timothy Pearson <tpearson at raptorengineering.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
Signed-off-by: Madhavan Srinivasan <maddy at linux.ibm.com>
Link: https://patch.msgid.link/505981576.1359853.1752615415117.JavaMail.zimbra@raptorengineeringinc.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---

LLM Generated explanations, may be completely bogus:

**Backport Status: YES**

This commit is suitable for backporting to stable kernel trees based on
the following analysis:

## Commit Analysis

### 1. Bug Fix Nature
The commit fixes a real hardware bug where the Microsemi Switchtec
PM8533 PFX 48xG3 PCIe switch incorrectly reports presence detection.
This causes downstream devices to not be re-detected after hot
insertion, which is a significant functional issue affecting users.

### 2. Small and Contained Fix
The patch adds only 33 lines of code:
- Adds a new helper function `pcie_check_link_active()` (11 lines)
- Modifies `pnv_php_get_adapter_state()` with a targeted workaround (13
  lines)
- The changes are confined to a single file:
  `drivers/pci/hotplug/pnv_php.c`

### 3. Clear and Minimal Side Effects
The workaround is:
- Only activated for specific hardware (downstream PCIe ports)
- Only when presence detection returns EMPTY
- Uses an additional check (link active status) as a fallback
- Similar approach already proven in pciehp_hpc.c driver

### 4. Hardware Quirk Fix
This is explicitly a hardware quirk workaround for broken hardware
(Microsemi Switchtec PM8533), which is one of the accepted categories
for stable backports according to stable kernel rules.

### 5. No Architectural Changes
The commit:
- Does not introduce new features
- Does not change any APIs or interfaces
- Does not modify core kernel infrastructure
- Simply adds a fallback detection mechanism

### 6. Tested Solution
The commit message indicates this was "observed" and tested on a Raptor
Computing Systems Blackbird system, suggesting real-world validation.

## Stable Tree Compliance

According to Documentation/process/stable-kernel-rules.rst, this patch
meets the criteria:
- Fixes a real bug that bothers people (hotplug detection failure)
- Is a hardware quirk fix (explicitly allowed)
- Is under 100 lines with context
- Is obviously correct (uses established pattern from pciehp_hpc.c)
- Has clear user impact (devices not being detected after hot insertion)

The workaround pattern of checking link active status when presence
detection fails is a well-established approach in PCIe hotplug drivers,
making this a low-risk backport candidate.

 drivers/pci/hotplug/pnv_php.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 573a41869c15..aaa8e0a2a893 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -391,6 +391,20 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
 	return 0;
 }
 
+static int pcie_check_link_active(struct pci_dev *pdev)
+{
+	u16 lnk_status;
+	int ret;
+
+	ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
+	if (ret == PCIBIOS_DEVICE_NOT_FOUND || PCI_POSSIBLE_ERROR(lnk_status))
+		return -ENODEV;
+
+	ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
+
+	return ret;
+}
+
 static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
 {
 	struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
@@ -403,6 +417,19 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
 	 */
 	ret = pnv_pci_get_presence_state(php_slot->id, &presence);
 	if (ret >= 0) {
+		if (pci_pcie_type(php_slot->pdev) == PCI_EXP_TYPE_DOWNSTREAM &&
+			presence == OPAL_PCI_SLOT_EMPTY) {
+			/*
+			 * Similar to pciehp_hpc, check whether the Link Active
+			 * bit is set to account for broken downstream bridges
+			 * that don't properly assert Presence Detect State, as
+			 * was observed on the Microsemi Switchtec PM8533 PFX
+			 * [11f8:8533].
+			 */
+			if (pcie_check_link_active(php_slot->pdev) > 0)
+				presence = OPAL_PCI_SLOT_PRESENT;
+		}
+
 		*state = presence;
 		ret = 0;
 	} else {
-- 
2.39.5



More information about the Linuxppc-dev mailing list