diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2013-09-05 17:07:41 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-09-23 19:40:46 -0400 |
commit | 3e43abb012d45dc284ef9a0fb0cea0fb004b5607 (patch) | |
tree | d29b259491d921d99d14f701fc403c00dbfe3176 /drivers/acpi | |
parent | 4ffe6e54b0ce259d254e7740a7a4a99dad14a484 (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.c | 132 |
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 | } |
361 | EXPORT_SYMBOL(acpi_pci_osc_control_set); | 361 | EXPORT_SYMBOL(acpi_pci_osc_control_set); |
362 | 362 | ||
363 | static int acpi_pci_root_add(struct acpi_device *device, | 363 | static 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 | |||
447 | static 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. |