Skip to content

Commit

Permalink
PCI/ACPI: Allow _OSC presence to be optional for PCI
Browse files Browse the repository at this point in the history
The PCI Firmware Spec, r3.2, sec 4.5.1, says:

  For a host bridge device that originates a PCI Express hierarchy, the
  _OSC interface defined in this section is required.  For a host bridge
  device that originates a PCI/PCI-X bus hierarchy, inclusion of an _OSC
  object is optional.

Allow PCI host bridges to bail out silently if _OSC is not found.

Reported-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Sinan Kaya <okaya@kernel.org>
[bhelgaas: cite PCI Firmware spec, the authoritative source]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
  • Loading branch information
Sinan Kaya authored and Bjorn Helgaas committed Sep 17, 2018
1 parent 1ad61b6 commit c238252
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions drivers/acpi/pci_root.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
}
EXPORT_SYMBOL(acpi_pci_osc_control_set);

static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
bool is_pcie)
{
u32 support, control, requested;
acpi_status status;
Expand Down Expand Up @@ -455,10 +456,15 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
decode_osc_support(root, "OS supports", support);
status = acpi_pci_osc_support(root, support);
if (ACPI_FAILURE(status)) {
*no_aspm = 1;

/* _OSC is optional for PCI host bridges */
if ((status == AE_NOT_FOUND) && !is_pcie)
return;

dev_info(&device->dev, "_OSC failed (%s)%s\n",
acpi_format_exception(status),
pcie_aspm_support_enabled() ? "; disabling ASPM" : "");
*no_aspm = 1;
return;
}

Expand Down Expand Up @@ -534,6 +540,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
acpi_handle handle = device->handle;
int no_aspm = 0;
bool hotadd = system_state == SYSTEM_RUNNING;
bool is_pcie;

root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
if (!root)
Expand Down Expand Up @@ -591,7 +598,8 @@ static int acpi_pci_root_add(struct acpi_device *device,

root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle);

negotiate_os_control(root, &no_aspm);
is_pcie = strcmp(acpi_device_hid(device), "PNP0A08") == 0;
negotiate_os_control(root, &no_aspm, is_pcie);

/*
* TBD: Need PCI interface for enumeration/configuration of roots.
Expand Down

0 comments on commit c238252

Please sign in to comment.