Commit 0e142889 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/hotplug'

- Fix runtime PM ref imbalance on Hot-Plug Capable ports caused by
  misinterpreting a config read failure after a device has been removed
  (Lukas Wunner)

- Avoid creating a useless PCIe port service device for pciehp if the slot
  is handled by the ACPI hotplug driver (Lukas Wunner)

- Ignore ACPI hotplug slots when calculating depth of pciehp hotplug ports
  (Lukas Wunner)

- Simplify pci_bridge_d3_possible() and clarify comments (Lukas Wunner)

* pci/hotplug:
  PCI: Move is_pciehp check out of pciehp_is_native()
  PCI: pciehp: Use is_pciehp instead of is_hotplug_bridge
  PCI/portdrv: Use is_pciehp instead of is_hotplug_bridge
  PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports
parents fc9a7d38 c2f9de5e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -995,7 +995,7 @@ static inline int pcie_hotplug_depth(struct pci_dev *dev)

	while (bus->parent) {
		bus = bus->parent;
		if (bus->self && bus->self->is_hotplug_bridge)
		if (bus->self && bus->self->is_pciehp)
			depth++;
	}

+1 −6
Original line number Diff line number Diff line
@@ -816,15 +816,10 @@ int pci_acpi_program_hp_params(struct pci_dev *dev)
bool pciehp_is_native(struct pci_dev *bridge)
{
	const struct pci_host_bridge *host;
	u32 slot_cap;

	if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
		return false;

	pcie_capability_read_dword(bridge, PCI_EXP_SLTCAP, &slot_cap);
	if (!(slot_cap & PCI_EXP_SLTCAP_HPC))
		return false;

	if (pcie_ports_native)
		return true;

@@ -1002,7 +997,7 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev)
	struct acpi_device *adev, *rpadev;
	const union acpi_object *obj;

	if (acpi_pci_disabled || !dev->is_hotplug_bridge)
	if (acpi_pci_disabled || !dev->is_pciehp)
		return false;

	adev = ACPI_COMPANION(&dev->dev);
+13 −5
Original line number Diff line number Diff line
@@ -3030,8 +3030,12 @@ static const struct dmi_system_id bridge_d3_blacklist[] = {
 * pci_bridge_d3_possible - Is it possible to put the bridge into D3
 * @bridge: Bridge to check
 *
 * This function checks if it is possible to move the bridge to D3.
 * Currently we only allow D3 for some PCIe ports and for Thunderbolt.
 *
 * Return: Whether it is possible to move the bridge to D3.
 *
 * The return value is guaranteed to be constant across the entire lifetime
 * of the bridge, including its hot-removal.
 */
bool pci_bridge_d3_possible(struct pci_dev *bridge)
{
@@ -3046,10 +3050,14 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge)
			return false;

		/*
		 * Hotplug ports handled by firmware in System Management Mode
		 * may not be put into D3 by the OS (Thunderbolt on non-Macs).
		 * Hotplug ports handled by platform firmware may not be put
		 * into D3 by the OS, e.g. ACPI slots ...
		 */
		if (bridge->is_hotplug_bridge && !pciehp_is_native(bridge))
		if (bridge->is_hotplug_bridge && !bridge->is_pciehp)
			return false;

		/* ... or PCIe hotplug ports not handled natively by the OS. */
		if (bridge->is_pciehp && !pciehp_is_native(bridge))
			return false;

		if (pci_bridge_d3_force)
@@ -3068,7 +3076,7 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge)
		 * by vendors for runtime D3 at least until 2018 because there
		 * was no OS support.
		 */
		if (bridge->is_hotplug_bridge)
		if (bridge->is_pciehp)
			return false;

		if (dmi_check_system(bridge_d3_blacklist))
+1 −1
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ static int get_port_device_capability(struct pci_dev *dev)
	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
	int services = 0;

	if (dev->is_hotplug_bridge &&
	if (dev->is_pciehp &&
	    (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
	     pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) &&
	    (pcie_ports_native || host->native_pcie_hotplug)) {
+1 −1
Original line number Diff line number Diff line
@@ -1678,7 +1678,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)

	pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32);
	if (reg32 & PCI_EXP_SLTCAP_HPC)
		pdev->is_hotplug_bridge = 1;
		pdev->is_hotplug_bridge = pdev->is_pciehp = 1;
}

static void set_pcie_thunderbolt(struct pci_dev *dev)
Loading