diff options
Diffstat (limited to 'drivers/pci/pcie/aspm.c')
-rw-r--r-- | drivers/pci/pcie/aspm.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 694ba565775..0d0d3e63092 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -105,7 +105,7 @@ static int policy_to_clkpm_state(struct pcie_link_state *link) | |||
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | 107 | ||
108 | static void pcie_set_clock_pm(struct pcie_link_state *link, int enable) | 108 | static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) |
109 | { | 109 | { |
110 | int pos; | 110 | int pos; |
111 | u16 reg16; | 111 | u16 reg16; |
@@ -126,6 +126,17 @@ static void pcie_set_clock_pm(struct pcie_link_state *link, int enable) | |||
126 | link->clkpm_enabled = !!enable; | 126 | link->clkpm_enabled = !!enable; |
127 | } | 127 | } |
128 | 128 | ||
129 | static void pcie_set_clkpm(struct pcie_link_state *link, int enable) | ||
130 | { | ||
131 | /* Don't enable Clock PM if the link is not Clock PM capable */ | ||
132 | if (!link->clkpm_capable && enable) | ||
133 | return; | ||
134 | /* Need nothing if the specified equals to current state */ | ||
135 | if (link->clkpm_enabled == enable) | ||
136 | return; | ||
137 | pcie_set_clkpm_nocheck(link, enable); | ||
138 | } | ||
139 | |||
129 | static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) | 140 | static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) |
130 | { | 141 | { |
131 | int pos, capable = 1, enabled = 1; | 142 | int pos, capable = 1, enabled = 1; |
@@ -660,7 +671,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
660 | 671 | ||
661 | /* Setup initial Clock PM state */ | 672 | /* Setup initial Clock PM state */ |
662 | state = (link->clkpm_capable) ? policy_to_clkpm_state(link) : 0; | 673 | state = (link->clkpm_capable) ? policy_to_clkpm_state(link) : 0; |
663 | pcie_set_clock_pm(link, state); | 674 | pcie_set_clkpm(link, state); |
664 | unlock: | 675 | unlock: |
665 | mutex_unlock(&aspm_lock); | 676 | mutex_unlock(&aspm_lock); |
666 | out: | 677 | out: |
@@ -738,12 +749,11 @@ void pci_disable_link_state(struct pci_dev *pdev, int state) | |||
738 | mutex_lock(&aspm_lock); | 749 | mutex_lock(&aspm_lock); |
739 | link_state = parent->link_state; | 750 | link_state = parent->link_state; |
740 | link_state->aspm_support &= ~state; | 751 | link_state->aspm_support &= ~state; |
741 | if (state & PCIE_LINK_STATE_CLKPM) | ||
742 | link_state->clkpm_capable = 0; | ||
743 | |||
744 | __pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled); | 752 | __pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled); |
745 | if (!link_state->clkpm_capable && link_state->clkpm_enabled) | 753 | if (state & PCIE_LINK_STATE_CLKPM) { |
746 | pcie_set_clock_pm(link_state, 0); | 754 | link_state->clkpm_capable = 0; |
755 | pcie_set_clkpm(link_state, 0); | ||
756 | } | ||
747 | mutex_unlock(&aspm_lock); | 757 | mutex_unlock(&aspm_lock); |
748 | up_read(&pci_bus_sem); | 758 | up_read(&pci_bus_sem); |
749 | } | 759 | } |
@@ -768,11 +778,7 @@ static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) | |||
768 | list_for_each_entry(link_state, &link_list, sibling) { | 778 | list_for_each_entry(link_state, &link_list, sibling) { |
769 | __pcie_aspm_configure_link_state(link_state, | 779 | __pcie_aspm_configure_link_state(link_state, |
770 | policy_to_aspm_state(link_state)); | 780 | policy_to_aspm_state(link_state)); |
771 | if (link_state->clkpm_capable && | 781 | pcie_set_clkpm(link_state, policy_to_clkpm_state(link_state)); |
772 | link_state->clkpm_enabled != policy_to_clkpm_state(link_state)) | ||
773 | pcie_set_clock_pm(link_state, | ||
774 | policy_to_clkpm_state(link_state)); | ||
775 | |||
776 | } | 782 | } |
777 | mutex_unlock(&aspm_lock); | 783 | mutex_unlock(&aspm_lock); |
778 | up_read(&pci_bus_sem); | 784 | up_read(&pci_bus_sem); |
@@ -839,7 +845,7 @@ static ssize_t clk_ctl_store(struct device *dev, | |||
839 | const char *buf, | 845 | const char *buf, |
840 | size_t n) | 846 | size_t n) |
841 | { | 847 | { |
842 | struct pci_dev *pci_device = to_pci_dev(dev); | 848 | struct pci_dev *pdev = to_pci_dev(dev); |
843 | int state; | 849 | int state; |
844 | 850 | ||
845 | if (n < 1) | 851 | if (n < 1) |
@@ -848,7 +854,7 @@ static ssize_t clk_ctl_store(struct device *dev, | |||
848 | 854 | ||
849 | down_read(&pci_bus_sem); | 855 | down_read(&pci_bus_sem); |
850 | mutex_lock(&aspm_lock); | 856 | mutex_lock(&aspm_lock); |
851 | pcie_set_clock_pm(pci_device->link_state, !!state); | 857 | pcie_set_clkpm_nocheck(pdev->link_state, !!state); |
852 | mutex_unlock(&aspm_lock); | 858 | mutex_unlock(&aspm_lock); |
853 | up_read(&pci_bus_sem); | 859 | up_read(&pci_bus_sem); |
854 | 860 | ||