mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-07 08:10:19 -05:00
Merge tag 'acpi-pci-4.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull PCI / ACPI fix from Rafael Wysocki: "This fixes a bug uncovered by a recent driver core change that modified the implementation of the ACPI_COMPANION_SET() macro to strictly rely on its second argument to be either NULL or a valid pointer to struct acpi_device. As it turns out, pcibios_root_bridge_prepare() on x86 and ia64 works with the assumption that the only code path calling pci_create_root_bus() is pci_acpi_scan_root() and therefore the sysdata argument passed to it will always match the expectations of pcibios_root_bridge_prepare(). That need not be the case, however, and in particular it is not the case for the Xen pcifront driver that passes a pointer to its own private data strcture as sysdata to pci_scan_bus_parented() which then passes it to pci_create_root_bus() and it ends up being used incorrectly by pcibios_root_bridge_prepare()" * tag 'acpi-pci-4.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PCI / ACPI: Do not set ACPI companions for host bridges with parents
This commit is contained in:
@@ -478,9 +478,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
|
||||
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||
{
|
||||
struct pci_controller *controller = bridge->bus->sysdata;
|
||||
|
||||
ACPI_COMPANION_SET(&bridge->dev, controller->companion);
|
||||
/*
|
||||
* We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
|
||||
* here, pci_create_root_bus() has been called by someone else and
|
||||
* sysdata is likely to be different from what we expect. Let it go in
|
||||
* that case.
|
||||
*/
|
||||
if (!bridge->dev.parent) {
|
||||
struct pci_controller *controller = bridge->bus->sysdata;
|
||||
ACPI_COMPANION_SET(&bridge->dev, controller->companion);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -482,9 +482,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
|
||||
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||
{
|
||||
struct pci_sysdata *sd = bridge->bus->sysdata;
|
||||
|
||||
ACPI_COMPANION_SET(&bridge->dev, sd->companion);
|
||||
/*
|
||||
* We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
|
||||
* here, pci_create_root_bus() has been called by someone else and
|
||||
* sysdata is likely to be different from what we expect. Let it go in
|
||||
* that case.
|
||||
*/
|
||||
if (!bridge->dev.parent) {
|
||||
struct pci_sysdata *sd = bridge->bus->sysdata;
|
||||
ACPI_COMPANION_SET(&bridge->dev, sd->companion);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user