Skip to content

Commit 37edd87

Browse files
maciej-w-rozyckibjorn-helgaas
authored andcommitted
PCI: Export pcie_retrain_link() for use outside ASPM
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/[email protected] Signed-off-by: Maciej W. Rozycki <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]>
1 parent 33a176a commit 37edd87

File tree

3 files changed

+50
-42
lines changed

3 files changed

+50
-42
lines changed

drivers/pci/pci.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4856,6 +4856,55 @@ static int pci_pm_reset(struct pci_dev *dev, bool probe)
48564856
return pci_dev_wait(dev, "PM D3hot->D0", PCIE_RESET_READY_POLL_MS);
48574857
}
48584858

4859+
/**
4860+
* pcie_wait_for_link_status - Wait for link training end
4861+
* @pdev: Device whose link to wait for.
4862+
*
4863+
* Return TRUE if successful, or FALSE if training has not completed
4864+
* within PCIE_LINK_RETRAIN_TIMEOUT_MS milliseconds.
4865+
*/
4866+
static bool pcie_wait_for_link_status(struct pci_dev *pdev)
4867+
{
4868+
unsigned long end_jiffies;
4869+
u16 lnksta;
4870+
4871+
end_jiffies = jiffies + msecs_to_jiffies(PCIE_LINK_RETRAIN_TIMEOUT_MS);
4872+
do {
4873+
pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnksta);
4874+
if (!(lnksta & PCI_EXP_LNKSTA_LT))
4875+
break;
4876+
msleep(1);
4877+
} while (time_before(jiffies, end_jiffies));
4878+
return !(lnksta & PCI_EXP_LNKSTA_LT);
4879+
}
4880+
4881+
/**
4882+
* pcie_retrain_link - Request a link retrain and wait for it to complete
4883+
* @pdev: Device whose link to retrain.
4884+
*
4885+
* Return TRUE if successful, or FALSE if training has not completed
4886+
* within PCIE_LINK_RETRAIN_TIMEOUT_MS milliseconds.
4887+
*/
4888+
bool pcie_retrain_link(struct pci_dev *pdev)
4889+
{
4890+
u16 lnkctl;
4891+
4892+
pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnkctl);
4893+
lnkctl |= PCI_EXP_LNKCTL_RL;
4894+
pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl);
4895+
if (pdev->clear_retrain_link) {
4896+
/*
4897+
* Due to an erratum in some devices the Retrain Link bit
4898+
* needs to be cleared again manually to allow the link
4899+
* training to succeed.
4900+
*/
4901+
lnkctl &= ~PCI_EXP_LNKCTL_RL;
4902+
pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl);
4903+
}
4904+
4905+
return pcie_wait_for_link_status(pdev);
4906+
}
4907+
48594908
/**
48604909
* pcie_wait_for_link_delay - Wait until link is active or inactive
48614910
* @pdev: Bridge device

drivers/pci/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
565565
pci_ers_result_t (*reset_subordinates)(struct pci_dev *pdev));
566566

567567
bool pcie_wait_for_link(struct pci_dev *pdev, bool active);
568+
bool pcie_retrain_link(struct pci_dev *pdev);
568569
#ifdef CONFIG_PCIEASPM
569570
void pcie_aspm_init_link_state(struct pci_dev *pdev);
570571
void pcie_aspm_exit_link_state(struct pci_dev *pdev);

drivers/pci/pcie/aspm.c

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -191,48 +191,6 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
191191
link->clkpm_disable = blacklist ? 1 : 0;
192192
}
193193

194-
/**
195-
* pcie_wait_for_link_status - Wait for link training end
196-
* @pdev: Device whose link to wait for.
197-
*
198-
* Return TRUE if successful, or FALSE if training has not completed
199-
* within PCIE_LINK_RETRAIN_TIMEOUT_MS milliseconds.
200-
*/
201-
static bool pcie_wait_for_link_status(struct pci_dev *pdev)
202-
{
203-
unsigned long end_jiffies;
204-
u16 lnksta;
205-
206-
end_jiffies = jiffies + msecs_to_jiffies(PCIE_LINK_RETRAIN_TIMEOUT_MS);
207-
do {
208-
pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnksta);
209-
if (!(lnksta & PCI_EXP_LNKSTA_LT))
210-
break;
211-
msleep(1);
212-
} while (time_before(jiffies, end_jiffies));
213-
return !(lnksta & PCI_EXP_LNKSTA_LT);
214-
}
215-
216-
static bool pcie_retrain_link(struct pci_dev *pdev)
217-
{
218-
u16 lnkctl;
219-
220-
pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnkctl);
221-
lnkctl |= PCI_EXP_LNKCTL_RL;
222-
pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl);
223-
if (pdev->clear_retrain_link) {
224-
/*
225-
* Due to an erratum in some devices the Retrain Link bit
226-
* needs to be cleared again manually to allow the link
227-
* training to succeed.
228-
*/
229-
lnkctl &= ~PCI_EXP_LNKCTL_RL;
230-
pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnkctl);
231-
}
232-
233-
return pcie_wait_for_link_status(pdev);
234-
}
235-
236194
/*
237195
* pcie_aspm_configure_common_clock: check if the 2 ends of a link
238196
* could use common clock. If they are, configure them to use the

0 commit comments

Comments
 (0)