diff options
Diffstat (limited to 'drivers/pci/pci.c')
| -rw-r--r-- | drivers/pci/pci.c | 30 | 
1 files changed, 9 insertions, 21 deletions
| diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ce096272f52b..c9338f914a0e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4638,8 +4638,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)   * pcie_wait_for_link_delay - Wait until link is active or inactive   * @pdev: Bridge device   * @active: waiting for active or inactive? - * @delay: Delay to wait after link has become active (in ms). Specify %0 - *	   for no delay. + * @delay: Delay to wait after link has become active (in ms)   *   * Use this to wait till link becomes active or inactive.   */ @@ -4680,7 +4679,7 @@ static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active,  		msleep(10);  		timeout -= 10;  	} -	if (active && ret && delay) +	if (active && ret)  		msleep(delay);  	else if (ret != active)  		pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", @@ -4801,28 +4800,17 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev)  	if (!pcie_downstream_port(dev))  		return; -	/* -	 * Per PCIe r5.0, sec 6.6.1, for downstream ports that support -	 * speeds > 5 GT/s, we must wait for link training to complete -	 * before the mandatory delay. -	 * -	 * We can only tell when link training completes via DLL Link -	 * Active, which is required for downstream ports that support -	 * speeds > 5 GT/s (sec 7.5.3.6).  Unfortunately some common -	 * devices do not implement Link Active reporting even when it's -	 * required, so we'll check for that directly instead of checking -	 * the supported link speed.  We assume devices without Link Active -	 * reporting can train in 100 ms regardless of speed. -	 */ -	if (dev->link_active_reporting) { -		pci_dbg(dev, "waiting for link to train\n"); -		if (!pcie_wait_for_link_delay(dev, true, 0)) { +	if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) { +		pci_dbg(dev, "waiting %d ms for downstream link\n", delay); +		msleep(delay); +	} else { +		pci_dbg(dev, "waiting %d ms for downstream link, after activation\n", +			delay); +		if (!pcie_wait_for_link_delay(dev, true, delay)) {  			/* Did not train, no need to wait any further */  			return;  		}  	} -	pci_dbg(child, "waiting %d ms to become accessible\n", delay); -	msleep(delay);  	if (!pci_device_is_present(child)) {  		pci_dbg(child, "waiting additional %d ms to become accessible\n", delay); |