Message ID | 5729439.MhkbZ0Pkbq@kreacher |
---|---|
State | New |
Headers | show |
Series | ACPI: PCI: PM: Power up PCI devices with ACPI companions upfront | expand |
On Mon, Apr 04, 2022 at 05:25:04PM +0200, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > The initial configuration of ACPI power resources on some systems > implies that some PCI devices on them are initially in D3cold. > > In some cases, especially for PCIe Root Ports, this is a "logical" > D3cold, meaning that the configuration space of the device is > accessible, but some of its functionality may be missing, but it > very well may be real D3cold, in which case the device will not > be accessible at all. However, the PCI bus type driver will need > to access its configuration space in order to enumerate it. > > To prevent possible device enumeration failures that may ensue as > a result of ACPI power resources being initially in the "off" > state, power up all children of the host bridge ACPI device object > that hold valid _ADR objects (which indicates that they will be > enumerated by the PCI bus type driver) and do that to all children > of the ACPI device objects corresponding to PCI bridges (including > PCIe ports). > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> > --- > drivers/acpi/pci_root.c | 2 ++ > drivers/pci/pci-acpi.c | 3 +++ > 2 files changed, 5 insertions(+) > > Index: linux-pm/drivers/acpi/pci_root.c > =================================================================== > --- linux-pm.orig/drivers/acpi/pci_root.c > +++ linux-pm/drivers/acpi/pci_root.c > @@ -927,6 +927,8 @@ struct pci_bus *acpi_pci_root_create(str > host_bridge->preserve_config = 1; > ACPI_FREE(obj); > > + acpi_dev_power_up_children_with_adr(device); > + > pci_scan_child_bus(bus); > pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info, > info); > Index: linux-pm/drivers/pci/pci-acpi.c > =================================================================== > --- linux-pm.orig/drivers/pci/pci-acpi.c > +++ linux-pm/drivers/pci/pci-acpi.c > @@ -1374,6 +1374,9 @@ void pci_acpi_setup(struct device *dev, > > acpi_pci_wakeup(pci_dev, false); > acpi_device_power_add_dependent(adev, dev); > + > + if (pci_is_bridge(pci_dev)) > + acpi_dev_power_up_children_with_adr(adev); > } > > void pci_acpi_cleanup(struct device *dev, struct acpi_device *adev) > > >
Index: linux-pm/drivers/acpi/pci_root.c =================================================================== --- linux-pm.orig/drivers/acpi/pci_root.c +++ linux-pm/drivers/acpi/pci_root.c @@ -927,6 +927,8 @@ struct pci_bus *acpi_pci_root_create(str host_bridge->preserve_config = 1; ACPI_FREE(obj); + acpi_dev_power_up_children_with_adr(device); + pci_scan_child_bus(bus); pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info, info); Index: linux-pm/drivers/pci/pci-acpi.c =================================================================== --- linux-pm.orig/drivers/pci/pci-acpi.c +++ linux-pm/drivers/pci/pci-acpi.c @@ -1374,6 +1374,9 @@ void pci_acpi_setup(struct device *dev, acpi_pci_wakeup(pci_dev, false); acpi_device_power_add_dependent(adev, dev); + + if (pci_is_bridge(pci_dev)) + acpi_dev_power_up_children_with_adr(adev); } void pci_acpi_cleanup(struct device *dev, struct acpi_device *adev)