From 14c8530dbc1b7cd5020c44b391e34bdb731fd098 Mon Sep 17 00:00:00 2001
From: Alan <alan@linux.intel.com>
Date: Mon, 19 May 2014 14:03:14 +0100
Subject: [PATCH] PCI: Support BAR sizes up to 8GB

This is needed for some of the Xeon Phi type systems.

[bhelgaas: added Nikhil, use ARRAY_SIZE() to connect with decl, folded in
Kevin's "order < 0" fix to ARRAY_SIZE() usage]
Signed-off-by: Nikhil P Rao <nikhil.rao@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/setup-bus.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 138bdd6393be8..9b3498c9b7392 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -921,7 +921,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 {
 	struct pci_dev *dev;
 	resource_size_t min_align, align, size, size0, size1;
-	resource_size_t aligns[12];	/* Alignments from 1Mb to 2Gb */
+	resource_size_t aligns[14];	/* Alignments from 1Mb to 8Gb */
 	int order, max_order;
 	struct resource *b_res = find_free_bus_resource(bus, type);
 	unsigned int mem64_mask = 0;
@@ -957,10 +957,17 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 				continue;
 			}
 #endif
-			/* For bridges size != alignment */
+			/*
+			 * aligns[0] is for 1MB (since bridge memory
+			 * windows are always at least 1MB aligned), so
+			 * keep "order" from being negative for smaller
+			 * resources.
+			 */
 			align = pci_resource_alignment(dev, r);
 			order = __ffs(align) - 20;
-			if (order > 11) {
+			if (order < 0)
+				order = 0;
+			if (order >= ARRAY_SIZE(aligns)) {
 				dev_warn(&dev->dev, "disabling BAR %d: %pR "
 					 "(bad alignment %#llx)\n", i, r,
 					 (unsigned long long) align);
@@ -968,8 +975,6 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 				continue;
 			}
 			size += r_size;
-			if (order < 0)
-				order = 0;
 			/* Exclude ranges with size > align from
 			   calculation of the alignment. */
 			if (r_size == align)
-- 
2.30.2