diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2009-08-18 21:59:52 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-09-09 16:29:46 -0400 |
commit | f1c0ca29ae72bc0c10282eada66c8a792ee98482 (patch) | |
tree | 4629fc8c5f0a8537376636b997f6a62dddc63ac2 /drivers/pci/pcie/aspm.c | |
parent | fc87e919c0ce8e213edf2ffca17f384f059873d3 (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.c | 41 |
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) | |||
719 | void pci_disable_link_state(struct pci_dev *pdev, int state) | 726 | void 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); |