aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie/aspm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie/aspm.c')
-rw-r--r--drivers/pci/pcie/aspm.c67
1 files changed, 25 insertions, 42 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 68a4d4b15f9f..694ba5657758 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -370,56 +370,39 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
370 } 370 }
371} 371}
372 372
373static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev, 373/**
374 unsigned int state) 374 * __pcie_aspm_check_state_one - check latency for endpoint device.
375 * @endpoint: pointer to the struct pci_dev of endpoint device
376 *
377 * TBD: The latency from the endpoint to root complex vary per switch's
378 * upstream link state above the device. Here we just do a simple check
379 * which assumes all links above the device can be in L1 state, that
380 * is we just consider the worst case. If switch's upstream link can't
381 * be put into L0S/L1, then our check is too strictly.
382 */
383static u32 __pcie_aspm_check_state_one(struct pci_dev *endpoint, u32 state)
375{ 384{
376 struct pci_dev *parent_dev, *tmp_dev; 385 u32 l1_switch_latency = 0;
377 unsigned int l1_latency = 0;
378 struct pcie_link_state *link_state;
379 struct aspm_latency *acceptable; 386 struct aspm_latency *acceptable;
387 struct pcie_link_state *link;
380 388
381 parent_dev = pdev->bus->self; 389 link = endpoint->bus->self->link_state;
382 link_state = parent_dev->link_state; 390 state &= link->aspm_support;
383 state &= link_state->aspm_support; 391 acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];
384 if (state == 0)
385 return 0;
386 acceptable = &link_state->acceptable[PCI_FUNC(pdev->devfn)];
387 392
388 /* 393 while (link && state) {
389 * Check latency for endpoint device.
390 * TBD: The latency from the endpoint to root complex vary per
391 * switch's upstream link state above the device. Here we just do a
392 * simple check which assumes all links above the device can be in L1
393 * state, that is we just consider the worst case. If switch's upstream
394 * link can't be put into L0S/L1, then our check is too strictly.
395 */
396 tmp_dev = pdev;
397 while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
398 parent_dev = tmp_dev->bus->self;
399 link_state = parent_dev->link_state;
400 if ((state & PCIE_LINK_STATE_L0S) && 394 if ((state & PCIE_LINK_STATE_L0S) &&
401 (link_state->latency.l0s > acceptable->l0s)) 395 (link->latency.l0s > acceptable->l0s))
402 state &= ~PCIE_LINK_STATE_L0S; 396 state &= ~PCIE_LINK_STATE_L0S;
403
404 if ((state & PCIE_LINK_STATE_L1) && 397 if ((state & PCIE_LINK_STATE_L1) &&
405 (link_state->latency.l1 + l1_latency > acceptable->l1)) 398 (link->latency.l1 + l1_switch_latency > acceptable->l1))
406 state &= ~PCIE_LINK_STATE_L1; 399 state &= ~PCIE_LINK_STATE_L1;
407 400 link = link->parent;
408 if (!parent_dev->bus->self) /* parent_dev is a root port */ 401 /*
409 break; 402 * Every switch on the path to root complex need 1
410 else { 403 * more microsecond for L1. Spec doesn't mention L0s.
411 /* 404 */
412 * parent_dev is the downstream port of a switch, make 405 l1_switch_latency += 1000;
413 * tmp_dev the upstream port of the switch
414 */
415 tmp_dev = parent_dev->bus->self;
416 /*
417 * every switch on the path to root complex need 1 more
418 * microsecond for L1. Spec doesn't mention L0S.
419 */
420 if (state & PCIE_LINK_STATE_L1)
421 l1_latency += 1000;
422 }
423 } 406 }
424 return state; 407 return state;
425} 408}