diff options
author | Taku Izumi <izumi.taku@jp.fujitsu.com> | 2012-10-30 02:27:13 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-11-07 11:58:46 -0500 |
commit | 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6 (patch) | |
tree | a9d52e96f6e269b5d19f1241fc04e61cd22c82c4 /drivers/acpi | |
parent | 642c92da36ae0bed3c31fdd408411ab95f4e326b (diff) |
PCI/ACPI: Request _OSC control before scanning PCI root bus
This patch moves up the code block to request _OSC control in order to
separate ACPI work and PCI work in acpi_pci_root_add().
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/pci_root.c | 121 |
1 files changed, 62 insertions, 59 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 50f329d7ccff..ab781f00e32d 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -454,6 +454,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
454 | acpi_handle handle; | 454 | acpi_handle handle; |
455 | struct acpi_device *child; | 455 | struct acpi_device *child; |
456 | u32 flags, base_flags; | 456 | u32 flags, base_flags; |
457 | bool is_osc_granted = false; | ||
457 | 458 | ||
458 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 459 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
459 | if (!root) | 460 | if (!root) |
@@ -524,6 +525,60 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
524 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | 525 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
525 | acpi_pci_osc_support(root, flags); | 526 | acpi_pci_osc_support(root, flags); |
526 | 527 | ||
528 | /* Indicate support for various _OSC capabilities. */ | ||
529 | if (pci_ext_cfg_avail()) | ||
530 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; | ||
531 | if (pcie_aspm_support_enabled()) { | ||
532 | flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | | ||
533 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; | ||
534 | } | ||
535 | if (pci_msi_enabled()) | ||
536 | flags |= OSC_MSI_SUPPORT; | ||
537 | if (flags != base_flags) { | ||
538 | status = acpi_pci_osc_support(root, flags); | ||
539 | if (ACPI_FAILURE(status)) { | ||
540 | dev_info(&device->dev, "ACPI _OSC support " | ||
541 | "notification failed, disabling PCIe ASPM\n"); | ||
542 | pcie_no_aspm(); | ||
543 | flags = base_flags; | ||
544 | } | ||
545 | } | ||
546 | if (!pcie_ports_disabled | ||
547 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { | ||
548 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | ||
549 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
550 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
551 | |||
552 | if (pci_aer_available()) { | ||
553 | if (aer_acpi_firmware_first()) | ||
554 | dev_dbg(&device->dev, | ||
555 | "PCIe errors handled by BIOS.\n"); | ||
556 | else | ||
557 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
558 | } | ||
559 | |||
560 | dev_info(&device->dev, | ||
561 | "Requesting ACPI _OSC control (0x%02x)\n", flags); | ||
562 | |||
563 | status = acpi_pci_osc_control_set(device->handle, &flags, | ||
564 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
565 | if (ACPI_SUCCESS(status)) { | ||
566 | is_osc_granted = true; | ||
567 | dev_info(&device->dev, | ||
568 | "ACPI _OSC control (0x%02x) granted\n", flags); | ||
569 | } else { | ||
570 | is_osc_granted = false; | ||
571 | dev_info(&device->dev, | ||
572 | "ACPI _OSC request failed (%s), " | ||
573 | "returned control mask: 0x%02x\n", | ||
574 | acpi_format_exception(status), flags); | ||
575 | } | ||
576 | } else { | ||
577 | dev_info(&device->dev, | ||
578 | "Unable to request _OSC control " | ||
579 | "(_OSC support mask: 0x%02x)\n", flags); | ||
580 | } | ||
581 | |||
527 | /* | 582 | /* |
528 | * TBD: Need PCI interface for enumeration/configuration of roots. | 583 | * TBD: Need PCI interface for enumeration/configuration of roots. |
529 | */ | 584 | */ |
@@ -563,66 +618,14 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
563 | list_for_each_entry(child, &device->children, node) | 618 | list_for_each_entry(child, &device->children, node) |
564 | acpi_pci_bridge_scan(child); | 619 | acpi_pci_bridge_scan(child); |
565 | 620 | ||
566 | /* Indicate support for various _OSC capabilities. */ | 621 | /* ASPM setting */ |
567 | if (pci_ext_cfg_avail()) | 622 | if (is_osc_granted) { |
568 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; | 623 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) |
569 | if (pcie_aspm_support_enabled()) | 624 | pcie_clear_aspm(root->bus); |
570 | flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | | ||
571 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; | ||
572 | if (pci_msi_enabled()) | ||
573 | flags |= OSC_MSI_SUPPORT; | ||
574 | if (flags != base_flags) { | ||
575 | status = acpi_pci_osc_support(root, flags); | ||
576 | if (ACPI_FAILURE(status)) { | ||
577 | dev_info(root->bus->bridge, "ACPI _OSC support " | ||
578 | "notification failed, disabling PCIe ASPM\n"); | ||
579 | pcie_no_aspm(); | ||
580 | flags = base_flags; | ||
581 | } | ||
582 | } | ||
583 | |||
584 | if (!pcie_ports_disabled | ||
585 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { | ||
586 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | ||
587 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
588 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
589 | |||
590 | if (pci_aer_available()) { | ||
591 | if (aer_acpi_firmware_first()) | ||
592 | dev_dbg(root->bus->bridge, | ||
593 | "PCIe errors handled by BIOS.\n"); | ||
594 | else | ||
595 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
596 | } | ||
597 | |||
598 | dev_info(root->bus->bridge, | ||
599 | "Requesting ACPI _OSC control (0x%02x)\n", flags); | ||
600 | |||
601 | status = acpi_pci_osc_control_set(device->handle, &flags, | ||
602 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
603 | if (ACPI_SUCCESS(status)) { | ||
604 | dev_info(root->bus->bridge, | ||
605 | "ACPI _OSC control (0x%02x) granted\n", flags); | ||
606 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { | ||
607 | /* | ||
608 | * We have ASPM control, but the FADT indicates | ||
609 | * that it's unsupported. Clear it. | ||
610 | */ | ||
611 | pcie_clear_aspm(root->bus); | ||
612 | } | ||
613 | } else { | ||
614 | dev_info(root->bus->bridge, | ||
615 | "ACPI _OSC request failed (%s), " | ||
616 | "returned control mask: 0x%02x\n", | ||
617 | acpi_format_exception(status), flags); | ||
618 | pr_info("ACPI _OSC control for PCIe not granted, " | ||
619 | "disabling ASPM\n"); | ||
620 | pcie_no_aspm(); | ||
621 | } | ||
622 | } else { | 625 | } else { |
623 | dev_info(root->bus->bridge, | 626 | pr_info("ACPI _OSC control for PCIe not granted, " |
624 | "Unable to request _OSC control " | 627 | "disabling ASPM\n"); |
625 | "(_OSC support mask: 0x%02x)\n", flags); | 628 | pcie_no_aspm(); |
626 | } | 629 | } |
627 | 630 | ||
628 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 631 | pci_acpi_add_bus_pm_notifier(device, root->bus); |