int fix_aperture __initdata = 1;
 
-struct bus_dev_range {
-       int bus;
-       int dev_base;
-       int dev_limit;
-};
-
-static struct bus_dev_range bus_dev_ranges[] __initdata = {
-       { 0x00, 0x18, 0x20},
-       { 0xff, 0x00, 0x20},
-       { 0xfe, 0x00, 0x20}
-};
-
 static struct resource gart_resource = {
        .name   = "GART",
        .flags  = IORESOURCE_MEM,
        search_agp_bridge(&agp_aper_order, &valid_agp);
 
        fix = 0;
-       for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
+       for (i = 0; amd_nb_bus_dev_ranges[i].dev_limit; i++) {
                int bus;
                int dev_base, dev_limit;
 
-               bus = bus_dev_ranges[i].bus;
-               dev_base = bus_dev_ranges[i].dev_base;
-               dev_limit = bus_dev_ranges[i].dev_limit;
+               bus = amd_nb_bus_dev_ranges[i].bus;
+               dev_base = amd_nb_bus_dev_ranges[i].dev_base;
+               dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
 
                for (slot = dev_base; slot < dev_limit; slot++) {
                        if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
                return;
 
        /* disable them all at first */
-       for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
+       for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
                int bus;
                int dev_base, dev_limit;
 
-               bus = bus_dev_ranges[i].bus;
-               dev_base = bus_dev_ranges[i].dev_base;
-               dev_limit = bus_dev_ranges[i].dev_limit;
+               bus = amd_nb_bus_dev_ranges[i].bus;
+               dev_base = amd_nb_bus_dev_ranges[i].dev_base;
+               dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
 
                for (slot = dev_base; slot < dev_limit; slot++) {
                        if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
 
        fix = 0;
        node = 0;
-       for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
+       for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
                int bus;
                int dev_base, dev_limit;
                u32 ctl;
 
-               bus = bus_dev_ranges[i].bus;
-               dev_base = bus_dev_ranges[i].dev_base;
-               dev_limit = bus_dev_ranges[i].dev_limit;
+               bus = amd_nb_bus_dev_ranges[i].bus;
+               dev_base = amd_nb_bus_dev_ranges[i].dev_base;
+               dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
 
                for (slot = dev_base; slot < dev_limit; slot++) {
                        if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
        }
 
        /* Fix up the north bridges */
-       for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
+       for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
                int bus, dev_base, dev_limit;
 
                /*
                 */
                u32 ctl = DISTLBWALKPRB | aper_order << 1;
 
-               bus = bus_dev_ranges[i].bus;
-               dev_base = bus_dev_ranges[i].dev_base;
-               dev_limit = bus_dev_ranges[i].dev_limit;
+               bus = amd_nb_bus_dev_ranges[i].bus;
+               dev_base = amd_nb_bus_dev_ranges[i].dev_base;
+               dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
                for (slot = dev_base; slot < dev_limit; slot++) {
                        if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
                                continue;
 
 #include <linux/cpu.h>
 #include <linux/range.h>
 
+#include <asm/amd_nb.h>
 #include <asm/pci_x86.h>
 
 #include <asm/pci-direct.h>
        .notifier_call  = amd_cpu_notify,
 };
 
+static void __init pci_enable_pci_io_ecs(void)
+{
+#ifdef CONFIG_AMD_NB
+       unsigned int i, n;
+
+       for (n = i = 0; !n && amd_nb_bus_dev_ranges[i].dev_limit; ++i) {
+               u8 bus = amd_nb_bus_dev_ranges[i].bus;
+               u8 slot = amd_nb_bus_dev_ranges[i].dev_base;
+               u8 limit = amd_nb_bus_dev_ranges[i].dev_limit;
+
+               for (; slot < limit; ++slot) {
+                       u32 val = read_pci_config(bus, slot, 3, 0);
+
+                       if (!early_is_amd_nb(val))
+                               continue;
+
+                       val = read_pci_config(bus, slot, 3, 0x8c);
+                       if (!(val & (ENABLE_CF8_EXT_CFG >> 32))) {
+                               val |= ENABLE_CF8_EXT_CFG >> 32;
+                               write_pci_config(bus, slot, 3, 0x8c, val);
+                       }
+                       ++n;
+               }
+       }
+       pr_info("Extended Config Space enabled on %u nodes\n", n);
+#endif
+}
+
 static int __init pci_io_ecs_init(void)
 {
        int cpu;
         if (boot_cpu_data.x86 < 0x10)
                return 0;
 
+       /* Try the PCI method first. */
+       if (early_pci_allowed())
+               pci_enable_pci_io_ecs();
+
        register_cpu_notifier(&amd_cpu_notifier);
        for_each_online_cpu(cpu)
                amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE,