@@ -204,8 +204,10 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
{
#ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
int rc;
+ unsigned long mmio64 = pci_find_host_bridge(bus)->has_mem64 ?
+ IORESOURCE_MEM_64 : 0;
- if (res->flags & IORESOURCE_MEM_64) {
+ if (res->flags & mmio64) {
rc = pci_bus_alloc_from_region(bus, res, size, align, min,
type_mask, alignf, alignf_data,
&pci_high);
@@ -1311,7 +1311,8 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES];
mask = IORESOURCE_MEM;
prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
- if (b_res[2].flags & IORESOURCE_MEM_64) {
+ if ((b_res[2].flags & IORESOURCE_MEM_64) &&
+ pci_find_host_bridge(bus)->has_mem64) {
prefmask |= IORESOURCE_MEM_64;
ret = pbus_size_mem(bus, prefmask, prefmask,
prefmask, prefmask,
@@ -1513,17 +1514,21 @@ static void pci_bridge_release_resources(struct pci_bus *bus,
* io port.
* 2. if there is non pref mmio assign fail, release bridge
* nonpref mmio.
- * 3. if there is 64bit pref mmio assign fail, and bridge pref
+ * 3. if there is pref mmio assign fail, and host bridge does
+ * have 64bit mmio, release bridge pref mmio.
+ * 4. if there is 64bit pref mmio assign fail, and bridge pref
* is 64bit, release bridge pref mmio.
- * 4. if there is pref mmio assign fail, and bridge pref is
+ * 5. if there is pref mmio assign fail, and bridge pref is
* 32bit mmio, release bridge pref mmio
- * 5. if there is pref mmio assign fail, and bridge pref is not
+ * 6. if there is pref mmio assign fail, and bridge pref is not
* assigned, release bridge nonpref mmio.
*/
if (type & IORESOURCE_IO)
idx = 0;
else if (!(type & IORESOURCE_PREFETCH))
idx = 1;
+ else if (!pci_find_host_bridge(bus)->has_mem64)
+ idx = 2;
else if ((type & IORESOURCE_MEM_64) &&
(b_res[2].flags & IORESOURCE_MEM_64))
idx = 2;
@@ -212,6 +212,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
struct resource *res = dev->resource + resno;
resource_size_t min;
int ret;
+ unsigned long mmio64 = pci_find_host_bridge(bus)->has_mem64 ?
+ IORESOURCE_MEM_64 : 0;
min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
@@ -223,7 +225,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
* things differently than they were sized, not everything will fit.
*/
ret = pci_bus_alloc_resource(bus, res, size, align, min,
- IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
+ IORESOURCE_PREFETCH | mmio64,
pcibios_align_resource, dev);
if (ret == 0)
return 0;
@@ -232,7 +234,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
* If the prefetchable window is only 32 bits wide, we can put
* 64-bit prefetchable resources in it.
*/
- if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
+ if (mmio64 &&
+ (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
(IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
ret = pci_bus_alloc_resource(bus, res, size, align, min,
IORESOURCE_PREFETCH,
@@ -247,7 +250,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
* non-prefetchable, the first call already tried the only possibility
* so we don't need to try again.
*/
- if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
+ if (res->flags & (IORESOURCE_PREFETCH | mmio64))
ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
pcibios_align_resource, dev);