aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-26 00:01:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-26 00:01:43 -0400
commit5aafdea448fb86412a6f8e46df518c1545d32436 (patch)
treec8e7b57382628873a26b15fbda1f41b527ad1c0b /drivers/pci
parent56a9ccb7ba5ffd5f285e3a9628cb446192c8639c (diff)
parenteca67315e0e0d5fd91264d79c88694006dbc7d31 (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.c6
-rw-r--r--drivers/pci/pcie/aspm.c33
-rw-r--r--drivers/pci/pcie/portdrv_core.c5
3 files changed, 40 insertions, 4 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b714d787bdd..2472e7177b4 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 3188cd96b33..eee09f756ec 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);
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 5130d0d2239..595654a1a6a 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 /*