From 3c0ec896a4b42bc4751c71cac5996d23d3b648ae Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sun, 11 Jun 2023 18:19:49 +0100 Subject: [PATCH] PCI/ASPM: Factor out waiting for link training to complete Move code polling for the Link Training bit to clear into a function of its own. [bhelgaas: reorder to clean up before exposing to PCI core] Link: https://lore.kernel.org/r/alpine.DEB.2.21.2306111605060.64925@angie.orcam.me.uk Signed-off-by: Maciej W. Rozycki Signed-off-by: Bjorn Helgaas --- drivers/pci/pcie/aspm.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index e2cfff3a0a2e0..eaaacf24e16cc 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -193,12 +193,32 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) link->clkpm_disable = blacklist ? 1 : 0; } -static bool pcie_retrain_link(struct pci_dev *pdev) +/** + * 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 LINK_RETRAIN_TIMEOUT jiffies. + */ +static bool pcie_wait_for_link_status(struct pci_dev *pdev) { unsigned long end_jiffies; - u16 lnkctl; u16 lnksta; + end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; + 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); @@ -212,15 +232,7 @@ static bool pcie_retrain_link(struct pci_dev *pdev) pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl); } - /* Wait for link training end. Break out after waiting for timeout */ - end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; - 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); + return pcie_wait_for_link_status(pdev); } /* -- 2.30.2