summaryrefslogtreecommitdiffstats
path: root/drivers/pci/setup-bus.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2009-09-19 13:47:57 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-09-19 13:47:57 +0100
commit40d743b8c16a8cf6e30c1d941aa6147f9550ea75 (patch)
tree9fcdf9a06b18a275253048d1ea7c9803cec38845 /drivers/pci/setup-bus.c
parent7da18afa423f167e7ef3c9728e584d8bf05bd55a (diff)
parent83e686ea0291ee93b87dcdc00b96443b80de56c9 (diff)
Merge branch 'for-rmk' of git://linux-arm.org/linux-2.6
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r--drivers/pci/setup-bus.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 7c443b4583a..cb1a027eb55 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -309,7 +309,7 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon
since these windows have 4K granularity and the IO ranges
of non-bridge PCI devices are limited to 256 bytes.
We must be careful with the ISA aliasing though. */
-static void pbus_size_io(struct pci_bus *bus)
+static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
{
struct pci_dev *dev;
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
@@ -336,6 +336,8 @@ static void pbus_size_io(struct pci_bus *bus)
size1 += r_size;
}
}
+ if (size < min_size)
+ size = min_size;
/* To be fixed in 2.5: we should have sort of HAVE_ISA
flag in the struct pci_bus. */
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
@@ -354,7 +356,8 @@ static void pbus_size_io(struct pci_bus *bus)
/* Calculate the size of the bus and minimal alignment which
guarantees that all child resources fit in this size. */
-static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
+static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
+ unsigned long type, resource_size_t min_size)
{
struct pci_dev *dev;
resource_size_t min_align, align, size;
@@ -404,6 +407,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
mem64_mask &= r->flags & IORESOURCE_MEM_64;
}
}
+ if (size < min_size)
+ size = min_size;
align = 0;
min_align = 0;
@@ -483,6 +488,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
{
struct pci_dev *dev;
unsigned long mask, prefmask;
+ resource_size_t min_mem_size = 0, min_io_size = 0;
list_for_each_entry(dev, &bus->devices, bus_list) {
struct pci_bus *b = dev->subordinate;
@@ -512,8 +518,12 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
case PCI_CLASS_BRIDGE_PCI:
pci_bridge_check_ranges(bus);
+ if (bus->self->is_hotplug_bridge) {
+ min_io_size = pci_hotplug_io_size;
+ min_mem_size = pci_hotplug_mem_size;
+ }
default:
- pbus_size_io(bus);
+ pbus_size_io(bus, min_io_size);
/* If the bridge supports prefetchable range, size it
separately. If it doesn't, or its prefetchable window
has already been allocated by arch code, try
@@ -521,9 +531,11 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
resources. */
mask = IORESOURCE_MEM;
prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
- if (pbus_size_mem(bus, prefmask, prefmask))
+ if (pbus_size_mem(bus, prefmask, prefmask, min_mem_size))
mask = prefmask; /* Success, size non-prefetch only. */
- pbus_size_mem(bus, mask, IORESOURCE_MEM);
+ else
+ min_mem_size += min_mem_size;
+ pbus_size_mem(bus, mask, IORESOURCE_MEM, min_mem_size);
break;
}
}