mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-11 12:44:49 -04:00
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
This commit is contained in:
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -1678,7 +1678,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)
|
||||
|
||||
pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32);
|
||||
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)
|
||||
|
||||
@@ -328,6 +328,11 @@ struct rcec_ea;
|
||||
* determined (e.g., for Root Complex Integrated
|
||||
* Endpoints without the relevant Capability
|
||||
* Registers).
|
||||
* @is_hotplug_bridge: Hotplug bridge of any kind (e.g. PCIe Hot-Plug Capable,
|
||||
* Conventional PCI Hot-Plug, ACPI slot).
|
||||
* Such bridges are allocated additional MMIO and bus
|
||||
* number resources to allow for hierarchy expansion.
|
||||
* @is_pciehp: PCIe Hot-Plug Capable bridge.
|
||||
*/
|
||||
struct pci_dev {
|
||||
struct list_head bus_list; /* Node in per-bus list */
|
||||
@@ -451,6 +456,7 @@ struct pci_dev {
|
||||
unsigned int is_physfn:1;
|
||||
unsigned int is_virtfn:1;
|
||||
unsigned int is_hotplug_bridge:1;
|
||||
unsigned int is_pciehp:1;
|
||||
unsigned int shpc_managed:1; /* SHPC owned by shpchp */
|
||||
unsigned int is_thunderbolt:1; /* Thunderbolt controller */
|
||||
/*
|
||||
|
||||
@@ -104,6 +104,7 @@ static inline bool shpchp_is_native(struct pci_dev *bridge) { return true; }
|
||||
|
||||
static inline bool hotplug_is_native(struct pci_dev *bridge)
|
||||
{
|
||||
return pciehp_is_native(bridge) || shpchp_is_native(bridge);
|
||||
return (bridge->is_pciehp && pciehp_is_native(bridge)) ||
|
||||
shpchp_is_native(bridge);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user