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.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 3188cd96b338..eee09f756ec9 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -69,6 +69,7 @@ struct pcie_link_state {
69}; 69};
70 70
71static int aspm_disabled, aspm_force, aspm_clear_state; 71static int aspm_disabled, aspm_force, aspm_clear_state;
72static bool aspm_support_enabled = true;
72static DEFINE_MUTEX(aspm_lock); 73static DEFINE_MUTEX(aspm_lock);
73static LIST_HEAD(link_list); 74static LIST_HEAD(link_list);
74 75
@@ -707,6 +708,28 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
707 up_read(&pci_bus_sem); 708 up_read(&pci_bus_sem);
708} 709}
709 710
711void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
712{
713 struct pcie_link_state *link = pdev->link_state;
714
715 if (aspm_disabled || !pci_is_pcie(pdev) || !link)
716 return;
717
718 if (aspm_policy != POLICY_POWERSAVE)
719 return;
720
721 if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
722 (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
723 return;
724
725 down_read(&pci_bus_sem);
726 mutex_lock(&aspm_lock);
727 pcie_config_aspm_path(link);
728 pcie_set_clkpm(link, policy_to_clkpm_state(link));
729 mutex_unlock(&aspm_lock);
730 up_read(&pci_bus_sem);
731}
732
710/* 733/*
711 * pci_disable_link_state - disable pci device's link state, so the link will 734 * pci_disable_link_state - disable pci device's link state, so the link will
712 * never enter specific states 735 * never enter specific states
@@ -747,6 +770,8 @@ static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
747 int i; 770 int i;
748 struct pcie_link_state *link; 771 struct pcie_link_state *link;
749 772
773 if (aspm_disabled)
774 return -EPERM;
750 for (i = 0; i < ARRAY_SIZE(policy_str); i++) 775 for (i = 0; i < ARRAY_SIZE(policy_str); i++)
751 if (!strncmp(val, policy_str[i], strlen(policy_str[i]))) 776 if (!strncmp(val, policy_str[i], strlen(policy_str[i])))
752 break; 777 break;
@@ -801,6 +826,8 @@ static ssize_t link_state_store(struct device *dev,
801 struct pcie_link_state *link, *root = pdev->link_state->root; 826 struct pcie_link_state *link, *root = pdev->link_state->root;
802 u32 val = buf[0] - '0', state = 0; 827 u32 val = buf[0] - '0', state = 0;
803 828
829 if (aspm_disabled)
830 return -EPERM;
804 if (n < 1 || val > 3) 831 if (n < 1 || val > 3)
805 return -EINVAL; 832 return -EINVAL;
806 833
@@ -896,6 +923,7 @@ static int __init pcie_aspm_disable(char *str)
896{ 923{
897 if (!strcmp(str, "off")) { 924 if (!strcmp(str, "off")) {
898 aspm_disabled = 1; 925 aspm_disabled = 1;
926 aspm_support_enabled = false;
899 printk(KERN_INFO "PCIe ASPM is disabled\n"); 927 printk(KERN_INFO "PCIe ASPM is disabled\n");
900 } else if (!strcmp(str, "force")) { 928 } else if (!strcmp(str, "force")) {
901 aspm_force = 1; 929 aspm_force = 1;
@@ -930,3 +958,8 @@ int pcie_aspm_enabled(void)
930} 958}
931EXPORT_SYMBOL(pcie_aspm_enabled); 959EXPORT_SYMBOL(pcie_aspm_enabled);
932 960
961bool pcie_aspm_support_enabled(void)
962{
963 return aspm_support_enabled;
964}
965EXPORT_SYMBOL(pcie_aspm_support_enabled);