[PATCH v2 2/6] pci/hotplug/pnv_php: Work around switches with broken
Bjorn Helgaas
helgaas at kernel.org
Thu Jun 19 05:44:00 AEST 2025
[+cc Lukas, pciehp expert]
On Wed, Jun 18, 2025 at 11:56:54AM -0500, Timothy Pearson wrote:
> presence detection
(subject/commit wrapping seems to be on all of these patches)
> 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.
Seems like this switch supports standard PCIe hotplug? Quite a bit of
this driver looks similar to things in pciehp. Is there some reason
we can't use pciehp directly? Maybe pciehp could work if there were
hooks for the PPC-specific bits?
> 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>
> ---
> 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 aec0a6d594ac..bac8af3df41a 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