aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2009-05-12 23:17:44 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-06-18 16:57:26 -0400
commit5aa63583cbec27482c6f1d761a0509f59b7969a8 (patch)
treea989edcd7e85199aee66eff2f087dfd6d94176bb
parent5cde89d80172a393e49077d2450545b97ac8d972 (diff)
PCI ASPM: cleanup change input argument of aspm functions
In the current ASPM implementation, there are many functions that take a pointer to struct pci_dev corresponding to the upstream component of the link as a parameter. But, since those functions handle PCI express link state, a pointer to struct pcie_link_state is more suitable than a pointer to struct pci_dev. Changing a parameter to a pointer to struct pcie_link_state makes ASPM code much simpler and easier to read. This patch also contains some minor cleanups. This patch doesn't have any functional change. 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>
-rw-r--r--drivers/pci/pcie/aspm.c372
1 files changed, 173 insertions, 199 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index a1ae9b6f3995..9eaaf95f65a2 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -75,10 +75,8 @@ static const char *policy_str[] = {
75 75
76#define LINK_RETRAIN_TIMEOUT HZ 76#define LINK_RETRAIN_TIMEOUT HZ
77 77
78static int policy_to_aspm_state(struct pci_dev *pdev) 78static int policy_to_aspm_state(struct pcie_link_state *link)
79{ 79{
80 struct pcie_link_state *link_state = pdev->link_state;
81
82 switch (aspm_policy) { 80 switch (aspm_policy) {
83 case POLICY_PERFORMANCE: 81 case POLICY_PERFORMANCE:
84 /* Disable ASPM and Clock PM */ 82 /* Disable ASPM and Clock PM */
@@ -87,15 +85,13 @@ static int policy_to_aspm_state(struct pci_dev *pdev)
87 /* Enable ASPM L0s/L1 */ 85 /* Enable ASPM L0s/L1 */
88 return PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1; 86 return PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
89 case POLICY_DEFAULT: 87 case POLICY_DEFAULT:
90 return link_state->aspm_default; 88 return link->aspm_default;
91 } 89 }
92 return 0; 90 return 0;
93} 91}
94 92
95static int policy_to_clkpm_state(struct pci_dev *pdev) 93static int policy_to_clkpm_state(struct pcie_link_state *link)
96{ 94{
97 struct pcie_link_state *link_state = pdev->link_state;
98
99 switch (aspm_policy) { 95 switch (aspm_policy) {
100 case POLICY_PERFORMANCE: 96 case POLICY_PERFORMANCE:
101 /* Disable ASPM and Clock PM */ 97 /* Disable ASPM and Clock PM */
@@ -104,73 +100,73 @@ static int policy_to_clkpm_state(struct pci_dev *pdev)
104 /* Disable Clock PM */ 100 /* Disable Clock PM */
105 return 1; 101 return 1;
106 case POLICY_DEFAULT: 102 case POLICY_DEFAULT:
107 return link_state->clkpm_default; 103 return link->clkpm_default;
108 } 104 }
109 return 0; 105 return 0;
110} 106}
111 107
112static void pcie_set_clock_pm(struct pci_dev *pdev, int enable) 108static void pcie_set_clock_pm(struct pcie_link_state *link, int enable)
113{ 109{
114 struct pci_dev *child_dev;
115 int pos; 110 int pos;
116 u16 reg16; 111 u16 reg16;
117 struct pcie_link_state *link_state = pdev->link_state; 112 struct pci_dev *child;
113 struct pci_bus *linkbus = link->pdev->subordinate;
118 114
119 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 115 list_for_each_entry(child, &linkbus->devices, bus_list) {
120 pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); 116 pos = pci_find_capability(child, PCI_CAP_ID_EXP);
121 if (!pos) 117 if (!pos)
122 return; 118 return;
123 pci_read_config_word(child_dev, pos + PCI_EXP_LNKCTL, &reg16); 119 pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
124 if (enable) 120 if (enable)
125 reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN; 121 reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN;
126 else 122 else
127 reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN; 123 reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
128 pci_write_config_word(child_dev, pos + PCI_EXP_LNKCTL, reg16); 124 pci_write_config_word(child, pos + PCI_EXP_LNKCTL, reg16);
129 } 125 }
130 link_state->clkpm_enabled = !!enable; 126 link->clkpm_enabled = !!enable;
131} 127}
132 128
133static void pcie_check_clock_pm(struct pci_dev *pdev, int blacklist) 129static void pcie_check_clock_pm(struct pcie_link_state *link, int blacklist)
134{ 130{
135 int pos; 131 int pos, capable = 1, enabled = 1;
136 u32 reg32; 132 u32 reg32;
137 u16 reg16; 133 u16 reg16;
138 int capable = 1, enabled = 1; 134 struct pci_dev *child;
139 struct pci_dev *child_dev; 135 struct pci_bus *linkbus = link->pdev->subordinate;
140 struct pcie_link_state *link_state = pdev->link_state;
141 136
142 /* All functions should have the same cap and state, take the worst */ 137 /* All functions should have the same cap and state, take the worst */
143 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 138 list_for_each_entry(child, &linkbus->devices, bus_list) {
144 pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); 139 pos = pci_find_capability(child, PCI_CAP_ID_EXP);
145 if (!pos) 140 if (!pos)
146 return; 141 return;
147 pci_read_config_dword(child_dev, pos + PCI_EXP_LNKCAP, &reg32); 142 pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, &reg32);
148 if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) { 143 if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) {
149 capable = 0; 144 capable = 0;
150 enabled = 0; 145 enabled = 0;
151 break; 146 break;
152 } 147 }
153 pci_read_config_word(child_dev, pos + PCI_EXP_LNKCTL, &reg16); 148 pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
154 if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN)) 149 if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN))
155 enabled = 0; 150 enabled = 0;
156 } 151 }
157 link_state->clkpm_enabled = enabled; 152 link->clkpm_enabled = enabled;
158 link_state->clkpm_default = enabled; 153 link->clkpm_default = enabled;
159 if (!blacklist) { 154 if (!blacklist) {
160 link_state->clkpm_capable = capable; 155 link->clkpm_capable = capable;
161 pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); 156 pcie_set_clock_pm(link, policy_to_clkpm_state(link));
162 } else { 157 } else {
163 link_state->clkpm_capable = 0; 158 link->clkpm_capable = 0;
164 pcie_set_clock_pm(pdev, 0); 159 pcie_set_clock_pm(link, 0);
165 } 160 }
166} 161}
167 162
168static bool pcie_aspm_downstream_has_switch(struct pci_dev *pdev) 163static bool pcie_aspm_downstream_has_switch(struct pcie_link_state *link)
169{ 164{
170 struct pci_dev *child_dev; 165 struct pci_dev *child;
166 struct pci_bus *linkbus = link->pdev->subordinate;
171 167
172 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 168 list_for_each_entry(child, &linkbus->devices, bus_list) {
173 if (child_dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) 169 if (child->pcie_type == PCI_EXP_TYPE_UPSTREAM)
174 return true; 170 return true;
175 } 171 }
176 return false; 172 return false;
@@ -181,89 +177,79 @@ static bool pcie_aspm_downstream_has_switch(struct pci_dev *pdev)
181 * could use common clock. If they are, configure them to use the 177 * could use common clock. If they are, configure them to use the
182 * common clock. That will reduce the ASPM state exit latency. 178 * common clock. That will reduce the ASPM state exit latency.
183 */ 179 */
184static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) 180static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
185{ 181{
186 int pos, child_pos, i = 0; 182 int ppos, cpos, same_clock = 1;
187 u16 reg16 = 0; 183 u16 reg16, parent_reg, child_reg[8];
188 struct pci_dev *child_dev;
189 int same_clock = 1;
190 unsigned long start_jiffies; 184 unsigned long start_jiffies;
191 u16 child_regs[8], parent_reg; 185 struct pci_dev *child, *parent = link->pdev;
186 struct pci_bus *linkbus = parent->subordinate;
192 /* 187 /*
193 * all functions of a slot should have the same Slot Clock 188 * All functions of a slot should have the same Slot Clock
194 * Configuration, so just check one function 189 * Configuration, so just check one function
195 * */ 190 */
196 child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev, 191 child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
197 bus_list); 192 BUG_ON(!child->is_pcie);
198 BUG_ON(!child_dev->is_pcie);
199 193
200 /* Check downstream component if bit Slot Clock Configuration is 1 */ 194 /* Check downstream component if bit Slot Clock Configuration is 1 */
201 child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); 195 cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
202 pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKSTA, &reg16); 196 pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, &reg16);
203 if (!(reg16 & PCI_EXP_LNKSTA_SLC)) 197 if (!(reg16 & PCI_EXP_LNKSTA_SLC))
204 same_clock = 0; 198 same_clock = 0;
205 199
206 /* Check upstream component if bit Slot Clock Configuration is 1 */ 200 /* Check upstream component if bit Slot Clock Configuration is 1 */
207 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 201 ppos = pci_find_capability(parent, PCI_CAP_ID_EXP);
208 pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16); 202 pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
209 if (!(reg16 & PCI_EXP_LNKSTA_SLC)) 203 if (!(reg16 & PCI_EXP_LNKSTA_SLC))
210 same_clock = 0; 204 same_clock = 0;
211 205
212 /* Configure downstream component, all functions */ 206 /* Configure downstream component, all functions */
213 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 207 list_for_each_entry(child, &linkbus->devices, bus_list) {
214 child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); 208 cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
215 pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, 209 pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, &reg16);
216 &reg16); 210 child_reg[PCI_FUNC(child->devfn)] = reg16;
217 child_regs[i] = reg16;
218 if (same_clock) 211 if (same_clock)
219 reg16 |= PCI_EXP_LNKCTL_CCC; 212 reg16 |= PCI_EXP_LNKCTL_CCC;
220 else 213 else
221 reg16 &= ~PCI_EXP_LNKCTL_CCC; 214 reg16 &= ~PCI_EXP_LNKCTL_CCC;
222 pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, 215 pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, reg16);
223 reg16);
224 i++;
225 } 216 }
226 217
227 /* Configure upstream component */ 218 /* Configure upstream component */
228 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16); 219 pci_read_config_word(parent, ppos + PCI_EXP_LNKCTL, &reg16);
229 parent_reg = reg16; 220 parent_reg = reg16;
230 if (same_clock) 221 if (same_clock)
231 reg16 |= PCI_EXP_LNKCTL_CCC; 222 reg16 |= PCI_EXP_LNKCTL_CCC;
232 else 223 else
233 reg16 &= ~PCI_EXP_LNKCTL_CCC; 224 reg16 &= ~PCI_EXP_LNKCTL_CCC;
234 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); 225 pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
235 226
236 /* retrain link */ 227 /* Retrain link */
237 reg16 |= PCI_EXP_LNKCTL_RL; 228 reg16 |= PCI_EXP_LNKCTL_RL;
238 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); 229 pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
239 230
240 /* Wait for link training end */ 231 /* Wait for link training end. Break out after waiting for timeout */
241 /* break out after waiting for timeout */
242 start_jiffies = jiffies; 232 start_jiffies = jiffies;
243 for (;;) { 233 for (;;) {
244 pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16); 234 pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
245 if (!(reg16 & PCI_EXP_LNKSTA_LT)) 235 if (!(reg16 & PCI_EXP_LNKSTA_LT))
246 break; 236 break;
247 if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) 237 if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT))
248 break; 238 break;
249 msleep(1); 239 msleep(1);
250 } 240 }
251 /* training failed -> recover */ 241 if (!(reg16 & PCI_EXP_LNKSTA_LT))
252 if (reg16 & PCI_EXP_LNKSTA_LT) { 242 return;
253 dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure" 243
254 " common clock\n"); 244 /* Training failed. Restore common clock configurations */
255 i = 0; 245 dev_printk(KERN_ERR, &parent->dev,
256 list_for_each_entry(child_dev, &pdev->subordinate->devices, 246 "ASPM: Could not configure common clock\n");
257 bus_list) { 247 list_for_each_entry(child, &linkbus->devices, bus_list) {
258 child_pos = pci_find_capability(child_dev, 248 cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
259 PCI_CAP_ID_EXP); 249 pci_write_config_word(child, cpos + PCI_EXP_LNKCTL,
260 pci_write_config_word(child_dev, 250 child_reg[PCI_FUNC(child->devfn)]);
261 child_pos + PCI_EXP_LNKCTL,
262 child_regs[i]);
263 i++;
264 }
265 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, parent_reg);
266 } 251 }
252 pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, parent_reg);
267} 253}
268 254
269/* 255/*
@@ -328,51 +314,50 @@ static void pcie_aspm_get_cap_device(struct pci_dev *pdev, u32 *state,
328 *enabled = reg16 & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1); 314 *enabled = reg16 & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1);
329} 315}
330 316
331static void pcie_aspm_cap_init(struct pci_dev *pdev) 317static void pcie_aspm_cap_init(struct pcie_link_state *link)
332{ 318{
333 struct pci_dev *child_dev;
334 u32 support, l0s, l1, enabled; 319 u32 support, l0s, l1, enabled;
335 struct pcie_link_state *link_state = pdev->link_state; 320 struct pci_dev *child, *parent = link->pdev;
321 struct pci_bus *linkbus = parent->subordinate;
336 322
337 /* upstream component states */ 323 /* upstream component states */
338 pcie_aspm_get_cap_device(pdev, &support, &l0s, &l1, &enabled); 324 pcie_aspm_get_cap_device(parent, &support, &l0s, &l1, &enabled);
339 link_state->aspm_support = support; 325 link->aspm_support = support;
340 link_state->latency.l0s = l0s; 326 link->latency.l0s = l0s;
341 link_state->latency.l1 = l1; 327 link->latency.l1 = l1;
342 link_state->aspm_enabled = enabled; 328 link->aspm_enabled = enabled;
343 329
344 /* downstream component states, all functions have the same setting */ 330 /* downstream component states, all functions have the same setting */
345 child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev, 331 child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
346 bus_list); 332 pcie_aspm_get_cap_device(child, &support, &l0s, &l1, &enabled);
347 pcie_aspm_get_cap_device(child_dev, &support, &l0s, &l1, &enabled); 333 link->aspm_support &= support;
348 link_state->aspm_support &= support; 334 link->latency.l0s = max_t(u32, link->latency.l0s, l0s);
349 link_state->latency.l0s = max_t(u32, link_state->latency.l0s, l0s); 335 link->latency.l1 = max_t(u32, link->latency.l1, l1);
350 link_state->latency.l1 = max_t(u32, link_state->latency.l1, l1); 336
351 337 if (!link->aspm_support)
352 if (!link_state->aspm_support)
353 return; 338 return;
354 339
355 link_state->aspm_enabled &= link_state->aspm_support; 340 link->aspm_enabled &= link->aspm_support;
356 link_state->aspm_default = link_state->aspm_enabled; 341 link->aspm_default = link->aspm_enabled;
357 342
358 /* ENDPOINT states*/ 343 /* ENDPOINT states*/
359 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 344 list_for_each_entry(child, &linkbus->devices, bus_list) {
360 int pos; 345 int pos;
361 u32 reg32; 346 u32 reg32;
362 unsigned int latency; 347 unsigned int latency;
363 struct aspm_latency *acceptable = 348 struct aspm_latency *acceptable =
364 &link_state->acceptable[PCI_FUNC(child_dev->devfn)]; 349 &link->acceptable[PCI_FUNC(child->devfn)];
365 350
366 if (child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT && 351 if (child->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
367 child_dev->pcie_type != PCI_EXP_TYPE_LEG_END) 352 child->pcie_type != PCI_EXP_TYPE_LEG_END)
368 continue; 353 continue;
369 354
370 pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); 355 pos = pci_find_capability(child, PCI_CAP_ID_EXP);
371 pci_read_config_dword(child_dev, pos + PCI_EXP_DEVCAP, &reg32); 356 pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
372 latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; 357 latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
373 latency = calc_L0S_latency(latency, 1); 358 latency = calc_L0S_latency(latency, 1);
374 acceptable->l0s = latency; 359 acceptable->l0s = latency;
375 if (link_state->aspm_support & PCIE_LINK_STATE_L1) { 360 if (link->aspm_support & PCIE_LINK_STATE_L1) {
376 latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9; 361 latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
377 latency = calc_L1_latency(latency, 1); 362 latency = calc_L1_latency(latency, 1);
378 acceptable->l1 = latency; 363 acceptable->l1 = latency;
@@ -434,33 +419,33 @@ static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev,
434 return state; 419 return state;
435} 420}
436 421
437static unsigned int pcie_aspm_check_state(struct pci_dev *pdev, 422static u32 pcie_aspm_check_state(struct pcie_link_state *link, u32 state)
438 unsigned int state)
439{ 423{
440 struct pci_dev *child_dev; 424 pci_power_t power_state;
425 struct pci_dev *child;
426 struct pci_bus *linkbus = link->pdev->subordinate;
441 427
442 /* If no child, ignore the link */ 428 /* If no child, ignore the link */
443 if (list_empty(&pdev->subordinate->devices)) 429 if (list_empty(&linkbus->devices))
444 return state; 430 return state;
445 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 431
446 if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { 432 list_for_each_entry(child, &linkbus->devices, bus_list) {
447 /* 433 /*
448 * If downstream component of a link is pci bridge, we 434 * If downstream component of a link is pci bridge, we
449 * disable ASPM for now for the link 435 * disable ASPM for now for the link
450 * */ 436 */
451 state = 0; 437 if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
452 break; 438 return 0;
453 } 439
454 if ((child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT && 440 if ((child->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
455 child_dev->pcie_type != PCI_EXP_TYPE_LEG_END)) 441 child->pcie_type != PCI_EXP_TYPE_LEG_END))
456 continue; 442 continue;
457 /* Device not in D0 doesn't need check latency */ 443 /* Device not in D0 doesn't need check latency */
458 if (child_dev->current_state == PCI_D1 || 444 power_state = child->current_state;
459 child_dev->current_state == PCI_D2 || 445 if (power_state == PCI_D1 || power_state == PCI_D2 ||
460 child_dev->current_state == PCI_D3hot || 446 power_state == PCI_D3hot || power_state == PCI_D3cold)
461 child_dev->current_state == PCI_D3cold)
462 continue; 447 continue;
463 state = __pcie_aspm_check_state_one(child_dev, state); 448 state = __pcie_aspm_check_state_one(child, state);
464 } 449 }
465 return state; 450 return state;
466} 451}
@@ -476,44 +461,38 @@ static void __pcie_aspm_config_one_dev(struct pci_dev *pdev, unsigned int state)
476 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); 461 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
477} 462}
478 463
479static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state) 464static void __pcie_aspm_config_link(struct pcie_link_state *link, u32 state)
480{ 465{
481 struct pci_dev *child_dev; 466 struct pci_dev *child, *parent = link->pdev;
482 int valid = 1; 467 struct pci_bus *linkbus = parent->subordinate;
483 struct pcie_link_state *link_state = pdev->link_state;
484 468
485 /* If no child, disable the link */ 469 /* If no child, disable the link */
486 if (list_empty(&pdev->subordinate->devices)) 470 if (list_empty(&linkbus->devices))
487 state = 0; 471 state = 0;
488 /* 472 /*
489 * if the downstream component has pci bridge function, don't do ASPM 473 * If the downstream component has pci bridge function, don't
490 * now 474 * do ASPM now.
491 */ 475 */
492 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 476 list_for_each_entry(child, &linkbus->devices, bus_list) {
493 if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { 477 if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
494 valid = 0; 478 return;
495 break;
496 }
497 } 479 }
498 if (!valid)
499 return;
500
501 /* 480 /*
502 * spec 2.0 suggests all functions should be configured the same 481 * Spec 2.0 suggests all functions should be configured the
503 * setting for ASPM. Enabling ASPM L1 should be done in upstream 482 * same setting for ASPM. Enabling ASPM L1 should be done in
504 * component first and then downstream, and vice versa for disabling 483 * upstream component first and then downstream, and vice
505 * ASPM L1. Spec doesn't mention L0S. 484 * versa for disabling ASPM L1. Spec doesn't mention L0S.
506 */ 485 */
507 if (state & PCIE_LINK_STATE_L1) 486 if (state & PCIE_LINK_STATE_L1)
508 __pcie_aspm_config_one_dev(pdev, state); 487 __pcie_aspm_config_one_dev(parent, state);
509 488
510 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) 489 list_for_each_entry(child, &linkbus->devices, bus_list)
511 __pcie_aspm_config_one_dev(child_dev, state); 490 __pcie_aspm_config_one_dev(child, state);
512 491
513 if (!(state & PCIE_LINK_STATE_L1)) 492 if (!(state & PCIE_LINK_STATE_L1))
514 __pcie_aspm_config_one_dev(pdev, state); 493 __pcie_aspm_config_one_dev(parent, state);
515 494
516 link_state->aspm_enabled = state; 495 link->aspm_enabled = state;
517} 496}
518 497
519static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link) 498static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link)
@@ -524,42 +503,38 @@ static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link)
524 return root_port_link; 503 return root_port_link;
525} 504}
526 505
527/* check the whole hierarchy, and configure each link in the hierarchy */ 506/* Check the whole hierarchy, and configure each link in the hierarchy */
528static void __pcie_aspm_configure_link_state(struct pci_dev *pdev, 507static void __pcie_aspm_configure_link_state(struct pcie_link_state *link,
529 unsigned int state) 508 u32 state)
530{ 509{
531 struct pcie_link_state *link_state = pdev->link_state; 510 struct pcie_link_state *leaf, *root = get_root_port_link(link);
532 struct pcie_link_state *root_port_link = get_root_port_link(link_state);
533 struct pcie_link_state *leaf;
534 511
535 state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; 512 state &= (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
536 513
537 /* check all links who have specific root port link */ 514 /* Check all links who have specific root port link */
538 list_for_each_entry(leaf, &link_list, sibling) { 515 list_for_each_entry(leaf, &link_list, sibling) {
539 if (!list_empty(&leaf->children) || 516 if (!list_empty(&leaf->children) ||
540 get_root_port_link(leaf) != root_port_link) 517 get_root_port_link(leaf) != root)
541 continue; 518 continue;
542 state = pcie_aspm_check_state(leaf->pdev, state); 519 state = pcie_aspm_check_state(leaf, state);
543 } 520 }
544 /* check root port link too in case it hasn't children */ 521 /* Check root port link too in case it hasn't children */
545 state = pcie_aspm_check_state(root_port_link->pdev, state); 522 state = pcie_aspm_check_state(root, state);
546 523 if (link->aspm_enabled == state)
547 if (link_state->aspm_enabled == state)
548 return; 524 return;
549
550 /* 525 /*
551 * we must change the hierarchy. See comments in 526 * We must change the hierarchy. See comments in
552 * __pcie_aspm_config_link for the order 527 * __pcie_aspm_config_link for the order
553 **/ 528 **/
554 if (state & PCIE_LINK_STATE_L1) { 529 if (state & PCIE_LINK_STATE_L1) {
555 list_for_each_entry(leaf, &link_list, sibling) { 530 list_for_each_entry(leaf, &link_list, sibling) {
556 if (get_root_port_link(leaf) == root_port_link) 531 if (get_root_port_link(leaf) == root)
557 __pcie_aspm_config_link(leaf->pdev, state); 532 __pcie_aspm_config_link(leaf, state);
558 } 533 }
559 } else { 534 } else {
560 list_for_each_entry_reverse(leaf, &link_list, sibling) { 535 list_for_each_entry_reverse(leaf, &link_list, sibling) {
561 if (get_root_port_link(leaf) == root_port_link) 536 if (get_root_port_link(leaf) == root)
562 __pcie_aspm_config_link(leaf->pdev, state); 537 __pcie_aspm_config_link(leaf, state);
563 } 538 }
564 } 539 }
565} 540}
@@ -568,20 +543,20 @@ static void __pcie_aspm_configure_link_state(struct pci_dev *pdev,
568 * pcie_aspm_configure_link_state: enable/disable PCI express link state 543 * pcie_aspm_configure_link_state: enable/disable PCI express link state
569 * @pdev: the root port or switch downstream port 544 * @pdev: the root port or switch downstream port
570 */ 545 */
571static void pcie_aspm_configure_link_state(struct pci_dev *pdev, 546static void pcie_aspm_configure_link_state(struct pcie_link_state *link,
572 unsigned int state) 547 u32 state)
573{ 548{
574 down_read(&pci_bus_sem); 549 down_read(&pci_bus_sem);
575 mutex_lock(&aspm_lock); 550 mutex_lock(&aspm_lock);
576 __pcie_aspm_configure_link_state(pdev, state); 551 __pcie_aspm_configure_link_state(link, state);
577 mutex_unlock(&aspm_lock); 552 mutex_unlock(&aspm_lock);
578 up_read(&pci_bus_sem); 553 up_read(&pci_bus_sem);
579} 554}
580 555
581static void free_link_state(struct pci_dev *pdev) 556static void free_link_state(struct pcie_link_state *link)
582{ 557{
583 kfree(pdev->link_state); 558 link->pdev->link_state = NULL;
584 pdev->link_state = NULL; 559 kfree(link);
585} 560}
586 561
587static int pcie_aspm_sanity_check(struct pci_dev *pdev) 562static int pcie_aspm_sanity_check(struct pci_dev *pdev)
@@ -648,7 +623,6 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
648 if (!link_state) 623 if (!link_state)
649 goto unlock_out; 624 goto unlock_out;
650 625
651 link_state->has_switch = pcie_aspm_downstream_has_switch(pdev);
652 INIT_LIST_HEAD(&link_state->children); 626 INIT_LIST_HEAD(&link_state->children);
653 INIT_LIST_HEAD(&link_state->link); 627 INIT_LIST_HEAD(&link_state->link);
654 if (pdev->bus->self) {/* this is a switch */ 628 if (pdev->bus->self) {/* this is a switch */
@@ -662,12 +636,13 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
662 list_add(&link_state->link, &parent_link_state->children); 636 list_add(&link_state->link, &parent_link_state->children);
663 link_state->parent = parent_link_state; 637 link_state->parent = parent_link_state;
664 } 638 }
665 639 link_state->pdev = pdev;
640 link_state->has_switch = pcie_aspm_downstream_has_switch(link_state);
666 pdev->link_state = link_state; 641 pdev->link_state = link_state;
667 642
668 if (!blacklist) { 643 if (!blacklist) {
669 pcie_aspm_configure_common_clock(pdev); 644 pcie_aspm_configure_common_clock(link_state);
670 pcie_aspm_cap_init(pdev); 645 pcie_aspm_cap_init(link_state);
671 } else { 646 } else {
672 link_state->aspm_enabled = 647 link_state->aspm_enabled =
673 (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); 648 (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
@@ -676,7 +651,6 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
676 link_state->aspm_support = 0; 651 link_state->aspm_support = 0;
677 } 652 }
678 653
679 link_state->pdev = pdev;
680 list_add(&link_state->sibling, &link_list); 654 list_add(&link_state->sibling, &link_list);
681 655
682 if (link_state->has_switch) { 656 if (link_state->has_switch) {
@@ -685,17 +659,18 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
685 * initialization will config the whole hierarchy. but we must 659 * initialization will config the whole hierarchy. but we must
686 * make sure BIOS doesn't set unsupported link state 660 * make sure BIOS doesn't set unsupported link state
687 **/ 661 **/
688 state = pcie_aspm_check_state(pdev, link_state->aspm_default); 662 state = pcie_aspm_check_state(link_state,
689 __pcie_aspm_config_link(pdev, state); 663 link_state->aspm_default);
664 __pcie_aspm_config_link(link_state, state);
690 } else 665 } else
691 __pcie_aspm_configure_link_state(pdev, 666 __pcie_aspm_configure_link_state(link_state,
692 policy_to_aspm_state(pdev)); 667 policy_to_aspm_state(link_state));
693 668
694 pcie_check_clock_pm(pdev, blacklist); 669 pcie_check_clock_pm(link_state, blacklist);
695 670
696unlock_out: 671unlock_out:
697 if (error) 672 if (error)
698 free_link_state(pdev); 673 free_link_state(link_state);
699 mutex_unlock(&aspm_lock); 674 mutex_unlock(&aspm_lock);
700out: 675out:
701 up_read(&pci_bus_sem); 676 up_read(&pci_bus_sem);
@@ -728,7 +703,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
728 list_del(&link_state->link); 703 list_del(&link_state->link);
729 /* Clock PM is for endpoint device */ 704 /* Clock PM is for endpoint device */
730 705
731 free_link_state(parent); 706 free_link_state(link_state);
732out: 707out:
733 mutex_unlock(&aspm_lock); 708 mutex_unlock(&aspm_lock);
734 up_read(&pci_bus_sem); 709 up_read(&pci_bus_sem);
@@ -748,7 +723,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
748 * devices changed PM state, we should recheck if latency meets all 723 * devices changed PM state, we should recheck if latency meets all
749 * functions' requirement 724 * functions' requirement
750 */ 725 */
751 pcie_aspm_configure_link_state(pdev, link_state->aspm_enabled); 726 pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled);
752} 727}
753 728
754/* 729/*
@@ -775,9 +750,9 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
775 if (state & PCIE_LINK_STATE_CLKPM) 750 if (state & PCIE_LINK_STATE_CLKPM)
776 link_state->clkpm_capable = 0; 751 link_state->clkpm_capable = 0;
777 752
778 __pcie_aspm_configure_link_state(parent, link_state->aspm_enabled); 753 __pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled);
779 if (!link_state->clkpm_capable && link_state->clkpm_enabled) 754 if (!link_state->clkpm_capable && link_state->clkpm_enabled)
780 pcie_set_clock_pm(parent, 0); 755 pcie_set_clock_pm(link_state, 0);
781 mutex_unlock(&aspm_lock); 756 mutex_unlock(&aspm_lock);
782 up_read(&pci_bus_sem); 757 up_read(&pci_bus_sem);
783} 758}
@@ -786,7 +761,6 @@ EXPORT_SYMBOL(pci_disable_link_state);
786static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) 761static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
787{ 762{
788 int i; 763 int i;
789 struct pci_dev *pdev;
790 struct pcie_link_state *link_state; 764 struct pcie_link_state *link_state;
791 765
792 for (i = 0; i < ARRAY_SIZE(policy_str); i++) 766 for (i = 0; i < ARRAY_SIZE(policy_str); i++)
@@ -801,12 +775,12 @@ static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
801 mutex_lock(&aspm_lock); 775 mutex_lock(&aspm_lock);
802 aspm_policy = i; 776 aspm_policy = i;
803 list_for_each_entry(link_state, &link_list, sibling) { 777 list_for_each_entry(link_state, &link_list, sibling) {
804 pdev = link_state->pdev; 778 __pcie_aspm_configure_link_state(link_state,
805 __pcie_aspm_configure_link_state(pdev, 779 policy_to_aspm_state(link_state));
806 policy_to_aspm_state(pdev));
807 if (link_state->clkpm_capable && 780 if (link_state->clkpm_capable &&
808 link_state->clkpm_enabled != policy_to_clkpm_state(pdev)) 781 link_state->clkpm_enabled != policy_to_clkpm_state(link_state))
809 pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); 782 pcie_set_clock_pm(link_state,
783 policy_to_clkpm_state(link_state));
810 784
811 } 785 }
812 mutex_unlock(&aspm_lock); 786 mutex_unlock(&aspm_lock);
@@ -844,7 +818,7 @@ static ssize_t link_state_store(struct device *dev,
844 const char *buf, 818 const char *buf,
845 size_t n) 819 size_t n)
846{ 820{
847 struct pci_dev *pci_device = to_pci_dev(dev); 821 struct pci_dev *pdev = to_pci_dev(dev);
848 int state; 822 int state;
849 823
850 if (n < 1) 824 if (n < 1)
@@ -852,7 +826,7 @@ static ssize_t link_state_store(struct device *dev,
852 state = buf[0]-'0'; 826 state = buf[0]-'0';
853 if (state >= 0 && state <= 3) { 827 if (state >= 0 && state <= 3) {
854 /* setup link aspm state */ 828 /* setup link aspm state */
855 pcie_aspm_configure_link_state(pci_device, state); 829 pcie_aspm_configure_link_state(pdev->link_state, state);
856 return n; 830 return n;
857 } 831 }
858 832
@@ -883,7 +857,7 @@ static ssize_t clk_ctl_store(struct device *dev,
883 857
884 down_read(&pci_bus_sem); 858 down_read(&pci_bus_sem);
885 mutex_lock(&aspm_lock); 859 mutex_lock(&aspm_lock);
886 pcie_set_clock_pm(pci_device, !!state); 860 pcie_set_clock_pm(pci_device->link_state, !!state);
887 mutex_unlock(&aspm_lock); 861 mutex_unlock(&aspm_lock);
888 up_read(&pci_bus_sem); 862 up_read(&pci_bus_sem);
889 863