aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie/aspm.c')
-rw-r--r--drivers/pci/pcie/aspm.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 317e3558a35e..c6a012b5ba39 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -518,25 +518,32 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
518 link = kzalloc(sizeof(*link), GFP_KERNEL); 518 link = kzalloc(sizeof(*link), GFP_KERNEL);
519 if (!link) 519 if (!link)
520 return NULL; 520 return NULL;
521
521 INIT_LIST_HEAD(&link->sibling); 522 INIT_LIST_HEAD(&link->sibling);
522 INIT_LIST_HEAD(&link->children); 523 INIT_LIST_HEAD(&link->children);
523 INIT_LIST_HEAD(&link->link); 524 INIT_LIST_HEAD(&link->link);
524 link->pdev = pdev; 525 link->pdev = pdev;
525 if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) { 526
527 /*
528 * Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe
529 * hierarchies.
530 */
531 if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
532 pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE) {
533 link->root = link;
534 } else {
526 struct pcie_link_state *parent; 535 struct pcie_link_state *parent;
536
527 parent = pdev->bus->parent->self->link_state; 537 parent = pdev->bus->parent->self->link_state;
528 if (!parent) { 538 if (!parent) {
529 kfree(link); 539 kfree(link);
530 return NULL; 540 return NULL;
531 } 541 }
542
532 link->parent = parent; 543 link->parent = parent;
544 link->root = link->parent->root;
533 list_add(&link->link, &parent->children); 545 list_add(&link->link, &parent->children);
534 } 546 }
535 /* Setup a pointer to the root port link */
536 if (!link->parent)
537 link->root = link;
538 else
539 link->root = link->parent->root;
540 547
541 list_add(&link->sibling, &link_list); 548 list_add(&link->sibling, &link_list);
542 pdev->link_state = link; 549 pdev->link_state = link;