]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/pci/pci.c
Merge tag 'pci-v4.18-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaa...
[linux.git] / drivers / pci / pci.c
index e90cf5c32e1432d378692d8392e9d07fe55a46b2..97acba712e4e7f7191df5fd7ae7800597dc94fd5 100644 (file)
@@ -112,6 +112,14 @@ unsigned int pcibios_max_latency = 255;
 /* If set, the PCIe ARI capability will not be used. */
 static bool pcie_ari_disabled;
 
+/* If set, the PCIe ATS capability will not be used. */
+static bool pcie_ats_disabled;
+
+bool pci_ats_disabled(void)
+{
+       return pcie_ats_disabled;
+}
+
 /* Disable bridge_d3 for all PCIe ports */
 static bool pci_bridge_d3_disable;
 /* Force bridge_d3 for all PCIe ports */
@@ -4153,6 +4161,35 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
 
        return pci_dev_wait(dev, "PM D3->D0", PCIE_RESET_READY_POLL_MS);
 }
+/**
+ * pcie_wait_for_link - Wait until link is active or inactive
+ * @pdev: Bridge device
+ * @active: waiting for active or inactive?
+ *
+ * Use this to wait till link becomes active or inactive.
+ */
+bool pcie_wait_for_link(struct pci_dev *pdev, bool active)
+{
+       int timeout = 1000;
+       bool ret;
+       u16 lnk_status;
+
+       for (;;) {
+               pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
+               ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
+               if (ret == active)
+                       return true;
+               if (timeout <= 0)
+                       break;
+               msleep(10);
+               timeout -= 10;
+       }
+
+       pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n",
+                active ? "set" : "cleared");
+
+       return false;
+}
 
 void pci_reset_secondary_bus(struct pci_dev *dev)
 {
@@ -5084,49 +5121,6 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
 }
 EXPORT_SYMBOL(pcie_set_mps);
 
-/**
- * pcie_get_minimum_link - determine minimum link settings of a PCI device
- * @dev: PCI device to query
- * @speed: storage for minimum speed
- * @width: storage for minimum width
- *
- * This function will walk up the PCI device chain and determine the minimum
- * link width and speed of the device.
- */
-int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
-                         enum pcie_link_width *width)
-{
-       int ret;
-
-       *speed = PCI_SPEED_UNKNOWN;
-       *width = PCIE_LNK_WIDTH_UNKNOWN;
-
-       while (dev) {
-               u16 lnksta;
-               enum pci_bus_speed next_speed;
-               enum pcie_link_width next_width;
-
-               ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
-               if (ret)
-                       return ret;
-
-               next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
-               next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
-                       PCI_EXP_LNKSTA_NLW_SHIFT;
-
-               if (next_speed < *speed)
-                       *speed = next_speed;
-
-               if (next_width < *width)
-                       *width = next_width;
-
-               dev = dev->bus->self;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(pcie_get_minimum_link);
-
 /**
  * pcie_bandwidth_available - determine minimum link settings of a PCIe
  *                           device and its bandwidth limitation
@@ -5717,15 +5711,14 @@ static void pci_no_domains(void)
 #endif
 }
 
-#ifdef CONFIG_PCI_DOMAINS
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
 static atomic_t __domain_nr = ATOMIC_INIT(-1);
 
-int pci_get_new_domain_nr(void)
+static int pci_get_new_domain_nr(void)
 {
        return atomic_inc_return(&__domain_nr);
 }
 
-#ifdef CONFIG_PCI_DOMAINS_GENERIC
 static int of_pci_bus_find_domain_nr(struct device *parent)
 {
        static int use_dt_domains = -1;
@@ -5780,7 +5773,6 @@ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
                               acpi_pci_bus_find_domain_nr(bus);
 }
 #endif
-#endif
 
 /**
  * pci_ext_cfg_avail - can we access extended PCI config space?
@@ -5808,6 +5800,9 @@ static int __init pci_setup(char *str)
                if (*str && (str = pcibios_setup(str)) && *str) {
                        if (!strcmp(str, "nomsi")) {
                                pci_no_msi();
+                       } else if (!strncmp(str, "noats", 5)) {
+                               pr_info("PCIe: ATS is disabled\n");
+                               pcie_ats_disabled = true;
                        } else if (!strcmp(str, "noaer")) {
                                pci_no_aer();
                        } else if (!strncmp(str, "realloc=", 8)) {