diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2011-12-15 04:46:24 -0500 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2011-12-15 04:46:24 -0500 |
commit | 5c11ad95b5ba7d5a3675f3d5829a8131a13b33d5 (patch) | |
tree | 60db5d6c52c885b9f525daf77b7f6ef159086c40 /drivers | |
parent | a06ec394c9318e2ee9209ca3c106d3fa6fbfeb00 (diff) | |
parent | 91f57d5e1be3db1e079c8696f1eab214f1c7922d (diff) |
Merge remote-tracking branch 'pci/pri-changes' into x86/amd
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/pci_root.c | 7 | ||||
-rw-r--r-- | drivers/pci/ats.c | 90 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 11 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 1 | ||||
-rw-r--r-- | drivers/pci/msi.c | 121 | ||||
-rw-r--r-- | drivers/pci/pci-acpi.c | 13 | ||||
-rw-r--r-- | drivers/pci/pcie/aspm.c | 58 |
10 files changed, 223 insertions, 87 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 2672c798272f..7aff6312ce7c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -596,6 +596,13 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
596 | if (ACPI_SUCCESS(status)) { | 596 | if (ACPI_SUCCESS(status)) { |
597 | dev_info(root->bus->bridge, | 597 | dev_info(root->bus->bridge, |
598 | "ACPI _OSC control (0x%02x) granted\n", flags); | 598 | "ACPI _OSC control (0x%02x) granted\n", flags); |
599 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { | ||
600 | /* | ||
601 | * We have ASPM control, but the FADT indicates | ||
602 | * that it's unsupported. Clear it. | ||
603 | */ | ||
604 | pcie_clear_aspm(root->bus); | ||
605 | } | ||
599 | } else { | 606 | } else { |
600 | dev_info(root->bus->bridge, | 607 | dev_info(root->bus->bridge, |
601 | "ACPI _OSC request failed (%s), " | 608 | "ACPI _OSC request failed (%s), " |
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index 7ec56fb0bd78..2df49af6cc90 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c | |||
@@ -174,21 +174,22 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs) | |||
174 | u32 max_requests; | 174 | u32 max_requests; |
175 | int pos; | 175 | int pos; |
176 | 176 | ||
177 | pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); | 177 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); |
178 | if (!pos) | 178 | if (!pos) |
179 | return -EINVAL; | 179 | return -EINVAL; |
180 | 180 | ||
181 | pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); | 181 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); |
182 | pci_read_config_word(pdev, pos + PCI_PRI_STATUS_OFF, &status); | 182 | pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status); |
183 | if ((control & PCI_PRI_ENABLE) || !(status & PCI_PRI_STATUS_STOPPED)) | 183 | if ((control & PCI_PRI_CTRL_ENABLE) || |
184 | !(status & PCI_PRI_STATUS_STOPPED)) | ||
184 | return -EBUSY; | 185 | return -EBUSY; |
185 | 186 | ||
186 | pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ_OFF, &max_requests); | 187 | pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ, &max_requests); |
187 | reqs = min(max_requests, reqs); | 188 | reqs = min(max_requests, reqs); |
188 | pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ_OFF, reqs); | 189 | pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs); |
189 | 190 | ||
190 | control |= PCI_PRI_ENABLE; | 191 | control |= PCI_PRI_CTRL_ENABLE; |
191 | pci_write_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, control); | 192 | pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); |
192 | 193 | ||
193 | return 0; | 194 | return 0; |
194 | } | 195 | } |
@@ -205,13 +206,13 @@ void pci_disable_pri(struct pci_dev *pdev) | |||
205 | u16 control; | 206 | u16 control; |
206 | int pos; | 207 | int pos; |
207 | 208 | ||
208 | pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); | 209 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); |
209 | if (!pos) | 210 | if (!pos) |
210 | return; | 211 | return; |
211 | 212 | ||
212 | pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); | 213 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); |
213 | control &= ~PCI_PRI_ENABLE; | 214 | control &= ~PCI_PRI_CTRL_ENABLE; |
214 | pci_write_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, control); | 215 | pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); |
215 | } | 216 | } |
216 | EXPORT_SYMBOL_GPL(pci_disable_pri); | 217 | EXPORT_SYMBOL_GPL(pci_disable_pri); |
217 | 218 | ||
@@ -226,13 +227,13 @@ bool pci_pri_enabled(struct pci_dev *pdev) | |||
226 | u16 control; | 227 | u16 control; |
227 | int pos; | 228 | int pos; |
228 | 229 | ||
229 | pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); | 230 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); |
230 | if (!pos) | 231 | if (!pos) |
231 | return false; | 232 | return false; |
232 | 233 | ||
233 | pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); | 234 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); |
234 | 235 | ||
235 | return (control & PCI_PRI_ENABLE) ? true : false; | 236 | return (control & PCI_PRI_CTRL_ENABLE) ? true : false; |
236 | } | 237 | } |
237 | EXPORT_SYMBOL_GPL(pci_pri_enabled); | 238 | EXPORT_SYMBOL_GPL(pci_pri_enabled); |
238 | 239 | ||
@@ -248,17 +249,17 @@ int pci_reset_pri(struct pci_dev *pdev) | |||
248 | u16 control; | 249 | u16 control; |
249 | int pos; | 250 | int pos; |
250 | 251 | ||
251 | pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); | 252 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); |
252 | if (!pos) | 253 | if (!pos) |
253 | return -EINVAL; | 254 | return -EINVAL; |
254 | 255 | ||
255 | pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); | 256 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); |
256 | if (control & PCI_PRI_ENABLE) | 257 | if (control & PCI_PRI_CTRL_ENABLE) |
257 | return -EBUSY; | 258 | return -EBUSY; |
258 | 259 | ||
259 | control |= PCI_PRI_RESET; | 260 | control |= PCI_PRI_CTRL_RESET; |
260 | 261 | ||
261 | pci_write_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, control); | 262 | pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); |
262 | 263 | ||
263 | return 0; | 264 | return 0; |
264 | } | 265 | } |
@@ -281,14 +282,14 @@ bool pci_pri_stopped(struct pci_dev *pdev) | |||
281 | u16 control, status; | 282 | u16 control, status; |
282 | int pos; | 283 | int pos; |
283 | 284 | ||
284 | pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); | 285 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); |
285 | if (!pos) | 286 | if (!pos) |
286 | return true; | 287 | return true; |
287 | 288 | ||
288 | pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); | 289 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); |
289 | pci_read_config_word(pdev, pos + PCI_PRI_STATUS_OFF, &status); | 290 | pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status); |
290 | 291 | ||
291 | if (control & PCI_PRI_ENABLE) | 292 | if (control & PCI_PRI_CTRL_ENABLE) |
292 | return false; | 293 | return false; |
293 | 294 | ||
294 | return (status & PCI_PRI_STATUS_STOPPED) ? true : false; | 295 | return (status & PCI_PRI_STATUS_STOPPED) ? true : false; |
@@ -310,15 +311,15 @@ int pci_pri_status(struct pci_dev *pdev) | |||
310 | u16 status, control; | 311 | u16 status, control; |
311 | int pos; | 312 | int pos; |
312 | 313 | ||
313 | pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); | 314 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); |
314 | if (!pos) | 315 | if (!pos) |
315 | return -EINVAL; | 316 | return -EINVAL; |
316 | 317 | ||
317 | pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); | 318 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); |
318 | pci_read_config_word(pdev, pos + PCI_PRI_STATUS_OFF, &status); | 319 | pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status); |
319 | 320 | ||
320 | /* Stopped bit is undefined when enable == 1, so clear it */ | 321 | /* Stopped bit is undefined when enable == 1, so clear it */ |
321 | if (control & PCI_PRI_ENABLE) | 322 | if (control & PCI_PRI_CTRL_ENABLE) |
322 | status &= ~PCI_PRI_STATUS_STOPPED; | 323 | status &= ~PCI_PRI_STATUS_STOPPED; |
323 | 324 | ||
324 | return status; | 325 | return status; |
@@ -341,25 +342,25 @@ int pci_enable_pasid(struct pci_dev *pdev, int features) | |||
341 | u16 control, supported; | 342 | u16 control, supported; |
342 | int pos; | 343 | int pos; |
343 | 344 | ||
344 | pos = pci_find_ext_capability(pdev, PCI_PASID_CAP); | 345 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); |
345 | if (!pos) | 346 | if (!pos) |
346 | return -EINVAL; | 347 | return -EINVAL; |
347 | 348 | ||
348 | pci_read_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, &control); | 349 | pci_read_config_word(pdev, pos + PCI_PASID_CTRL, &control); |
349 | pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF, &supported); | 350 | pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported); |
350 | 351 | ||
351 | if (!(supported & PCI_PASID_ENABLE)) | 352 | if (control & PCI_PASID_CTRL_ENABLE) |
352 | return -EINVAL; | 353 | return -EINVAL; |
353 | 354 | ||
354 | supported &= PCI_PASID_EXEC | PCI_PASID_PRIV; | 355 | supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV; |
355 | 356 | ||
356 | /* User wants to enable anything unsupported? */ | 357 | /* User wants to enable anything unsupported? */ |
357 | if ((supported & features) != features) | 358 | if ((supported & features) != features) |
358 | return -EINVAL; | 359 | return -EINVAL; |
359 | 360 | ||
360 | control = PCI_PASID_ENABLE | features; | 361 | control = PCI_PASID_CTRL_ENABLE | features; |
361 | 362 | ||
362 | pci_write_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, control); | 363 | pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control); |
363 | 364 | ||
364 | return 0; | 365 | return 0; |
365 | } | 366 | } |
@@ -375,11 +376,11 @@ void pci_disable_pasid(struct pci_dev *pdev) | |||
375 | u16 control = 0; | 376 | u16 control = 0; |
376 | int pos; | 377 | int pos; |
377 | 378 | ||
378 | pos = pci_find_ext_capability(pdev, PCI_PASID_CAP); | 379 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); |
379 | if (!pos) | 380 | if (!pos) |
380 | return; | 381 | return; |
381 | 382 | ||
382 | pci_write_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, control); | 383 | pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control); |
383 | } | 384 | } |
384 | EXPORT_SYMBOL_GPL(pci_disable_pasid); | 385 | EXPORT_SYMBOL_GPL(pci_disable_pasid); |
385 | 386 | ||
@@ -390,22 +391,21 @@ EXPORT_SYMBOL_GPL(pci_disable_pasid); | |||
390 | * Returns a negative value when no PASI capability is present. | 391 | * Returns a negative value when no PASI capability is present. |
391 | * Otherwise is returns a bitmask with supported features. Current | 392 | * Otherwise is returns a bitmask with supported features. Current |
392 | * features reported are: | 393 | * features reported are: |
393 | * PCI_PASID_ENABLE - PASID capability can be enabled | 394 | * PCI_PASID_CAP_EXEC - Execute permission supported |
394 | * PCI_PASID_EXEC - Execute permission supported | 395 | * PCI_PASID_CAP_PRIV - Priviledged mode supported |
395 | * PCI_PASID_PRIV - Priviledged mode supported | ||
396 | */ | 396 | */ |
397 | int pci_pasid_features(struct pci_dev *pdev) | 397 | int pci_pasid_features(struct pci_dev *pdev) |
398 | { | 398 | { |
399 | u16 supported; | 399 | u16 supported; |
400 | int pos; | 400 | int pos; |
401 | 401 | ||
402 | pos = pci_find_ext_capability(pdev, PCI_PASID_CAP); | 402 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); |
403 | if (!pos) | 403 | if (!pos) |
404 | return -EINVAL; | 404 | return -EINVAL; |
405 | 405 | ||
406 | pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF, &supported); | 406 | pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported); |
407 | 407 | ||
408 | supported &= PCI_PASID_ENABLE | PCI_PASID_EXEC | PCI_PASID_PRIV; | 408 | supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV; |
409 | 409 | ||
410 | return supported; | 410 | return supported; |
411 | } | 411 | } |
@@ -425,11 +425,11 @@ int pci_max_pasids(struct pci_dev *pdev) | |||
425 | u16 supported; | 425 | u16 supported; |
426 | int pos; | 426 | int pos; |
427 | 427 | ||
428 | pos = pci_find_ext_capability(pdev, PCI_PASID_CAP); | 428 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); |
429 | if (!pos) | 429 | if (!pos) |
430 | return -EINVAL; | 430 | return -EINVAL; |
431 | 431 | ||
432 | pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF, &supported); | 432 | pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported); |
433 | 433 | ||
434 | supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT; | 434 | supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT; |
435 | 435 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index fce1c54a0c8d..ba43c037de80 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -467,7 +467,7 @@ static int add_bridge(acpi_handle handle) | |||
467 | * granted by the BIOS for it. | 467 | * granted by the BIOS for it. |
468 | */ | 468 | */ |
469 | root = acpi_pci_find_root(handle); | 469 | root = acpi_pci_find_root(handle); |
470 | if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) | 470 | if (root && (root->osc_control_set & OSC_PCI_NATIVE_HOTPLUG)) |
471 | return -ENODEV; | 471 | return -ENODEV; |
472 | 472 | ||
473 | /* if the bridge doesn't have _STA, we assume it is always there */ | 473 | /* if the bridge doesn't have _STA, we assume it is always there */ |
@@ -1395,7 +1395,7 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
1395 | if (!root) | 1395 | if (!root) |
1396 | return AE_OK; | 1396 | return AE_OK; |
1397 | 1397 | ||
1398 | if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) | 1398 | if (root->osc_control_set & OSC_PCI_NATIVE_HOTPLUG) |
1399 | return AE_OK; | 1399 | return AE_OK; |
1400 | 1400 | ||
1401 | (*count)++; | 1401 | (*count)++; |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 838f571027b7..9a33fdde2d16 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -45,7 +45,6 @@ extern int pciehp_poll_time; | |||
45 | extern int pciehp_debug; | 45 | extern int pciehp_debug; |
46 | extern int pciehp_force; | 46 | extern int pciehp_force; |
47 | extern struct workqueue_struct *pciehp_wq; | 47 | extern struct workqueue_struct *pciehp_wq; |
48 | extern struct workqueue_struct *pciehp_ordered_wq; | ||
49 | 48 | ||
50 | #define dbg(format, arg...) \ | 49 | #define dbg(format, arg...) \ |
51 | do { \ | 50 | do { \ |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 7ac8358df8fd..b8c99d35ac97 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -43,7 +43,6 @@ int pciehp_poll_mode; | |||
43 | int pciehp_poll_time; | 43 | int pciehp_poll_time; |
44 | int pciehp_force; | 44 | int pciehp_force; |
45 | struct workqueue_struct *pciehp_wq; | 45 | struct workqueue_struct *pciehp_wq; |
46 | struct workqueue_struct *pciehp_ordered_wq; | ||
47 | 46 | ||
48 | #define DRIVER_VERSION "0.4" | 47 | #define DRIVER_VERSION "0.4" |
49 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" | 48 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" |
@@ -345,18 +344,11 @@ static int __init pcied_init(void) | |||
345 | if (!pciehp_wq) | 344 | if (!pciehp_wq) |
346 | return -ENOMEM; | 345 | return -ENOMEM; |
347 | 346 | ||
348 | pciehp_ordered_wq = alloc_ordered_workqueue("pciehp_ordered", 0); | ||
349 | if (!pciehp_ordered_wq) { | ||
350 | destroy_workqueue(pciehp_wq); | ||
351 | return -ENOMEM; | ||
352 | } | ||
353 | |||
354 | pciehp_firmware_init(); | 347 | pciehp_firmware_init(); |
355 | retval = pcie_port_service_register(&hpdriver_portdrv); | 348 | retval = pcie_port_service_register(&hpdriver_portdrv); |
356 | dbg("pcie_port_service_register = %d\n", retval); | 349 | dbg("pcie_port_service_register = %d\n", retval); |
357 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 350 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); |
358 | if (retval) { | 351 | if (retval) { |
359 | destroy_workqueue(pciehp_ordered_wq); | ||
360 | destroy_workqueue(pciehp_wq); | 352 | destroy_workqueue(pciehp_wq); |
361 | dbg("Failure to register service\n"); | 353 | dbg("Failure to register service\n"); |
362 | } | 354 | } |
@@ -366,9 +358,8 @@ static int __init pcied_init(void) | |||
366 | static void __exit pcied_cleanup(void) | 358 | static void __exit pcied_cleanup(void) |
367 | { | 359 | { |
368 | dbg("unload_pciehpd()\n"); | 360 | dbg("unload_pciehpd()\n"); |
369 | destroy_workqueue(pciehp_ordered_wq); | ||
370 | destroy_workqueue(pciehp_wq); | ||
371 | pcie_port_service_unregister(&hpdriver_portdrv); | 361 | pcie_port_service_unregister(&hpdriver_portdrv); |
362 | destroy_workqueue(pciehp_wq); | ||
372 | info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); | 363 | info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); |
373 | } | 364 | } |
374 | 365 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 085dbb5fc168..27f44295a657 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -344,7 +344,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
344 | kfree(info); | 344 | kfree(info); |
345 | goto out; | 345 | goto out; |
346 | } | 346 | } |
347 | queue_work(pciehp_ordered_wq, &info->work); | 347 | queue_work(pciehp_wq, &info->work); |
348 | out: | 348 | out: |
349 | mutex_unlock(&p_slot->lock); | 349 | mutex_unlock(&p_slot->lock); |
350 | } | 350 | } |
@@ -439,7 +439,7 @@ static void handle_surprise_event(struct slot *p_slot) | |||
439 | else | 439 | else |
440 | p_slot->state = POWERON_STATE; | 440 | p_slot->state = POWERON_STATE; |
441 | 441 | ||
442 | queue_work(pciehp_ordered_wq, &info->work); | 442 | queue_work(pciehp_wq, &info->work); |
443 | } | 443 | } |
444 | 444 | ||
445 | static void interrupt_event_handler(struct work_struct *work) | 445 | static void interrupt_event_handler(struct work_struct *work) |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 7b1414810ae3..bcdbb1643621 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -806,7 +806,6 @@ static void pcie_cleanup_slot(struct controller *ctrl) | |||
806 | struct slot *slot = ctrl->slot; | 806 | struct slot *slot = ctrl->slot; |
807 | cancel_delayed_work(&slot->work); | 807 | cancel_delayed_work(&slot->work); |
808 | flush_workqueue(pciehp_wq); | 808 | flush_workqueue(pciehp_wq); |
809 | flush_workqueue(pciehp_ordered_wq); | ||
810 | kfree(slot); | 809 | kfree(slot); |
811 | } | 810 | } |
812 | 811 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 0e6d04d7ba4f..337e16ab4a92 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -323,6 +323,8 @@ static void free_msi_irqs(struct pci_dev *dev) | |||
323 | if (list_is_last(&entry->list, &dev->msi_list)) | 323 | if (list_is_last(&entry->list, &dev->msi_list)) |
324 | iounmap(entry->mask_base); | 324 | iounmap(entry->mask_base); |
325 | } | 325 | } |
326 | kobject_del(&entry->kobj); | ||
327 | kobject_put(&entry->kobj); | ||
326 | list_del(&entry->list); | 328 | list_del(&entry->list); |
327 | kfree(entry); | 329 | kfree(entry); |
328 | } | 330 | } |
@@ -403,6 +405,98 @@ void pci_restore_msi_state(struct pci_dev *dev) | |||
403 | } | 405 | } |
404 | EXPORT_SYMBOL_GPL(pci_restore_msi_state); | 406 | EXPORT_SYMBOL_GPL(pci_restore_msi_state); |
405 | 407 | ||
408 | |||
409 | #define to_msi_attr(obj) container_of(obj, struct msi_attribute, attr) | ||
410 | #define to_msi_desc(obj) container_of(obj, struct msi_desc, kobj) | ||
411 | |||
412 | struct msi_attribute { | ||
413 | struct attribute attr; | ||
414 | ssize_t (*show)(struct msi_desc *entry, struct msi_attribute *attr, | ||
415 | char *buf); | ||
416 | ssize_t (*store)(struct msi_desc *entry, struct msi_attribute *attr, | ||
417 | const char *buf, size_t count); | ||
418 | }; | ||
419 | |||
420 | static ssize_t show_msi_mode(struct msi_desc *entry, struct msi_attribute *atr, | ||
421 | char *buf) | ||
422 | { | ||
423 | return sprintf(buf, "%s\n", entry->msi_attrib.is_msix ? "msix" : "msi"); | ||
424 | } | ||
425 | |||
426 | static ssize_t msi_irq_attr_show(struct kobject *kobj, | ||
427 | struct attribute *attr, char *buf) | ||
428 | { | ||
429 | struct msi_attribute *attribute = to_msi_attr(attr); | ||
430 | struct msi_desc *entry = to_msi_desc(kobj); | ||
431 | |||
432 | if (!attribute->show) | ||
433 | return -EIO; | ||
434 | |||
435 | return attribute->show(entry, attribute, buf); | ||
436 | } | ||
437 | |||
438 | static const struct sysfs_ops msi_irq_sysfs_ops = { | ||
439 | .show = msi_irq_attr_show, | ||
440 | }; | ||
441 | |||
442 | static struct msi_attribute mode_attribute = | ||
443 | __ATTR(mode, S_IRUGO, show_msi_mode, NULL); | ||
444 | |||
445 | |||
446 | struct attribute *msi_irq_default_attrs[] = { | ||
447 | &mode_attribute.attr, | ||
448 | NULL | ||
449 | }; | ||
450 | |||
451 | void msi_kobj_release(struct kobject *kobj) | ||
452 | { | ||
453 | struct msi_desc *entry = to_msi_desc(kobj); | ||
454 | |||
455 | pci_dev_put(entry->dev); | ||
456 | } | ||
457 | |||
458 | static struct kobj_type msi_irq_ktype = { | ||
459 | .release = msi_kobj_release, | ||
460 | .sysfs_ops = &msi_irq_sysfs_ops, | ||
461 | .default_attrs = msi_irq_default_attrs, | ||
462 | }; | ||
463 | |||
464 | static int populate_msi_sysfs(struct pci_dev *pdev) | ||
465 | { | ||
466 | struct msi_desc *entry; | ||
467 | struct kobject *kobj; | ||
468 | int ret; | ||
469 | int count = 0; | ||
470 | |||
471 | pdev->msi_kset = kset_create_and_add("msi_irqs", NULL, &pdev->dev.kobj); | ||
472 | if (!pdev->msi_kset) | ||
473 | return -ENOMEM; | ||
474 | |||
475 | list_for_each_entry(entry, &pdev->msi_list, list) { | ||
476 | kobj = &entry->kobj; | ||
477 | kobj->kset = pdev->msi_kset; | ||
478 | pci_dev_get(pdev); | ||
479 | ret = kobject_init_and_add(kobj, &msi_irq_ktype, NULL, | ||
480 | "%u", entry->irq); | ||
481 | if (ret) | ||
482 | goto out_unroll; | ||
483 | |||
484 | count++; | ||
485 | } | ||
486 | |||
487 | return 0; | ||
488 | |||
489 | out_unroll: | ||
490 | list_for_each_entry(entry, &pdev->msi_list, list) { | ||
491 | if (!count) | ||
492 | break; | ||
493 | kobject_del(&entry->kobj); | ||
494 | kobject_put(&entry->kobj); | ||
495 | count--; | ||
496 | } | ||
497 | return ret; | ||
498 | } | ||
499 | |||
406 | /** | 500 | /** |
407 | * msi_capability_init - configure device's MSI capability structure | 501 | * msi_capability_init - configure device's MSI capability structure |
408 | * @dev: pointer to the pci_dev data structure of MSI device function | 502 | * @dev: pointer to the pci_dev data structure of MSI device function |
@@ -454,6 +548,13 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
454 | return ret; | 548 | return ret; |
455 | } | 549 | } |
456 | 550 | ||
551 | ret = populate_msi_sysfs(dev); | ||
552 | if (ret) { | ||
553 | msi_mask_irq(entry, mask, ~mask); | ||
554 | free_msi_irqs(dev); | ||
555 | return ret; | ||
556 | } | ||
557 | |||
457 | /* Set MSI enabled bits */ | 558 | /* Set MSI enabled bits */ |
458 | pci_intx_for_msi(dev, 0); | 559 | pci_intx_for_msi(dev, 0); |
459 | msi_set_enable(dev, pos, 1); | 560 | msi_set_enable(dev, pos, 1); |
@@ -574,6 +675,12 @@ static int msix_capability_init(struct pci_dev *dev, | |||
574 | 675 | ||
575 | msix_program_entries(dev, entries); | 676 | msix_program_entries(dev, entries); |
576 | 677 | ||
678 | ret = populate_msi_sysfs(dev); | ||
679 | if (ret) { | ||
680 | ret = 0; | ||
681 | goto error; | ||
682 | } | ||
683 | |||
577 | /* Set MSI-X enabled bits and unmask the function */ | 684 | /* Set MSI-X enabled bits and unmask the function */ |
578 | pci_intx_for_msi(dev, 0); | 685 | pci_intx_for_msi(dev, 0); |
579 | dev->msix_enabled = 1; | 686 | dev->msix_enabled = 1; |
@@ -732,6 +839,8 @@ void pci_disable_msi(struct pci_dev *dev) | |||
732 | 839 | ||
733 | pci_msi_shutdown(dev); | 840 | pci_msi_shutdown(dev); |
734 | free_msi_irqs(dev); | 841 | free_msi_irqs(dev); |
842 | kset_unregister(dev->msi_kset); | ||
843 | dev->msi_kset = NULL; | ||
735 | } | 844 | } |
736 | EXPORT_SYMBOL(pci_disable_msi); | 845 | EXPORT_SYMBOL(pci_disable_msi); |
737 | 846 | ||
@@ -830,6 +939,8 @@ void pci_disable_msix(struct pci_dev *dev) | |||
830 | 939 | ||
831 | pci_msix_shutdown(dev); | 940 | pci_msix_shutdown(dev); |
832 | free_msi_irqs(dev); | 941 | free_msi_irqs(dev); |
942 | kset_unregister(dev->msi_kset); | ||
943 | dev->msi_kset = NULL; | ||
833 | } | 944 | } |
834 | EXPORT_SYMBOL(pci_disable_msix); | 945 | EXPORT_SYMBOL(pci_disable_msix); |
835 | 946 | ||
@@ -870,5 +981,15 @@ EXPORT_SYMBOL(pci_msi_enabled); | |||
870 | 981 | ||
871 | void pci_msi_init_pci_dev(struct pci_dev *dev) | 982 | void pci_msi_init_pci_dev(struct pci_dev *dev) |
872 | { | 983 | { |
984 | int pos; | ||
873 | INIT_LIST_HEAD(&dev->msi_list); | 985 | INIT_LIST_HEAD(&dev->msi_list); |
986 | |||
987 | /* Disable the msi hardware to avoid screaming interrupts | ||
988 | * during boot. This is the power on reset default so | ||
989 | * usually this should be a noop. | ||
990 | */ | ||
991 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
992 | if (pos) | ||
993 | msi_set_enable(dev, pos, 0); | ||
994 | msix_set_enable(dev, 0); | ||
874 | } | 995 | } |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 4ecb6408b0d6..060fd22a1103 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -45,16 +45,20 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | |||
45 | { | 45 | { |
46 | struct pci_dev *pci_dev = context; | 46 | struct pci_dev *pci_dev = context; |
47 | 47 | ||
48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { | 48 | if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev) |
49 | return; | ||
50 | |||
51 | if (!pci_dev->pm_cap || !pci_dev->pme_support | ||
52 | || pci_check_pme_status(pci_dev)) { | ||
49 | if (pci_dev->pme_poll) | 53 | if (pci_dev->pme_poll) |
50 | pci_dev->pme_poll = false; | 54 | pci_dev->pme_poll = false; |
51 | 55 | ||
52 | pci_wakeup_event(pci_dev); | 56 | pci_wakeup_event(pci_dev); |
53 | pci_check_pme_status(pci_dev); | ||
54 | pm_runtime_resume(&pci_dev->dev); | 57 | pm_runtime_resume(&pci_dev->dev); |
55 | if (pci_dev->subordinate) | ||
56 | pci_pme_wakeup_bus(pci_dev->subordinate); | ||
57 | } | 58 | } |
59 | |||
60 | if (pci_dev->subordinate) | ||
61 | pci_pme_wakeup_bus(pci_dev->subordinate); | ||
58 | } | 62 | } |
59 | 63 | ||
60 | /** | 64 | /** |
@@ -395,7 +399,6 @@ static int __init acpi_pci_init(void) | |||
395 | 399 | ||
396 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { | 400 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { |
397 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); | 401 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); |
398 | pcie_clear_aspm(); | ||
399 | pcie_no_aspm(); | 402 | pcie_no_aspm(); |
400 | } | 403 | } |
401 | 404 | ||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index cbfbab18be91..1cfbf228fbb1 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -68,7 +68,7 @@ struct pcie_link_state { | |||
68 | struct aspm_latency acceptable[8]; | 68 | struct aspm_latency acceptable[8]; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static int aspm_disabled, aspm_force, aspm_clear_state; | 71 | static int aspm_disabled, aspm_force; |
72 | static bool aspm_support_enabled = true; | 72 | static bool aspm_support_enabled = true; |
73 | static DEFINE_MUTEX(aspm_lock); | 73 | static DEFINE_MUTEX(aspm_lock); |
74 | static LIST_HEAD(link_list); | 74 | static LIST_HEAD(link_list); |
@@ -500,9 +500,6 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
500 | int pos; | 500 | int pos; |
501 | u32 reg32; | 501 | u32 reg32; |
502 | 502 | ||
503 | if (aspm_clear_state) | ||
504 | return -EINVAL; | ||
505 | |||
506 | /* | 503 | /* |
507 | * Some functions in a slot might not all be PCIe functions, | 504 | * Some functions in a slot might not all be PCIe functions, |
508 | * very strange. Disable ASPM for the whole slot | 505 | * very strange. Disable ASPM for the whole slot |
@@ -574,9 +571,6 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
574 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | 571 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) |
575 | return; | 572 | return; |
576 | 573 | ||
577 | if (aspm_disabled && !aspm_clear_state) | ||
578 | return; | ||
579 | |||
580 | /* VIA has a strange chipset, root port is under a bridge */ | 574 | /* VIA has a strange chipset, root port is under a bridge */ |
581 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && | 575 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && |
582 | pdev->bus->self) | 576 | pdev->bus->self) |
@@ -608,7 +602,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
608 | * the BIOS's expectation, we'll do so once pci_enable_device() is | 602 | * the BIOS's expectation, we'll do so once pci_enable_device() is |
609 | * called. | 603 | * called. |
610 | */ | 604 | */ |
611 | if (aspm_policy != POLICY_POWERSAVE || aspm_clear_state) { | 605 | if (aspm_policy != POLICY_POWERSAVE) { |
612 | pcie_config_aspm_path(link); | 606 | pcie_config_aspm_path(link); |
613 | pcie_set_clkpm(link, policy_to_clkpm_state(link)); | 607 | pcie_set_clkpm(link, policy_to_clkpm_state(link)); |
614 | } | 608 | } |
@@ -649,8 +643,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
649 | struct pci_dev *parent = pdev->bus->self; | 643 | struct pci_dev *parent = pdev->bus->self; |
650 | struct pcie_link_state *link, *root, *parent_link; | 644 | struct pcie_link_state *link, *root, *parent_link; |
651 | 645 | ||
652 | if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) || | 646 | if (!pci_is_pcie(pdev) || !parent || !parent->link_state) |
653 | !parent || !parent->link_state) | ||
654 | return; | 647 | return; |
655 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 648 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
656 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | 649 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) |
@@ -734,13 +727,18 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev) | |||
734 | * pci_disable_link_state - disable pci device's link state, so the link will | 727 | * pci_disable_link_state - disable pci device's link state, so the link will |
735 | * never enter specific states | 728 | * never enter specific states |
736 | */ | 729 | */ |
737 | static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) | 730 | static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, |
731 | bool force) | ||
738 | { | 732 | { |
739 | struct pci_dev *parent = pdev->bus->self; | 733 | struct pci_dev *parent = pdev->bus->self; |
740 | struct pcie_link_state *link; | 734 | struct pcie_link_state *link; |
741 | 735 | ||
742 | if (aspm_disabled || !pci_is_pcie(pdev)) | 736 | if (aspm_disabled && !force) |
737 | return; | ||
738 | |||
739 | if (!pci_is_pcie(pdev)) | ||
743 | return; | 740 | return; |
741 | |||
744 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || | 742 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || |
745 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) | 743 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) |
746 | parent = pdev; | 744 | parent = pdev; |
@@ -768,16 +766,31 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) | |||
768 | 766 | ||
769 | void pci_disable_link_state_locked(struct pci_dev *pdev, int state) | 767 | void pci_disable_link_state_locked(struct pci_dev *pdev, int state) |
770 | { | 768 | { |
771 | __pci_disable_link_state(pdev, state, false); | 769 | __pci_disable_link_state(pdev, state, false, false); |
772 | } | 770 | } |
773 | EXPORT_SYMBOL(pci_disable_link_state_locked); | 771 | EXPORT_SYMBOL(pci_disable_link_state_locked); |
774 | 772 | ||
775 | void pci_disable_link_state(struct pci_dev *pdev, int state) | 773 | void pci_disable_link_state(struct pci_dev *pdev, int state) |
776 | { | 774 | { |
777 | __pci_disable_link_state(pdev, state, true); | 775 | __pci_disable_link_state(pdev, state, true, false); |
778 | } | 776 | } |
779 | EXPORT_SYMBOL(pci_disable_link_state); | 777 | EXPORT_SYMBOL(pci_disable_link_state); |
780 | 778 | ||
779 | void pcie_clear_aspm(struct pci_bus *bus) | ||
780 | { | ||
781 | struct pci_dev *child; | ||
782 | |||
783 | /* | ||
784 | * Clear any ASPM setup that the firmware has carried out on this bus | ||
785 | */ | ||
786 | list_for_each_entry(child, &bus->devices, bus_list) { | ||
787 | __pci_disable_link_state(child, PCIE_LINK_STATE_L0S | | ||
788 | PCIE_LINK_STATE_L1 | | ||
789 | PCIE_LINK_STATE_CLKPM, | ||
790 | false, true); | ||
791 | } | ||
792 | } | ||
793 | |||
781 | static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) | 794 | static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) |
782 | { | 795 | { |
783 | int i; | 796 | int i; |
@@ -935,6 +948,7 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) | |||
935 | static int __init pcie_aspm_disable(char *str) | 948 | static int __init pcie_aspm_disable(char *str) |
936 | { | 949 | { |
937 | if (!strcmp(str, "off")) { | 950 | if (!strcmp(str, "off")) { |
951 | aspm_policy = POLICY_DEFAULT; | ||
938 | aspm_disabled = 1; | 952 | aspm_disabled = 1; |
939 | aspm_support_enabled = false; | 953 | aspm_support_enabled = false; |
940 | printk(KERN_INFO "PCIe ASPM is disabled\n"); | 954 | printk(KERN_INFO "PCIe ASPM is disabled\n"); |
@@ -947,16 +961,18 @@ static int __init pcie_aspm_disable(char *str) | |||
947 | 961 | ||
948 | __setup("pcie_aspm=", pcie_aspm_disable); | 962 | __setup("pcie_aspm=", pcie_aspm_disable); |
949 | 963 | ||
950 | void pcie_clear_aspm(void) | ||
951 | { | ||
952 | if (!aspm_force) | ||
953 | aspm_clear_state = 1; | ||
954 | } | ||
955 | |||
956 | void pcie_no_aspm(void) | 964 | void pcie_no_aspm(void) |
957 | { | 965 | { |
958 | if (!aspm_force) | 966 | /* |
967 | * Disabling ASPM is intended to prevent the kernel from modifying | ||
968 | * existing hardware state, not to clear existing state. To that end: | ||
969 | * (a) set policy to POLICY_DEFAULT in order to avoid changing state | ||
970 | * (b) prevent userspace from changing policy | ||
971 | */ | ||
972 | if (!aspm_force) { | ||
973 | aspm_policy = POLICY_DEFAULT; | ||
959 | aspm_disabled = 1; | 974 | aspm_disabled = 1; |
975 | } | ||
960 | } | 976 | } |
961 | 977 | ||
962 | /** | 978 | /** |