diff options
| -rw-r--r-- | drivers/pci/pcie/aspm.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 04b6a3098505..3d27c97e0486 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
| @@ -33,6 +33,7 @@ struct aspm_latency { | |||
| 33 | 33 | ||
| 34 | struct pcie_link_state { | 34 | struct pcie_link_state { |
| 35 | struct pci_dev *pdev; /* Upstream component of the Link */ | 35 | struct pci_dev *pdev; /* Upstream component of the Link */ |
| 36 | struct pcie_link_state *root; /* pointer to the root port link */ | ||
| 36 | struct pcie_link_state *parent; /* pointer to the parent Link state */ | 37 | struct pcie_link_state *parent; /* pointer to the parent Link state */ |
| 37 | struct list_head sibling; /* node in link_list */ | 38 | struct list_head sibling; /* node in link_list */ |
| 38 | struct list_head children; /* list of child link states */ | 39 | struct list_head children; /* list of child link states */ |
| @@ -486,26 +487,17 @@ static void __pcie_aspm_config_link(struct pcie_link_state *link, u32 state) | |||
| 486 | link->aspm_enabled = state; | 487 | link->aspm_enabled = state; |
| 487 | } | 488 | } |
| 488 | 489 | ||
| 489 | static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link) | ||
| 490 | { | ||
| 491 | struct pcie_link_state *root_port_link = link; | ||
| 492 | while (root_port_link->parent) | ||
| 493 | root_port_link = root_port_link->parent; | ||
| 494 | return root_port_link; | ||
| 495 | } | ||
| 496 | |||
| 497 | /* Check the whole hierarchy, and configure each link in the hierarchy */ | 490 | /* Check the whole hierarchy, and configure each link in the hierarchy */ |
| 498 | static void __pcie_aspm_configure_link_state(struct pcie_link_state *link, | 491 | static void __pcie_aspm_configure_link_state(struct pcie_link_state *link, |
| 499 | u32 state) | 492 | u32 state) |
| 500 | { | 493 | { |
| 501 | struct pcie_link_state *leaf, *root = get_root_port_link(link); | 494 | struct pcie_link_state *leaf, *root = link->root; |
| 502 | 495 | ||
| 503 | state &= (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); | 496 | state &= (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); |
| 504 | 497 | ||
| 505 | /* Check all links who have specific root port link */ | 498 | /* Check all links who have specific root port link */ |
| 506 | list_for_each_entry(leaf, &link_list, sibling) { | 499 | list_for_each_entry(leaf, &link_list, sibling) { |
| 507 | if (!list_empty(&leaf->children) || | 500 | if (!list_empty(&leaf->children) || (leaf->root != root)) |
| 508 | get_root_port_link(leaf) != root) | ||
| 509 | continue; | 501 | continue; |
| 510 | state = pcie_aspm_check_state(leaf, state); | 502 | state = pcie_aspm_check_state(leaf, state); |
| 511 | } | 503 | } |
| @@ -519,12 +511,12 @@ static void __pcie_aspm_configure_link_state(struct pcie_link_state *link, | |||
| 519 | **/ | 511 | **/ |
| 520 | if (state & PCIE_LINK_STATE_L1) { | 512 | if (state & PCIE_LINK_STATE_L1) { |
| 521 | list_for_each_entry(leaf, &link_list, sibling) { | 513 | list_for_each_entry(leaf, &link_list, sibling) { |
| 522 | if (get_root_port_link(leaf) == root) | 514 | if (leaf->root == root) |
| 523 | __pcie_aspm_config_link(leaf, state); | 515 | __pcie_aspm_config_link(leaf, state); |
| 524 | } | 516 | } |
| 525 | } else { | 517 | } else { |
| 526 | list_for_each_entry_reverse(leaf, &link_list, sibling) { | 518 | list_for_each_entry_reverse(leaf, &link_list, sibling) { |
| 527 | if (get_root_port_link(leaf) == root) | 519 | if (leaf->root == root) |
| 528 | __pcie_aspm_config_link(leaf, state); | 520 | __pcie_aspm_config_link(leaf, state); |
| 529 | } | 521 | } |
| 530 | } | 522 | } |
| @@ -600,6 +592,12 @@ static struct pcie_link_state *pcie_aspm_setup_link_state(struct pci_dev *pdev) | |||
| 600 | link->parent = parent; | 592 | link->parent = parent; |
| 601 | list_add(&link->link, &parent->children); | 593 | list_add(&link->link, &parent->children); |
| 602 | } | 594 | } |
| 595 | /* Setup a pointer to the root port link */ | ||
| 596 | if (!link->parent) | ||
| 597 | link->root = link; | ||
| 598 | else | ||
| 599 | link->root = link->parent->root; | ||
| 600 | |||
| 603 | list_add(&link->sibling, &link_list); | 601 | list_add(&link->sibling, &link_list); |
| 604 | 602 | ||
| 605 | pdev->link_state = link; | 603 | pdev->link_state = link; |
