aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie/aspm.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2009-08-18 21:59:52 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-09-09 16:29:46 -0400
commitf1c0ca29ae72bc0c10282eada66c8a792ee98482 (patch)
tree4629fc8c5f0a8537376636b997f6a62dddc63ac2 /drivers/pci/pcie/aspm.c
parentfc87e919c0ce8e213edf2ffca17f384f059873d3 (diff)
PCI ASPM: introduce disable flag
Introduce 'aspm_disable' flag to manage disabled ASPM state more robust way. Acked-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pcie/aspm.c')
-rw-r--r--drivers/pci/pcie/aspm.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 0800c5146826..8f7884a8bc2e 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -43,6 +43,7 @@ struct pcie_link_state {
43 u32 aspm_support:2; /* Supported ASPM state */ 43 u32 aspm_support:2; /* Supported ASPM state */
44 u32 aspm_enabled:2; /* Enabled ASPM state */ 44 u32 aspm_enabled:2; /* Enabled ASPM state */
45 u32 aspm_default:2; /* Default ASPM state by BIOS */ 45 u32 aspm_default:2; /* Default ASPM state by BIOS */
46 u32 aspm_disable:2; /* Disabled ASPM state */
46 47
47 /* Clock PM state */ 48 /* Clock PM state */
48 u32 clkpm_capable:1; /* Clock PM capable? */ 49 u32 clkpm_capable:1; /* Clock PM capable? */
@@ -322,10 +323,9 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
322 struct pci_bus *linkbus = parent->subordinate; 323 struct pci_bus *linkbus = parent->subordinate;
323 324
324 if (blacklist) { 325 if (blacklist) {
325 /* Set support state to 0, so we will disable ASPM later */ 326 /* Set enabled/disable so that we will disable ASPM later */
326 link->aspm_support = 0;
327 link->aspm_default = 0;
328 link->aspm_enabled = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1; 327 link->aspm_enabled = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
328 link->aspm_disable = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
329 return; 329 return;
330 } 330 }
331 331
@@ -348,6 +348,17 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
348 348
349 /* Save default state */ 349 /* Save default state */
350 link->aspm_default = link->aspm_enabled; 350 link->aspm_default = link->aspm_enabled;
351 /*
352 * If the downstream component has pci bridge function, don't
353 * do ASPM for now.
354 */
355 list_for_each_entry(child, &linkbus->devices, bus_list) {
356 if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
357 link->aspm_disable =
358 PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
359 break;
360 }
361 }
351 362
352 if (!link->aspm_support) 363 if (!link->aspm_support)
353 return; 364 return;
@@ -458,14 +469,10 @@ static void __pcie_aspm_config_link(struct pcie_link_state *link, u32 state)
458 struct pci_dev *child, *parent = link->pdev; 469 struct pci_dev *child, *parent = link->pdev;
459 struct pci_bus *linkbus = parent->subordinate; 470 struct pci_bus *linkbus = parent->subordinate;
460 471
461 /* 472 state &= ~link->aspm_disable;
462 * If the downstream component has pci bridge function, don't 473 /* Nothing to do if the link is already in the requested state */
463 * do ASPM now. 474 if (link->aspm_enabled == state)
464 */ 475 return;
465 list_for_each_entry(child, &linkbus->devices, bus_list) {
466 if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
467 return;
468 }
469 /* 476 /*
470 * Spec 2.0 suggests all functions should be configured the 477 * Spec 2.0 suggests all functions should be configured the
471 * same setting for ASPM. Enabling ASPM L1 should be done in 478 * same setting for ASPM. Enabling ASPM L1 should be done in
@@ -719,7 +726,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
719void pci_disable_link_state(struct pci_dev *pdev, int state) 726void pci_disable_link_state(struct pci_dev *pdev, int state)
720{ 727{
721 struct pci_dev *parent = pdev->bus->self; 728 struct pci_dev *parent = pdev->bus->self;
722 struct pcie_link_state *link_state; 729 struct pcie_link_state *link;
723 730
724 if (aspm_disabled || !pdev->is_pcie) 731 if (aspm_disabled || !pdev->is_pcie)
725 return; 732 return;
@@ -731,12 +738,12 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
731 738
732 down_read(&pci_bus_sem); 739 down_read(&pci_bus_sem);
733 mutex_lock(&aspm_lock); 740 mutex_lock(&aspm_lock);
734 link_state = parent->link_state; 741 link = parent->link_state;
735 link_state->aspm_support &= ~state; 742 link->aspm_disable |= state;
736 __pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled); 743 __pcie_aspm_configure_link_state(link, link->aspm_enabled);
737 if (state & PCIE_LINK_STATE_CLKPM) { 744 if (state & PCIE_LINK_STATE_CLKPM) {
738 link_state->clkpm_capable = 0; 745 link->clkpm_capable = 0;
739 pcie_set_clkpm(link_state, 0); 746 pcie_set_clkpm(link, 0);
740 } 747 }
741 mutex_unlock(&aspm_lock); 748 mutex_unlock(&aspm_lock);
742 up_read(&pci_bus_sem); 749 up_read(&pci_bus_sem);