[+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 <sanasta...@raptorengineering.com>
> Signed-off-by: Timothy Pearson <tpear...@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

Reply via email to