Merge branch 'stable/xen-pcifront-0.8.2' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / arch / x86 / pci / i386.c
index 8379c2c3d076e8d2a7ee44c580af7fa06ad71d86..c4bb261c106e16eaeab09092a9942418dba61133 100644 (file)
@@ -65,16 +65,21 @@ pcibios_align_resource(void *data, const struct resource *res,
                        resource_size_t size, resource_size_t align)
 {
        struct pci_dev *dev = data;
-       resource_size_t start = res->start;
+       resource_size_t start = round_down(res->end - size + 1, align);
 
        if (res->flags & IORESOURCE_IO) {
-               if (skip_isa_ioresource_align(dev))
-                       return start;
-               if (start & 0x300)
-                       start = (start + 0x3ff) & ~0x3ff;
+
+               /*
+                * If we're avoiding ISA aliases, the largest contiguous I/O
+                * port space is 256 bytes.  Clearing bits 9 and 10 preserves
+                * all 256-byte and smaller alignments, so the result will
+                * still be correctly aligned.
+                */
+               if (!skip_isa_ioresource_align(dev))
+                       start &= ~0x300;
        } else if (res->flags & IORESOURCE_MEM) {
                if (start < BIOS_END)
-                       start = BIOS_END;
+                       start = res->end;       /* fail; no space */
        }
        return start;
 }