diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-26 00:01:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-26 00:01:43 -0400 |
commit | 5aafdea448fb86412a6f8e46df518c1545d32436 (patch) | |
tree | c8e7b57382628873a26b15fbda1f41b527ad1c0b /drivers/pci | |
parent | 56a9ccb7ba5ffd5f285e3a9628cb446192c8639c (diff) | |
parent | eca67315e0e0d5fd91264d79c88694006dbc7d31 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
PCI: Disable ASPM when _OSC control is not granted for PCIe services
PCI: Changing ASPM policy, via /sys, to POWERSAVE could cause NMIs
PCI: PCIe links may not get configured for ASPM under POWERSAVE mode
PCI/ACPI: Report ASPM support to BIOS if not disabled from command line
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci.c | 6 | ||||
-rw-r--r-- | drivers/pci/pcie/aspm.c | 33 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_core.c | 5 |
3 files changed, 40 insertions, 4 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b714d787bddd..2472e7177b4b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -740,6 +740,12 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
740 | 740 | ||
741 | if (!__pci_complete_power_transition(dev, state)) | 741 | if (!__pci_complete_power_transition(dev, state)) |
742 | error = 0; | 742 | error = 0; |
743 | /* | ||
744 | * When aspm_policy is "powersave" this call ensures | ||
745 | * that ASPM is configured. | ||
746 | */ | ||
747 | if (!error && dev->bus->self) | ||
748 | pcie_aspm_powersave_config_link(dev->bus->self); | ||
743 | 749 | ||
744 | return error; | 750 | return error; |
745 | } | 751 | } |
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 | ||
71 | static int aspm_disabled, aspm_force, aspm_clear_state; | 71 | static int aspm_disabled, aspm_force, aspm_clear_state; |
72 | static bool aspm_support_enabled = true; | ||
72 | static DEFINE_MUTEX(aspm_lock); | 73 | static DEFINE_MUTEX(aspm_lock); |
73 | static LIST_HEAD(link_list); | 74 | static 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 | ||
711 | void 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 | } |
931 | EXPORT_SYMBOL(pcie_aspm_enabled); | 959 | EXPORT_SYMBOL(pcie_aspm_enabled); |
932 | 960 | ||
961 | bool pcie_aspm_support_enabled(void) | ||
962 | { | ||
963 | return aspm_support_enabled; | ||
964 | } | ||
965 | EXPORT_SYMBOL(pcie_aspm_support_enabled); | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 5130d0d22390..595654a1a6a6 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/pcieport_if.h> | 16 | #include <linux/pcieport_if.h> |
17 | #include <linux/aer.h> | 17 | #include <linux/aer.h> |
18 | #include <linux/pci-aspm.h> | ||
19 | 18 | ||
20 | #include "../pci.h" | 19 | #include "../pci.h" |
21 | #include "portdrv.h" | 20 | #include "portdrv.h" |
@@ -356,10 +355,8 @@ int pcie_port_device_register(struct pci_dev *dev) | |||
356 | 355 | ||
357 | /* Get and check PCI Express port services */ | 356 | /* Get and check PCI Express port services */ |
358 | capabilities = get_port_device_capability(dev); | 357 | capabilities = get_port_device_capability(dev); |
359 | if (!capabilities) { | 358 | if (!capabilities) |
360 | pcie_no_aspm(); | ||
361 | return 0; | 359 | return 0; |
362 | } | ||
363 | 360 | ||
364 | pci_set_master(dev); | 361 | pci_set_master(dev); |
365 | /* | 362 | /* |