Re: [PATCH v2] PCI: quirks: Add warm reset quirk for IBM Spyre accelerator
Mahesh J Salgaonkar <[email protected]>
| Newsgroups | gmane.linux.ports.ppc.embedded,gmane.linux.kernel.pci,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
On 2026-08-21 18:04:01 Fri, Avinash Roy wrote: > From: Shivaprasad G Bhat <[email protected]> > > The IBM Spyre accelerator (PCI ID 1014:06a7) requires a dedicated warm > reset method for reliable EEH recovery on pSeries/ppc64 platforms. > > FLR alone is insufficient because it does not re-initialize firmware > state machine for the current version of the card. The existing API > pci_set_pcie_reset_state() is used to drive the platform-level > PERST# using the EEH interfaces by adding a device specific quirk. > > The reset function is placed in arch/powerpc/platforms/pseries/pci.c > where the EEH infrastructure is already present, declared in > pseries.h, and registered in the generic pci_dev_reset_methods[] table > in drivers/pci/quirks.c under a CONFIG_PPC_PSERIES guard. > > This reset method is only registered when CONFIG_PPC_PSERIES is enabled, > so it is not available on other platforms. > > Reset sequence: > - Assert PERST# via pcie_warm_reset, hold 250 ms > - Deassert PERST# via pcie_deassert_reset > - Wait 250 ms for PCIe link retrain > > Signed-off-by: Avinash Roy <[email protected]> > Signed-off-by: Shivaprasad G Bhat <[email protected]> > > --- > Changelog > v1: https://lore.kernel.org/linux-pci/[email protected]/ > > Reworded the commit message to highlight the warm reset requirement being > a need of the current card and not a platform deficiency. > > diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c > index 84e4ffe957a8..7aa58d57208f 100644 > --- a/arch/powerpc/platforms/pseries/pci.c > +++ b/arch/powerpc/platforms/pseries/pci.c > @@ -11,6 +11,7 @@ > #include <linux/kernel.h> > #include <linux/pci.h> > #include <linux/string.h> > +#include <linux/delay.h> > > #include <asm/eeh.h> > #include <asm/pci-bridge.h> > @@ -236,6 +237,41 @@ static void fixup_winbond_82c105(struct pci_dev* dev) > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, > fixup_winbond_82c105); > > +/* > + * Reset Spyre adapter using pci_set_pcie_reset_state() > + * This is specifically for PPC platforms where EEH (Enhanced Error Handling) > + * requires this reset method for proper device recovery. > + */ > +int reset_spyre(struct pci_dev *dev, bool probe) > +{ > + int ret; > + > + if (probe) > + return 0; > + > + /* Assert warm reset */ > + ret = pci_set_pcie_reset_state(dev, pcie_warm_reset); > + if (ret) { > + pci_err(dev, "Failed to assert reset: %d\n", ret); > + return ret; > + } > + > + /* Wait for reset to take effect */ > + msleep(250); How did you arriver on this number ? Is this time defined by hardware/firmware specs for reset ? Also, Can you #define the value 250 and use macro instead of constant numbmer. > + > + /* Deassert reset */ > + ret = pci_set_pcie_reset_state(dev, pcie_deassert_reset); > + if (ret) { > + pci_err(dev, "Failed to deassert reset: %d\n", ret); > + return ret; > + } > + > + /* Wait for device to recover */ > + msleep(250); same here. > + > + return 0; > +} > + Thanks, -Mahesh.