Skip to content

Commit 0e14288

Browse files
committed
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
2 parents fc9a7d3 + c2f9de5 commit 0e14288

7 files changed

Lines changed: 25 additions & 15 deletions

File tree

drivers/pci/hotplug/pciehp_hpc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@ static inline int pcie_hotplug_depth(struct pci_dev *dev)
995995

996996
while (bus->parent) {
997997
bus = bus->parent;
998-
if (bus->self && bus->self->is_hotplug_bridge)
998+
if (bus->self && bus->self->is_pciehp)
999999
depth++;
10001000
}
10011001

drivers/pci/pci-acpi.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -816,15 +816,10 @@ int pci_acpi_program_hp_params(struct pci_dev *dev)
816816
bool pciehp_is_native(struct pci_dev *bridge)
817817
{
818818
const struct pci_host_bridge *host;
819-
u32 slot_cap;
820819

821820
if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
822821
return false;
823822

824-
pcie_capability_read_dword(bridge, PCI_EXP_SLTCAP, &slot_cap);
825-
if (!(slot_cap & PCI_EXP_SLTCAP_HPC))
826-
return false;
827-
828823
if (pcie_ports_native)
829824
return true;
830825

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

1005-
if (acpi_pci_disabled || !dev->is_hotplug_bridge)
1000+
if (acpi_pci_disabled || !dev->is_pciehp)
10061001
return false;
10071002

10081003
adev = ACPI_COMPANION(&dev->dev);

drivers/pci/pci.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,8 +3030,12 @@ static const struct dmi_system_id bridge_d3_blacklist[] = {
30303030
* pci_bridge_d3_possible - Is it possible to put the bridge into D3
30313031
* @bridge: Bridge to check
30323032
*
3033-
* This function checks if it is possible to move the bridge to D3.
30343033
* Currently we only allow D3 for some PCIe ports and for Thunderbolt.
3034+
*
3035+
* Return: Whether it is possible to move the bridge to D3.
3036+
*
3037+
* The return value is guaranteed to be constant across the entire lifetime
3038+
* of the bridge, including its hot-removal.
30353039
*/
30363040
bool pci_bridge_d3_possible(struct pci_dev *bridge)
30373041
{
@@ -3046,10 +3050,14 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge)
30463050
return false;
30473051

30483052
/*
3049-
* Hotplug ports handled by firmware in System Management Mode
3050-
* may not be put into D3 by the OS (Thunderbolt on non-Macs).
3053+
* Hotplug ports handled by platform firmware may not be put
3054+
* into D3 by the OS, e.g. ACPI slots ...
30513055
*/
3052-
if (bridge->is_hotplug_bridge && !pciehp_is_native(bridge))
3056+
if (bridge->is_hotplug_bridge && !bridge->is_pciehp)
3057+
return false;
3058+
3059+
/* ... or PCIe hotplug ports not handled natively by the OS. */
3060+
if (bridge->is_pciehp && !pciehp_is_native(bridge))
30533061
return false;
30543062

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

30743082
if (dmi_check_system(bridge_d3_blacklist))

drivers/pci/pcie/portdrv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ static int get_port_device_capability(struct pci_dev *dev)
220220
struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
221221
int services = 0;
222222

223-
if (dev->is_hotplug_bridge &&
223+
if (dev->is_pciehp &&
224224
(pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
225225
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) &&
226226
(pcie_ports_native || host->native_pcie_hotplug)) {

drivers/pci/probe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1678,7 +1678,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)
16781678

16791679
pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32);
16801680
if (reg32 & PCI_EXP_SLTCAP_HPC)
1681-
pdev->is_hotplug_bridge = 1;
1681+
pdev->is_hotplug_bridge = pdev->is_pciehp = 1;
16821682
}
16831683

16841684
static void set_pcie_thunderbolt(struct pci_dev *dev)

include/linux/pci.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,11 @@ struct rcec_ea;
328328
* determined (e.g., for Root Complex Integrated
329329
* Endpoints without the relevant Capability
330330
* Registers).
331+
* @is_hotplug_bridge: Hotplug bridge of any kind (e.g. PCIe Hot-Plug Capable,
332+
* Conventional PCI Hot-Plug, ACPI slot).
333+
* Such bridges are allocated additional MMIO and bus
334+
* number resources to allow for hierarchy expansion.
335+
* @is_pciehp: PCIe Hot-Plug Capable bridge.
331336
*/
332337
struct pci_dev {
333338
struct list_head bus_list; /* Node in per-bus list */
@@ -451,6 +456,7 @@ struct pci_dev {
451456
unsigned int is_physfn:1;
452457
unsigned int is_virtfn:1;
453458
unsigned int is_hotplug_bridge:1;
459+
unsigned int is_pciehp:1;
454460
unsigned int shpc_managed:1; /* SHPC owned by shpchp */
455461
unsigned int is_thunderbolt:1; /* Thunderbolt controller */
456462
/*

include/linux/pci_hotplug.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ static inline bool shpchp_is_native(struct pci_dev *bridge) { return true; }
104104

105105
static inline bool hotplug_is_native(struct pci_dev *bridge)
106106
{
107-
return pciehp_is_native(bridge) || shpchp_is_native(bridge);
107+
return (bridge->is_pciehp && pciehp_is_native(bridge)) ||
108+
shpchp_is_native(bridge);
108109
}
109110
#endif

0 commit comments

Comments
 (0)