diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2024-09-19 14:25:25 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2024-09-19 14:25:25 -0500 |
commit | dffe4cca2e36e5a546fccf3f39a444731887ba9a (patch) | |
tree | 063020a6130e93013037bd8b9f8963eb46a3735c /drivers/pci/pci.c | |
parent | dceed69701ac2ac357c062117a3f201096c4bdab (diff) | |
parent | 59100eb248c0b15585affa546c7f6834b30eb5a4 (diff) | |
download | linux-dffe4cca2e36e5a546fccf3f39a444731887ba9a.tar.gz linux-dffe4cca2e36e5a546fccf3f39a444731887ba9a.tar.bz2 linux-dffe4cca2e36e5a546fccf3f39a444731887ba9a.zip |
Merge branch 'pci/enumeration'
- Clear LBMS bit after a manual link retrain so we don't try to retrain a
link when there's no downstream device anymore (Maciej W. Rozycki)
- Revert to the original link speed after retraining fails instead of
leaving it restricted to 2.5GT/s, so a future device has a chance to use
higher speeds (Maciej W. Rozycki)
- Correct interpretation of pcie_retrain_link() return status and update it
to return 0/errno instead of true/false (Maciej W. Rozycki)
* pci/enumeration:
PCI: Use an error code with PCIe failed link retraining
PCI: Correct error reporting with PCIe failed link retraining
PCI: Revert to the original speed after PCIe failed link retraining
PCI: Clear the LBMS bit after a link retrain
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 55d6124acb2d..7148a3d4ec8d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1339,7 +1339,7 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) if (delay > PCI_RESET_WAIT) { if (retrain) { retrain = false; - if (pcie_failed_link_retrain(bridge)) { + if (pcie_failed_link_retrain(bridge) == 0) { delay = 1; continue; } @@ -4732,7 +4732,15 @@ int pcie_retrain_link(struct pci_dev *pdev, bool use_lt) pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_RL); } - return pcie_wait_for_link_status(pdev, use_lt, !use_lt); + rc = pcie_wait_for_link_status(pdev, use_lt, !use_lt); + + /* + * Clear LBMS after a manual retrain so that the bit can be used + * to track link speed or width changes made by hardware itself + * in attempt to correct unreliable link operation. + */ + pcie_capability_write_word(pdev, PCI_EXP_LNKSTA, PCI_EXP_LNKSTA_LBMS); + return rc; } /** |