Merge branch 'pci/hotplug'

- Allow D3 only if Root Port can signal and wake from D3 so we don't miss
  hotplug events on AMD Yellow Carp (Mario Limonciello)

- Clean up hotplug include files to enable future powerpc cleanup
  (Christophe Leroy)

* pci/hotplug:
  PCI: hotplug: Clean up include files
  PCI/ACPI: Allow D3 only if Root Port can signal and wake from D3
This commit is contained in:
Bjorn Helgaas 2022-05-24 16:42:21 -05:00
commit 85ae3970a0
6 changed files with 36 additions and 11 deletions

View File

@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <linux/of_fdt.h>
#include <asm/opal.h>
#include <asm/pnv-pci.h>

View File

@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/vmalloc.h>

View File

@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/of.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <linux/smp.h>
@ -20,6 +21,7 @@
#include <asm/eeh.h> /* for eeh_add_device() */
#include <asm/rtas.h> /* rtas_call */
#include <asm/pci-bridge.h> /* for pci_controller */
#include <asm/prom.h>
#include "../pci.h" /* for pci_add_new_bus */
/* and pci_do_scan_bus */
#include "rpaphp.h"

View File

@ -8,6 +8,7 @@
* Send feedback to <lxie@us.ibm.com>
*
*/
#include <linux/of.h>
#include <linux/pci.h>
#include <linux/string.h>

View File

@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sysfs.h>
#include <linux/of.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/slab.h>

View File

@ -974,9 +974,11 @@ bool acpi_pci_power_manageable(struct pci_dev *dev)
bool acpi_pci_bridge_d3(struct pci_dev *dev)
{
const union acpi_object *obj;
struct acpi_device *adev;
struct pci_dev *rpdev;
struct acpi_device *adev;
acpi_status status;
unsigned long long state;
const union acpi_object *obj;
if (acpi_pci_disabled || !dev->is_hotplug_bridge)
return false;
@ -985,12 +987,6 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev)
if (acpi_pci_power_manageable(dev))
return true;
/*
* The ACPI firmware will provide the device-specific properties through
* _DSD configuration object. Look for the 'HotPlugSupportInD3' property
* for the root port and if it is set we know the hierarchy behind it
* supports D3 just fine.
*/
rpdev = pcie_find_root_port(dev);
if (!rpdev)
return false;
@ -999,11 +995,34 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev)
if (!adev)
return false;
if (acpi_dev_get_property(adev, "HotPlugSupportInD3",
ACPI_TYPE_INTEGER, &obj) < 0)
/*
* If the Root Port cannot signal wakeup signals at all, i.e., it
* doesn't supply a wakeup GPE via _PRW, it cannot signal hotplug
* events from low-power states including D3hot and D3cold.
*/
if (!adev->wakeup.flags.valid)
return false;
return obj->integer.value == 1;
/*
* If the Root Port cannot wake itself from D3hot or D3cold, we
* can't use D3.
*/
status = acpi_evaluate_integer(adev->handle, "_S0W", NULL, &state);
if (ACPI_SUCCESS(status) && state < ACPI_STATE_D3_HOT)
return false;
/*
* The "HotPlugSupportInD3" property in a Root Port _DSD indicates
* the Port can signal hotplug events while in D3. We assume any
* bridges *below* that Root Port can also signal hotplug events
* while in D3.
*/
if (!acpi_dev_get_property(adev, "HotPlugSupportInD3",
ACPI_TYPE_INTEGER, &obj) &&
obj->integer.value == 1)
return true;
return false;
}
int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)