aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pcie/aspm.c71
1 files changed, 38 insertions, 33 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 419f1f3697c0..fdb3b7da7383 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -41,9 +41,10 @@ struct pcie_link_state {
41 struct list_head link; 41 struct list_head link;
42 42
43 /* ASPM state */ 43 /* ASPM state */
44 unsigned int support_state; 44 u32 aspm_support:2; /* Supported ASPM state */
45 unsigned int enabled_state; 45 u32 aspm_enabled:2; /* Enabled ASPM state */
46 unsigned int bios_aspm_state; 46 u32 aspm_default:2; /* Default ASPM state by BIOS */
47
47 /* upstream component */ 48 /* upstream component */
48 unsigned int l0s_upper_latency; 49 unsigned int l0s_upper_latency;
49 unsigned int l1_upper_latency; 50 unsigned int l1_upper_latency;
@@ -88,9 +89,9 @@ static int policy_to_aspm_state(struct pci_dev *pdev)
88 return 0; 89 return 0;
89 case POLICY_POWERSAVE: 90 case POLICY_POWERSAVE:
90 /* Enable ASPM L0s/L1 */ 91 /* Enable ASPM L0s/L1 */
91 return PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; 92 return PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
92 case POLICY_DEFAULT: 93 case POLICY_DEFAULT:
93 return link_state->bios_aspm_state; 94 return link_state->aspm_default;
94 } 95 }
95 return 0; 96 return 0;
96} 97}
@@ -311,6 +312,7 @@ static void pcie_aspm_get_cap_device(struct pci_dev *pdev, u32 *state,
311 u32 reg32; 312 u32 reg32;
312 unsigned int latency; 313 unsigned int latency;
313 314
315 *l0s = *l1 = *enabled = 0;
314 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 316 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
315 pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32); 317 pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
316 *state = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; 318 *state = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
@@ -333,26 +335,29 @@ static void pcie_aspm_get_cap_device(struct pci_dev *pdev, u32 *state,
333static void pcie_aspm_cap_init(struct pci_dev *pdev) 335static void pcie_aspm_cap_init(struct pci_dev *pdev)
334{ 336{
335 struct pci_dev *child_dev; 337 struct pci_dev *child_dev;
336 u32 state, tmp; 338 u32 support, l0s, l1, enabled;
337 struct pcie_link_state *link_state = pdev->link_state; 339 struct pcie_link_state *link_state = pdev->link_state;
338 340
339 /* upstream component states */ 341 /* upstream component states */
340 pcie_aspm_get_cap_device(pdev, &link_state->support_state, 342 pcie_aspm_get_cap_device(pdev, &support, &l0s, &l1, &enabled);
341 &link_state->l0s_upper_latency, 343 link_state->aspm_support = support;
342 &link_state->l1_upper_latency, 344 link_state->l0s_upper_latency = l0s;
343 &link_state->enabled_state); 345 link_state->l1_upper_latency = l1;
346 link_state->aspm_enabled = enabled;
347
344 /* downstream component states, all functions have the same setting */ 348 /* downstream component states, all functions have the same setting */
345 child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev, 349 child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev,
346 bus_list); 350 bus_list);
347 pcie_aspm_get_cap_device(child_dev, &state, 351 pcie_aspm_get_cap_device(child_dev, &support, &l0s, &l1, &enabled);
348 &link_state->l0s_down_latency, 352 link_state->aspm_support &= support;
349 &link_state->l1_down_latency, 353 link_state->l0s_down_latency = l0s;
350 &tmp); 354 link_state->l1_down_latency = l1;
351 link_state->support_state &= state; 355
352 if (!link_state->support_state) 356 if (!link_state->aspm_support)
353 return; 357 return;
354 link_state->enabled_state &= link_state->support_state; 358
355 link_state->bios_aspm_state = link_state->enabled_state; 359 link_state->aspm_enabled &= link_state->aspm_support;
360 link_state->aspm_default = link_state->aspm_enabled;
356 361
357 /* ENDPOINT states*/ 362 /* ENDPOINT states*/
358 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 363 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
@@ -371,7 +376,7 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
371 latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; 376 latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
372 latency = calc_L0S_latency(latency, 1); 377 latency = calc_L0S_latency(latency, 1);
373 ep_state->l0s_acceptable_latency = latency; 378 ep_state->l0s_acceptable_latency = latency;
374 if (link_state->support_state & PCIE_LINK_STATE_L1) { 379 if (link_state->aspm_support & PCIE_LINK_STATE_L1) {
375 latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9; 380 latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
376 latency = calc_L1_latency(latency, 1); 381 latency = calc_L1_latency(latency, 1);
377 ep_state->l1_acceptable_latency = latency; 382 ep_state->l1_acceptable_latency = latency;
@@ -389,7 +394,7 @@ static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev,
389 394
390 parent_dev = pdev->bus->self; 395 parent_dev = pdev->bus->self;
391 link_state = parent_dev->link_state; 396 link_state = parent_dev->link_state;
392 state &= link_state->support_state; 397 state &= link_state->aspm_support;
393 if (state == 0) 398 if (state == 0)
394 return 0; 399 return 0;
395 ep_state = &link_state->endpoints[PCI_FUNC(pdev->devfn)]; 400 ep_state = &link_state->endpoints[PCI_FUNC(pdev->devfn)];
@@ -519,7 +524,7 @@ static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state)
519 if (!(state & PCIE_LINK_STATE_L1)) 524 if (!(state & PCIE_LINK_STATE_L1))
520 __pcie_aspm_config_one_dev(pdev, state); 525 __pcie_aspm_config_one_dev(pdev, state);
521 526
522 link_state->enabled_state = state; 527 link_state->aspm_enabled = state;
523} 528}
524 529
525static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link) 530static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link)
@@ -550,7 +555,7 @@ static void __pcie_aspm_configure_link_state(struct pci_dev *pdev,
550 /* check root port link too in case it hasn't children */ 555 /* check root port link too in case it hasn't children */
551 state = pcie_aspm_check_state(root_port_link->pdev, state); 556 state = pcie_aspm_check_state(root_port_link->pdev, state);
552 557
553 if (link_state->enabled_state == state) 558 if (link_state->aspm_enabled == state)
554 return; 559 return;
555 560
556 /* 561 /*
@@ -675,10 +680,11 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
675 pcie_aspm_configure_common_clock(pdev); 680 pcie_aspm_configure_common_clock(pdev);
676 pcie_aspm_cap_init(pdev); 681 pcie_aspm_cap_init(pdev);
677 } else { 682 } else {
678 link_state->enabled_state = PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; 683 link_state->aspm_enabled =
679 link_state->bios_aspm_state = 0; 684 (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
685 link_state->aspm_default = 0;
680 /* Set support state to 0, so we will disable ASPM later */ 686 /* Set support state to 0, so we will disable ASPM later */
681 link_state->support_state = 0; 687 link_state->aspm_support = 0;
682 } 688 }
683 689
684 link_state->pdev = pdev; 690 link_state->pdev = pdev;
@@ -690,7 +696,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
690 * initialization will config the whole hierarchy. but we must 696 * initialization will config the whole hierarchy. but we must
691 * make sure BIOS doesn't set unsupported link state 697 * make sure BIOS doesn't set unsupported link state
692 **/ 698 **/
693 state = pcie_aspm_check_state(pdev, link_state->bios_aspm_state); 699 state = pcie_aspm_check_state(pdev, link_state->aspm_default);
694 __pcie_aspm_config_link(pdev, state); 700 __pcie_aspm_config_link(pdev, state);
695 } else 701 } else
696 __pcie_aspm_configure_link_state(pdev, 702 __pcie_aspm_configure_link_state(pdev,
@@ -753,7 +759,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
753 * devices changed PM state, we should recheck if latency meets all 759 * devices changed PM state, we should recheck if latency meets all
754 * functions' requirement 760 * functions' requirement
755 */ 761 */
756 pcie_aspm_configure_link_state(pdev, link_state->enabled_state); 762 pcie_aspm_configure_link_state(pdev, link_state->aspm_enabled);
757} 763}
758 764
759/* 765/*
@@ -776,12 +782,11 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
776 down_read(&pci_bus_sem); 782 down_read(&pci_bus_sem);
777 mutex_lock(&aspm_lock); 783 mutex_lock(&aspm_lock);
778 link_state = parent->link_state; 784 link_state = parent->link_state;
779 link_state->support_state &= 785 link_state->aspm_support &= ~state;
780 ~(state & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1));
781 if (state & PCIE_LINK_STATE_CLKPM) 786 if (state & PCIE_LINK_STATE_CLKPM)
782 link_state->clk_pm_capable = 0; 787 link_state->clk_pm_capable = 0;
783 788
784 __pcie_aspm_configure_link_state(parent, link_state->enabled_state); 789 __pcie_aspm_configure_link_state(parent, link_state->aspm_enabled);
785 if (!link_state->clk_pm_capable && link_state->clk_pm_enabled) 790 if (!link_state->clk_pm_capable && link_state->clk_pm_enabled)
786 pcie_set_clock_pm(parent, 0); 791 pcie_set_clock_pm(parent, 0);
787 mutex_unlock(&aspm_lock); 792 mutex_unlock(&aspm_lock);
@@ -842,7 +847,7 @@ static ssize_t link_state_show(struct device *dev,
842 struct pci_dev *pci_device = to_pci_dev(dev); 847 struct pci_dev *pci_device = to_pci_dev(dev);
843 struct pcie_link_state *link_state = pci_device->link_state; 848 struct pcie_link_state *link_state = pci_device->link_state;
844 849
845 return sprintf(buf, "%d\n", link_state->enabled_state); 850 return sprintf(buf, "%d\n", link_state->aspm_enabled);
846} 851}
847 852
848static ssize_t link_state_store(struct device *dev, 853static ssize_t link_state_store(struct device *dev,
@@ -908,7 +913,7 @@ void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
908 pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) 913 pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
909 return; 914 return;
910 915
911 if (link_state->support_state) 916 if (link_state->aspm_support)
912 sysfs_add_file_to_group(&pdev->dev.kobj, 917 sysfs_add_file_to_group(&pdev->dev.kobj,
913 &dev_attr_link_state.attr, power_group); 918 &dev_attr_link_state.attr, power_group);
914 if (link_state->clk_pm_capable) 919 if (link_state->clk_pm_capable)
@@ -924,7 +929,7 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
924 pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) 929 pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
925 return; 930 return;
926 931
927 if (link_state->support_state) 932 if (link_state->aspm_support)
928 sysfs_remove_file_from_group(&pdev->dev.kobj, 933 sysfs_remove_file_from_group(&pdev->dev.kobj,
929 &dev_attr_link_state.attr, power_group); 934 &dev_attr_link_state.attr, power_group);
930 if (link_state->clk_pm_capable) 935 if (link_state->clk_pm_capable)