aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/aspm.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 71222814c1ec..3188cd96b338 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -68,7 +68,7 @@ struct pcie_link_state {
68 struct aspm_latency acceptable[8]; 68 struct aspm_latency acceptable[8];
69}; 69};
70 70
71static int aspm_disabled, aspm_force; 71static int aspm_disabled, aspm_force, aspm_clear_state;
72static DEFINE_MUTEX(aspm_lock); 72static DEFINE_MUTEX(aspm_lock);
73static LIST_HEAD(link_list); 73static LIST_HEAD(link_list);
74 74
@@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
139{ 139{
140 /* Don't enable Clock PM if the link is not Clock PM capable */ 140 /* Don't enable Clock PM if the link is not Clock PM capable */
141 if (!link->clkpm_capable && enable) 141 if (!link->clkpm_capable && enable)
142 return; 142 enable = 0;
143 /* Need nothing if the specified equals to current state */ 143 /* Need nothing if the specified equals to current state */
144 if (link->clkpm_enabled == enable) 144 if (link->clkpm_enabled == enable)
145 return; 145 return;
@@ -498,6 +498,10 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
498 struct pci_dev *child; 498 struct pci_dev *child;
499 int pos; 499 int pos;
500 u32 reg32; 500 u32 reg32;
501
502 if (aspm_clear_state)
503 return -EINVAL;
504
501 /* 505 /*
502 * Some functions in a slot might not all be PCIe functions, 506 * Some functions in a slot might not all be PCIe functions,
503 * very strange. Disable ASPM for the whole slot 507 * very strange. Disable ASPM for the whole slot
@@ -563,12 +567,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
563 struct pcie_link_state *link; 567 struct pcie_link_state *link;
564 int blacklist = !!pcie_aspm_sanity_check(pdev); 568 int blacklist = !!pcie_aspm_sanity_check(pdev);
565 569
566 if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state) 570 if (!pci_is_pcie(pdev) || pdev->link_state)
567 return; 571 return;
568 if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && 572 if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
569 pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) 573 pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
570 return; 574 return;
571 575
576 if (aspm_disabled && !aspm_clear_state)
577 return;
578
572 /* VIA has a strange chipset, root port is under a bridge */ 579 /* VIA has a strange chipset, root port is under a bridge */
573 if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && 580 if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
574 pdev->bus->self) 581 pdev->bus->self)
@@ -641,7 +648,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
641 struct pci_dev *parent = pdev->bus->self; 648 struct pci_dev *parent = pdev->bus->self;
642 struct pcie_link_state *link, *root, *parent_link; 649 struct pcie_link_state *link, *root, *parent_link;
643 650
644 if (aspm_disabled || !pci_is_pcie(pdev) || 651 if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
645 !parent || !parent->link_state) 652 !parent || !parent->link_state)
646 return; 653 return;
647 if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && 654 if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
@@ -899,6 +906,12 @@ static int __init pcie_aspm_disable(char *str)
899 906
900__setup("pcie_aspm=", pcie_aspm_disable); 907__setup("pcie_aspm=", pcie_aspm_disable);
901 908
909void pcie_clear_aspm(void)
910{
911 if (!aspm_force)
912 aspm_clear_state = 1;
913}
914
902void pcie_no_aspm(void) 915void pcie_no_aspm(void)
903{ 916{
904 if (!aspm_force) 917 if (!aspm_force)