These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / pci / setup-bus.c
index 508cc56..1723ac1 100644 (file)
@@ -1037,9 +1037,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
                        struct resource *r = &dev->resource[i];
                        resource_size_t r_size;
 
-                       if (r->parent || ((r->flags & mask) != type &&
-                                         (r->flags & mask) != type2 &&
-                                         (r->flags & mask) != type3))
+                       if (r->parent || (r->flags & IORESOURCE_PCI_FIXED) ||
+                           ((r->flags & mask) != type &&
+                            (r->flags & mask) != type2 &&
+                            (r->flags & mask) != type3))
                                continue;
                        r_size = resource_size(r);
 #ifdef CONFIG_PCI_IOV
@@ -1340,6 +1341,47 @@ void pci_bus_size_bridges(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pci_bus_size_bridges);
 
+static void assign_fixed_resource_on_bus(struct pci_bus *b, struct resource *r)
+{
+       int i;
+       struct resource *parent_r;
+       unsigned long mask = IORESOURCE_IO | IORESOURCE_MEM |
+                            IORESOURCE_PREFETCH;
+
+       pci_bus_for_each_resource(b, parent_r, i) {
+               if (!parent_r)
+                       continue;
+
+               if ((r->flags & mask) == (parent_r->flags & mask) &&
+                   resource_contains(parent_r, r))
+                       request_resource(parent_r, r);
+       }
+}
+
+/*
+ * Try to assign any resources marked as IORESOURCE_PCI_FIXED, as they
+ * are skipped by pbus_assign_resources_sorted().
+ */
+static void pdev_assign_fixed_resources(struct pci_dev *dev)
+{
+       int i;
+
+       for (i = 0; i <  PCI_NUM_RESOURCES; i++) {
+               struct pci_bus *b;
+               struct resource *r = &dev->resource[i];
+
+               if (r->parent || !(r->flags & IORESOURCE_PCI_FIXED) ||
+                   !(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
+                       continue;
+
+               b = dev->bus;
+               while (b && !r->parent) {
+                       assign_fixed_resource_on_bus(b, r);
+                       b = b->parent;
+               }
+       }
+}
+
 void __pci_bus_assign_resources(const struct pci_bus *bus,
                                struct list_head *realloc_head,
                                struct list_head *fail_head)
@@ -1350,6 +1392,8 @@ void __pci_bus_assign_resources(const struct pci_bus *bus,
        pbus_assign_resources_sorted(bus, realloc_head, fail_head);
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
+               pdev_assign_fixed_resources(dev);
+
                b = dev->subordinate;
                if (!b)
                        continue;