diff options
author | Oza Pawandeep <poza@codeaurora.org> | 2018-05-17 16:44:11 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2018-05-17 16:44:11 -0500 |
commit | 9f5a70f18c5893a30d6c339adc48de43c57dd7e2 (patch) | |
tree | a9883d7afecbedeffb9379bc88c9c5d06793f1ab /drivers/pci/pci.c | |
parent | 2af8641b2ad3c0faf1ba63e989ca2f2f2134e10d (diff) |
PCI: Add generic pcie_wait_for_link() interface
Clients such as hotplug and Downstream Port Containment (DPC) both need to
wait until a link becomes active or inactive.
Add a generic pcie_wait_link_active() interface and use it instead of
duplicating the code.
Signed-off-by: Oza Pawandeep <poza@codeaurora.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Keith Busch <keith.busch@intel.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e597655a5643..764bf64a097d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4138,6 +4138,35 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) return pci_dev_wait(dev, "PM D3->D0", PCIE_RESET_READY_POLL_MS); } +/** + * pcie_wait_for_link - Wait until link is active or inactive + * @pdev: Bridge device + * @active: waiting for active or inactive? + * + * Use this to wait till link becomes active or inactive. + */ +bool pcie_wait_for_link(struct pci_dev *pdev, bool active) +{ + int timeout = 1000; + bool ret; + u16 lnk_status; + + for (;;) { + pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); + ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); + if (ret == active) + return true; + if (timeout <= 0) + break; + msleep(10); + timeout -= 10; + } + + pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", + active ? "set" : "cleared"); + + return false; +} void pci_reset_secondary_bus(struct pci_dev *dev) { |