aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2013-09-05 17:07:41 -0400
committerBjorn Helgaas <bhelgaas@google.com>2013-09-23 19:40:46 -0400
commit3e43abb012d45dc284ef9a0fb0cea0fb004b5607 (patch)
treed29b259491d921d99d14f701fc403c00dbfe3176 /drivers/acpi
parent4ffe6e54b0ce259d254e7740a7a4a99dad14a484 (diff)
PCI/ACPI: Move _OSC stuff from acpi_pci_root_add() to negotiate_os_control()
This doesn't change any of the _OSC code; it just moves it out into a new function so it doesn't clutter acpi_pci_root_add() so much. This also enables future simplifications. Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/pci_root.c132
1 files changed, 71 insertions, 61 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index cc87cc4fea0e..3e57f104e09a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -360,67 +360,13 @@ out:
360} 360}
361EXPORT_SYMBOL(acpi_pci_osc_control_set); 361EXPORT_SYMBOL(acpi_pci_osc_control_set);
362 362
363static int acpi_pci_root_add(struct acpi_device *device, 363static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
364 const struct acpi_device_id *not_used) 364 int *clear_aspm)
365{ 365{
366 unsigned long long segment, bus;
367 acpi_status status;
368 int result;
369 struct acpi_pci_root *root;
370 u32 flags, base_flags; 366 u32 flags, base_flags;
367 acpi_status status;
368 struct acpi_device *device = root->device;
371 acpi_handle handle = device->handle; 369 acpi_handle handle = device->handle;
372 bool no_aspm = false, clear_aspm = false;
373
374 root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
375 if (!root)
376 return -ENOMEM;
377
378 segment = 0;
379 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL,
380 &segment);
381 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
382 dev_err(&device->dev, "can't evaluate _SEG\n");
383 result = -ENODEV;
384 goto end;
385 }
386
387 /* Check _CRS first, then _BBN. If no _BBN, default to zero. */
388 root->secondary.flags = IORESOURCE_BUS;
389 status = try_get_root_bridge_busnr(handle, &root->secondary);
390 if (ACPI_FAILURE(status)) {
391 /*
392 * We need both the start and end of the downstream bus range
393 * to interpret _CBA (MMCONFIG base address), so it really is
394 * supposed to be in _CRS. If we don't find it there, all we
395 * can do is assume [_BBN-0xFF] or [0-0xFF].
396 */
397 root->secondary.end = 0xFF;
398 dev_warn(&device->dev,
399 FW_BUG "no secondary bus range in _CRS\n");
400 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN,
401 NULL, &bus);
402 if (ACPI_SUCCESS(status))
403 root->secondary.start = bus;
404 else if (status == AE_NOT_FOUND)
405 root->secondary.start = 0;
406 else {
407 dev_err(&device->dev, "can't evaluate _BBN\n");
408 result = -ENODEV;
409 goto end;
410 }
411 }
412
413 root->device = device;
414 root->segment = segment & 0xFFFF;
415 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
416 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
417 device->driver_data = root;
418
419 pr_info(PREFIX "%s [%s] (domain %04x %pR)\n",
420 acpi_device_name(device), acpi_device_bid(device),
421 root->segment, &root->secondary);
422
423 root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle);
424 370
425 /* 371 /*
426 * All supported architectures that use ACPI have support for 372 * All supported architectures that use ACPI have support for
@@ -441,7 +387,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
441 if (ACPI_FAILURE(status)) { 387 if (ACPI_FAILURE(status)) {
442 dev_info(&device->dev, "ACPI _OSC support " 388 dev_info(&device->dev, "ACPI _OSC support "
443 "notification failed, disabling PCIe ASPM\n"); 389 "notification failed, disabling PCIe ASPM\n");
444 no_aspm = true; 390 *no_aspm = 1;
445 flags = base_flags; 391 flags = base_flags;
446 } 392 }
447 } 393 }
@@ -473,7 +419,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
473 * We have ASPM control, but the FADT indicates 419 * We have ASPM control, but the FADT indicates
474 * that it's unsupported. Clear it. 420 * that it's unsupported. Clear it.
475 */ 421 */
476 clear_aspm = true; 422 *clear_aspm = 1;
477 } 423 }
478 } else { 424 } else {
479 dev_info(&device->dev, 425 dev_info(&device->dev,
@@ -489,13 +435,77 @@ static int acpi_pci_root_add(struct acpi_device *device,
489 * flag here, to defer the action until after the ACPI 435 * flag here, to defer the action until after the ACPI
490 * root scan. 436 * root scan.
491 */ 437 */
492 no_aspm = true; 438 *no_aspm = 1;
493 } 439 }
494 } else { 440 } else {
495 dev_info(&device->dev, 441 dev_info(&device->dev,
496 "Unable to request _OSC control " 442 "Unable to request _OSC control "
497 "(_OSC support mask: 0x%02x)\n", flags); 443 "(_OSC support mask: 0x%02x)\n", flags);
498 } 444 }
445}
446
447static int acpi_pci_root_add(struct acpi_device *device,
448 const struct acpi_device_id *not_used)
449{
450 unsigned long long segment, bus;
451 acpi_status status;
452 int result;
453 struct acpi_pci_root *root;
454 acpi_handle handle = device->handle;
455 int no_aspm = 0, clear_aspm = 0;
456
457 root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
458 if (!root)
459 return -ENOMEM;
460
461 segment = 0;
462 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL,
463 &segment);
464 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
465 dev_err(&device->dev, "can't evaluate _SEG\n");
466 result = -ENODEV;
467 goto end;
468 }
469
470 /* Check _CRS first, then _BBN. If no _BBN, default to zero. */
471 root->secondary.flags = IORESOURCE_BUS;
472 status = try_get_root_bridge_busnr(handle, &root->secondary);
473 if (ACPI_FAILURE(status)) {
474 /*
475 * We need both the start and end of the downstream bus range
476 * to interpret _CBA (MMCONFIG base address), so it really is
477 * supposed to be in _CRS. If we don't find it there, all we
478 * can do is assume [_BBN-0xFF] or [0-0xFF].
479 */
480 root->secondary.end = 0xFF;
481 dev_warn(&device->dev,
482 FW_BUG "no secondary bus range in _CRS\n");
483 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN,
484 NULL, &bus);
485 if (ACPI_SUCCESS(status))
486 root->secondary.start = bus;
487 else if (status == AE_NOT_FOUND)
488 root->secondary.start = 0;
489 else {
490 dev_err(&device->dev, "can't evaluate _BBN\n");
491 result = -ENODEV;
492 goto end;
493 }
494 }
495
496 root->device = device;
497 root->segment = segment & 0xFFFF;
498 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
499 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
500 device->driver_data = root;
501
502 pr_info(PREFIX "%s [%s] (domain %04x %pR)\n",
503 acpi_device_name(device), acpi_device_bid(device),
504 root->segment, &root->secondary);
505
506 root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle);
507
508 negotiate_os_control(root, &no_aspm, &clear_aspm);
499 509
500 /* 510 /*
501 * TBD: Need PCI interface for enumeration/configuration of roots. 511 * TBD: Need PCI interface for enumeration/configuration of roots.