PCI: acpiphp: Avoid setting is_hotplug_bridge for PCIe Upstream Ports
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 21 Nov 2022 18:16:57 +0000 (19:16 +0100)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 22 Nov 2022 19:27:28 +0000 (13:27 -0600)
commitc63a3be76df678b173c59f1d5dc19a21b2d1c753
tree94a9f14fd722ae04f7437a9a59affd81aaab5039
parent05f5747414c6ecb8a7f9b0c1dc10bcffa6dfb5ba
PCI: acpiphp: Avoid setting is_hotplug_bridge for PCIe Upstream Ports

It is reported that on some systems pciehp binds to an Upstream Port and
attempts to operate it which causes devices below the Port to disappear
from the bus.

This happens because acpiphp sets dev->is_hotplug_bridge for that Port
(after receiving a Device Check notification on it from the platform
firmware via ACPI) during the enumeration of PCI devices.

get_port_device_capability() sees that dev->is_hotplug_bridge is set and
adds PCIE_PORT_SERVICE_HP to Port services, which allows pciehp to bind to
the Port in question.

Even though this particular problem can be addressed by making the
portdrv_core checks more robust, it also causes power management to work
differently on the affected systems which generally is not desirable (PCIe
Ports with dev->is_hotplug_bridge set have to pass additional tests to be
allowed to go into the D3hot/cold power states which affects runtime PM of
devices below these Ports).

For this reason, amend check_hotplug_bridge() with a PCIe type check to
prevent it from setting dev->is_hotplug_bridge for Upstream Ports.

Suggested-by: Lukas Wunner <lukas@wunner.de>
Link: https://lore.kernel.org/r/2262230.ElGaqSPkdT@kreacher
Reported-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Tested-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
drivers/pci/hotplug/acpiphp_glue.c