Merge tag 'libnvdimm-for-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm...
[cascardo/linux.git] / drivers / pci / probe.c
index 8ed37dd..0b2be17 100644 (file)
@@ -660,6 +660,35 @@ static void pci_set_bus_speed(struct pci_bus *bus)
        }
 }
 
+static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
+{
+       struct irq_domain *d;
+
+       /*
+        * Any firmware interface that can resolve the msi_domain
+        * should be called from here.
+        */
+       d = pci_host_bridge_of_msi_domain(bus);
+
+       return d;
+}
+
+static void pci_set_bus_msi_domain(struct pci_bus *bus)
+{
+       struct irq_domain *d;
+
+       /*
+        * Either bus is the root, and we must obtain it from the
+        * firmware, or we inherit it from the bridge device.
+        */
+       if (pci_is_root_bus(bus))
+               d = pci_host_bridge_msi_domain(bus);
+       else
+               d = dev_get_msi_domain(&bus->self->dev);
+
+       dev_set_msi_domain(&bus->dev, d);
+}
+
 static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
                                           struct pci_dev *bridge, int busnr)
 {
@@ -713,6 +742,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
        bridge->subordinate = child;
 
 add_dev:
+       pci_set_bus_msi_domain(child);
        ret = device_register(&child->dev);
        WARN_ON(ret < 0);
 
@@ -825,6 +855,9 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
                        child->bridge_ctl = bctl;
                }
 
+               /* Read and initialize bridge resources */
+               pci_read_bridge_bases(child);
+
                cmax = pci_scan_child_bus(child);
                if (cmax > subordinate)
                        dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
@@ -885,6 +918,9 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
 
                if (!is_cardbus) {
                        child->bridge_ctl = bctl;
+
+                       /* Read and initialize bridge resources */
+                       pci_read_bridge_bases(child);
                        max = pci_scan_child_bus(child);
                } else {
                        /*
@@ -996,7 +1032,12 @@ void set_pcie_port_type(struct pci_dev *pdev)
        else if (type == PCI_EXP_TYPE_UPSTREAM ||
                 type == PCI_EXP_TYPE_DOWNSTREAM) {
                parent = pci_upstream_bridge(pdev);
-               if (!parent->has_secondary_link)
+
+               /*
+                * Usually there's an upstream device (Root Port or Switch
+                * Downstream Port), but we can't assume one exists.
+                */
+               if (parent && !parent->has_secondary_link)
                        pdev->has_secondary_link = 1;
        }
 }
@@ -1102,7 +1143,7 @@ int pci_cfg_space_size(struct pci_dev *dev)
 
 #define LEGACY_IO_RESOURCE     (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
 
-static void pci_msi_setup_pci_dev(struct pci_dev *dev)
+void pci_msi_setup_pci_dev(struct pci_dev *dev)
 {
        /*
         * Disable the MSI hardware to avoid screaming interrupts
@@ -1132,7 +1173,6 @@ int pci_setup_device(struct pci_dev *dev)
 {
        u32 class;
        u8 hdr_type;
-       struct pci_slot *slot;
        int pos = 0;
        struct pci_bus_region region;
        struct resource *res;
@@ -1148,10 +1188,7 @@ int pci_setup_device(struct pci_dev *dev)
        dev->error_state = pci_channel_io_normal;
        set_pcie_port_type(dev);
 
-       list_for_each_entry(slot, &dev->bus->slots, list)
-               if (PCI_SLOT(dev->devfn) == slot->number)
-                       dev->slot = slot;
-
+       pci_dev_assign_slot(dev);
        /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
           set this higher, assuming the system even supports it.  */
        dev->dma_mask = 0xffffffff;
@@ -1267,13 +1304,51 @@ int pci_setup_device(struct pci_dev *dev)
        bad:
                dev_err(&dev->dev, "ignoring class %#08x (doesn't match header type %02x)\n",
                        dev->class, dev->hdr_type);
-               dev->class = PCI_CLASS_NOT_DEFINED;
+               dev->class = PCI_CLASS_NOT_DEFINED << 8;
        }
 
        /* We found a fine healthy device, go go go... */
        return 0;
 }
 
+static void pci_configure_mps(struct pci_dev *dev)
+{
+       struct pci_dev *bridge = pci_upstream_bridge(dev);
+       int mps, p_mps, rc;
+
+       if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge))
+               return;
+
+       mps = pcie_get_mps(dev);
+       p_mps = pcie_get_mps(bridge);
+
+       if (mps == p_mps)
+               return;
+
+       if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
+               dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+                        mps, pci_name(bridge), p_mps);
+               return;
+       }
+
+       /*
+        * Fancier MPS configuration is done later by
+        * pcie_bus_configure_settings()
+        */
+       if (pcie_bus_config != PCIE_BUS_DEFAULT)
+               return;
+
+       rc = pcie_set_mps(dev, p_mps);
+       if (rc) {
+               dev_warn(&dev->dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+                        p_mps);
+               return;
+       }
+
+       dev_info(&dev->dev, "Max Payload Size set to %d (was %d, max %d)\n",
+                p_mps, mps, 128 << dev->pcie_mpss);
+}
+
 static struct hpp_type0 pci_default_type0 = {
        .revision = 1,
        .cache_line_size = 8,
@@ -1395,6 +1470,8 @@ static void pci_configure_device(struct pci_dev *dev)
        struct hotplug_params hpp;
        int ret;
 
+       pci_configure_mps(dev);
+
        memset(&hpp, 0, sizeof(hpp));
        ret = pci_get_hp_params(dev, &hpp);
        if (ret)
@@ -1539,10 +1616,24 @@ static void pci_init_capabilities(struct pci_dev *dev)
        /* Single Root I/O Virtualization */
        pci_iov_init(dev);
 
+       /* Address Translation Services */
+       pci_ats_init(dev);
+
        /* Enable ACS P2P upstream forwarding */
        pci_enable_acs(dev);
 }
 
+static void pci_set_msi_domain(struct pci_dev *dev)
+{
+       /*
+        * If no domain has been set through the pcibios_add_device
+        * callback, inherit the default from the bus device.
+        */
+       if (!dev_get_msi_domain(&dev->dev))
+               dev_set_msi_domain(&dev->dev,
+                                  dev_get_msi_domain(&dev->bus->dev));
+}
+
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
        int ret;
@@ -1584,6 +1675,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
        ret = pcibios_add_device(dev);
        WARN_ON(ret < 0);
 
+       /* Setup MSI irq domain */
+       pci_set_msi_domain(dev);
+
        /* Notifier could use PCI capabilities */
        dev->match_driver = false;
        ret = device_add(&dev->dev);
@@ -1790,22 +1884,6 @@ static void pcie_write_mrrs(struct pci_dev *dev)
                dev_err(&dev->dev, "MRRS was unable to be configured with a safe value.  If problems are experienced, try running with pci=pcie_bus_safe\n");
 }
 
-static void pcie_bus_detect_mps(struct pci_dev *dev)
-{
-       struct pci_dev *bridge = dev->bus->self;
-       int mps, p_mps;
-
-       if (!bridge)
-               return;
-
-       mps = pcie_get_mps(dev);
-       p_mps = pcie_get_mps(bridge);
-
-       if (mps != p_mps)
-               dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
-                        mps, pci_name(bridge), p_mps);
-}
-
 static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
 {
        int mps, orig_mps;
@@ -1813,10 +1891,9 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
        if (!pci_is_pcie(dev))
                return 0;
 
-       if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
-               pcie_bus_detect_mps(dev);
+       if (pcie_bus_config == PCIE_BUS_TUNE_OFF ||
+           pcie_bus_config == PCIE_BUS_DEFAULT)
                return 0;
-       }
 
        mps = 128 << *(u8 *)data;
        orig_mps = pcie_get_mps(dev);
@@ -1974,6 +2051,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
        b->bridge = get_device(&bridge->dev);
        device_enable_async_suspend(b->bridge);
        pci_set_bus_of_node(b);
+       pci_set_bus_msi_domain(b);
 
        if (!parent)
                set_dev_node(b->bridge, pcibus_to_node(b));
@@ -2095,8 +2173,9 @@ void pci_bus_release_busn_res(struct pci_bus *b)
                        res, ret ? "can not be" : "is");
 }
 
-struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
-               struct pci_ops *ops, void *sysdata, struct list_head *resources)
+struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
+               struct pci_ops *ops, void *sysdata,
+               struct list_head *resources, struct msi_controller *msi)
 {
        struct resource_entry *window;
        bool found = false;
@@ -2113,6 +2192,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
        if (!b)
                return NULL;
 
+       b->msi = msi;
+
        if (!found) {
                dev_info(&b->dev,
                 "No busn resource found for root bus, will use [bus %02x-ff]\n",
@@ -2127,6 +2208,13 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 
        return b;
 }
+
+struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+               struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+       return pci_scan_root_bus_msi(parent, bus, ops, sysdata, resources,
+                                    NULL);
+}
 EXPORT_SYMBOL(pci_scan_root_bus);
 
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,