PCI: Export pcie_retrain_link() for use outside ASPM
authorMaciej W. Rozycki <macro@orcam.me.uk>
Sun, 11 Jun 2023 17:19:41 +0000 (18:19 +0100)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 20 Jun 2023 15:58:53 +0000 (10:58 -0500)
Export pcie_retrain_link() for link retrain needs outside ASPM.  Struct
pcie_link_state is local to ASPM and only used by pcie_retrain_link() to
get at the associated PCI device, so change the operand and adjust the lone
call site accordingly.  Document the interface.  No functional change at
this point.

Link: https://lore.kernel.org/r/alpine.DEB.2.21.2306110229010.64925@angie.orcam.me.uk
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aspm.c

index 71645d5..47ceb85 100644 (file)
@@ -4857,6 +4857,55 @@ static int pci_pm_reset(struct pci_dev *dev, bool probe)
 }
 
 /**
+ * pcie_wait_for_link_status - Wait for link training end
+ * @pdev: Device whose link to wait for.
+ *
+ * Return TRUE if successful, or FALSE if training has not completed
+ * within PCIE_LINK_RETRAIN_TIMEOUT_MS milliseconds.
+ */
+static bool pcie_wait_for_link_status(struct pci_dev *pdev)
+{
+       unsigned long end_jiffies;
+       u16 lnksta;
+
+       end_jiffies = jiffies + msecs_to_jiffies(PCIE_LINK_RETRAIN_TIMEOUT_MS);
+       do {
+               pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnksta);
+               if (!(lnksta & PCI_EXP_LNKSTA_LT))
+                       break;
+               msleep(1);
+       } while (time_before(jiffies, end_jiffies));
+       return !(lnksta & PCI_EXP_LNKSTA_LT);
+}
+
+/**
+ * pcie_retrain_link - Request a link retrain and wait for it to complete
+ * @pdev: Device whose link to retrain.
+ *
+ * Return TRUE if successful, or FALSE if training has not completed
+ * within PCIE_LINK_RETRAIN_TIMEOUT_MS milliseconds.
+ */
+bool pcie_retrain_link(struct pci_dev *pdev)
+{
+       u16 lnkctl;
+
+       pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnkctl);
+       lnkctl |= PCI_EXP_LNKCTL_RL;
+       pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl);
+       if (pdev->clear_retrain_link) {
+               /*
+                * Due to an erratum in some devices the Retrain Link bit
+                * needs to be cleared again manually to allow the link
+                * training to succeed.
+                */
+               lnkctl &= ~PCI_EXP_LNKCTL_RL;
+               pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl);
+       }
+
+       return pcie_wait_for_link_status(pdev);
+}
+
+/**
  * pcie_wait_for_link_delay - Wait until link is active or inactive
  * @pdev: Bridge device
  * @active: waiting for active or inactive?
index d5fe253..0d9671b 100644 (file)
@@ -565,6 +565,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
                pci_ers_result_t (*reset_subordinates)(struct pci_dev *pdev));
 
 bool pcie_wait_for_link(struct pci_dev *pdev, bool active);
+bool pcie_retrain_link(struct pci_dev *pdev);
 #ifdef CONFIG_PCIEASPM
 void pcie_aspm_init_link_state(struct pci_dev *pdev);
 void pcie_aspm_exit_link_state(struct pci_dev *pdev);
index 721e5c7..0c5d392 100644 (file)
@@ -191,48 +191,6 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
        link->clkpm_disable = blacklist ? 1 : 0;
 }
 
-/**
- * pcie_wait_for_link_status - Wait for link training end
- * @pdev: Device whose link to wait for.
- *
- * Return TRUE if successful, or FALSE if training has not completed
- * within PCIE_LINK_RETRAIN_TIMEOUT_MS milliseconds.
- */
-static bool pcie_wait_for_link_status(struct pci_dev *pdev)
-{
-       unsigned long end_jiffies;
-       u16 lnksta;
-
-       end_jiffies = jiffies + msecs_to_jiffies(PCIE_LINK_RETRAIN_TIMEOUT_MS);
-       do {
-               pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnksta);
-               if (!(lnksta & PCI_EXP_LNKSTA_LT))
-                       break;
-               msleep(1);
-       } while (time_before(jiffies, end_jiffies));
-       return !(lnksta & PCI_EXP_LNKSTA_LT);
-}
-
-static bool pcie_retrain_link(struct pci_dev *pdev)
-{
-       u16 lnkctl;
-
-       pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnkctl);
-       lnkctl |= PCI_EXP_LNKCTL_RL;
-       pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl);
-       if (pdev->clear_retrain_link) {
-               /*
-                * Due to an erratum in some devices the Retrain Link bit
-                * needs to be cleared again manually to allow the link
-                * training to succeed.
-                */
-               lnkctl &= ~PCI_EXP_LNKCTL_RL;
-               pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl);
-       }
-
-       return pcie_wait_for_link_status(pdev);
-}
-
 /*
  * pcie_aspm_configure_common_clock: check if the 2 ends of a link
  *   could use common clock. If they are, configure them to use the