if (bridge->release_fn)
bridge->release_fn(bridge);
+
+ pci_free_resource_list(&bridge->windows);
}
static void pci_release_host_bridge_dev(struct device *dev)
{
devm_pci_release_host_bridge_dev(dev);
- pci_free_host_bridge(to_pci_host_bridge(dev));
+ kfree(to_pci_host_bridge(dev));
}
struct pci_host_bridge *pci_alloc_host_bridge(size_t priv)
PCIE_SPEED_2_5GT, /* 1 */
PCIE_SPEED_5_0GT, /* 2 */
PCIE_SPEED_8_0GT, /* 3 */
- PCI_SPEED_UNKNOWN, /* 4 */
+ PCIE_SPEED_16_0GT, /* 4 */
PCI_SPEED_UNKNOWN, /* 5 */
PCI_SPEED_UNKNOWN, /* 6 */
PCI_SPEED_UNKNOWN, /* 7 */
}
}
+static void pci_configure_ltr(struct pci_dev *dev)
+{
+#ifdef CONFIG_PCIEASPM
+ u32 cap;
+ struct pci_dev *bridge;
+
+ if (!pci_is_pcie(dev))
+ return;
+
+ pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
+ if (!(cap & PCI_EXP_DEVCAP2_LTR))
+ return;
+
+ /*
+ * Software must not enable LTR in an Endpoint unless the Root
+ * Complex and all intermediate Switches indicate support for LTR.
+ * PCIe r3.1, sec 6.18.
+ */
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+ dev->ltr_path = 1;
+ else {
+ bridge = pci_upstream_bridge(dev);
+ if (bridge && bridge->ltr_path)
+ dev->ltr_path = 1;
+ }
+
+ if (dev->ltr_path)
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
+ PCI_EXP_DEVCTL2_LTR_EN);
+#endif
+}
+
static void pci_configure_device(struct pci_dev *dev)
{
struct hotplug_params hpp;
pci_configure_mps(dev);
pci_configure_extended_tags(dev, NULL);
pci_configure_relaxed_ordering(dev);
+ pci_configure_ltr(dev);
memset(&hpp, 0, sizeof(hpp));
ret = pci_get_hp_params(dev, &hpp);
static int only_one_child(struct pci_bus *bus)
{
- struct pci_dev *parent = bus->self;
+ struct pci_dev *bridge = bus->self;
- if (!parent || !pci_is_pcie(parent))
+ /*
+ * Systems with unusual topologies set PCI_SCAN_ALL_PCIE_DEVS so
+ * we scan for all possible devices, not just Device 0.
+ */
+ if (pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
return 0;
- if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
- return 1;
/*
- * PCIe downstream ports are bridges that normally lead to only a
- * device 0, but if PCI_SCAN_ALL_PCIE_DEVS is set, scan all
- * possible devices, not just device 0. See PCIe spec r3.0,
- * sec 7.3.1.
+ * A PCIe Downstream Port normally leads to a Link with only Device
+ * 0 on it (PCIe spec r3.1, sec 7.3.1). As an optimization, scan
+ * only for Device 0 in that situation.
+ *
+ * Checking has_secondary_link is a hack to identify Downstream
+ * Ports because sometimes Switches are configured such that the
+ * PCIe Port Type labels are backwards.
*/
- if (parent->has_secondary_link &&
- !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
+ if (bridge && pci_is_pcie(bridge) && bridge->has_secondary_link)
return 1;
+
return 0;
}
for_each_pci_bridge(dev, bus) {
cmax = max;
max = pci_scan_bridge_extend(bus, dev, max, 0, 0);
- used_buses += cmax - max;
+
+ /*
+ * Reserve one bus for each bridge now to avoid extending
+ * hotplug bridges too much during the second scan below.
+ */
+ used_buses++;
+ if (cmax - max > 1)
+ used_buses += cmax - max - 1;
}
/* Scan bridges that need to be reconfigured */
* bridges if any.
*/
buses = available_buses / hotplug_bridges;
- buses = min(buses, available_buses - used_buses);
+ buses = min(buses, available_buses - used_buses + 1);
}
cmax = max;
max = pci_scan_bridge_extend(bus, dev, cmax, buses, 1);
- used_buses += max - cmax;
+ /* One bus is already accounted so don't add it again */
+ if (max - cmax > 1)
+ used_buses += max - cmax - 1;
}
/*