Skip to content

Commit

Permalink
PCI / ACPI: Make acpiphp ignore root bridges using PCIe native hotplug
Browse files Browse the repository at this point in the history
If the kernel has requested control of the PCIe native hotplug
feature for a given root complex, the acpiphp driver should not try
to handle that root complex and it should leave it to pciehp.
Failing to do so causes problems to happen if acpiphp is loaded
before pciehp on such systems.

To address this issue make find_root_bridges() ignore PCIe root
complexes with PCIe native hotplug enabled and make add_bridge()
return error code if PCIe native hotplug is enabled for the given
root port.  This causes acpiphp to refuse to load if PCIe native
hotplug is enabled for all complexes and to refuse binding to
the root complexes with PCIe native hotplug is enabled.

Acked-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
  • Loading branch information
Rafael J. Wysocki authored and Jesse Barnes committed Oct 31, 2011
1 parent 839d881 commit 0d52f54
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions drivers/pci/hotplug/acpiphp_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle)
{
acpi_status status;
unsigned long long tmp;
struct acpi_pci_root *root;
acpi_handle dummy_handle;

/*
* We shouldn't use this bridge if PCIe native hotplug control has been
* granted by the BIOS for it.
*/
root = acpi_pci_find_root(handle);
if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
return -ENODEV;

/* if the bridge doesn't have _STA, we assume it is always there */
status = acpi_get_handle(handle, "_STA", &dummy_handle);
if (ACPI_SUCCESS(status)) {
Expand Down Expand Up @@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
static acpi_status
find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
{
struct acpi_pci_root *root;
int *count = (int *)context;

if (acpi_is_root_bridge(handle)) {
acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
handle_hotplug_event_bridge, NULL);
(*count)++;
}
if (!acpi_is_root_bridge(handle))
return AE_OK;

root = acpi_pci_find_root(handle);
if (!root)
return AE_OK;

if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
return AE_OK;

(*count)++;
acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
handle_hotplug_event_bridge, NULL);

return AE_OK ;
}

Expand Down

0 comments on commit 0d52f54

Please sign in to comment.