When a resource is assigned, IORESOURCE_STARTALIGN flag is cleared,
resulting in pci_resource_alignment() returning 0 in some situations
(at least for bridge windows).

Add heuristic to pci_resource_alignment() which mimics start and size
alignment by taking minimum of those for an assigned resource. It may
overestimate alignment when start has large alignment but the exact
alignment information is not available and regenerating it by sizing
the bridge again is costly.

Signed-off-by: Ilpo Järvinen <[email protected]>
---
 drivers/pci/setup-res.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index c15bce20815d..03098f159ec9 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -13,6 +13,7 @@
  *          Resource sorting
  */
 
+#include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/pci.h>
@@ -265,6 +266,18 @@ resource_size_t pci_resource_alignment(const struct 
pci_dev *dev,
            (res->flags & (IORESOURCE_IO|IORESOURCE_MEM)))
                min_align = pci_min_window_alignment(dev->bus, res->flags);
 
+       if (resource_assigned(res)) {
+               resource_size_t start_align = 1, size_align;
+
+               size_align = roundup_pow_of_two(resource_size(res));
+               if (res->start)
+                       start_align <<= __ffs(res->start);
+               else
+                       start_align = size_align;
+
+               return max(min(start_align, size_align), min_align);
+       }
+
        return max(resource_alignment(res), min_align);
 }
 
-- 
2.39.5


Reply via email to