Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.git] / arch / powerpc / kernel / pci-common.c
index 571854f..224e9a1 100644 (file)
@@ -598,6 +598,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
                        res->start = pci_addr;
                        break;
                case 2:         /* PCI Memory space */
+               case 3:         /* PCI 64 bits Memory space */
                        printk(KERN_INFO
                               " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
                               cpu_addr, cpu_addr + size - 1, pci_addr,
@@ -748,7 +749,13 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
                struct resource *res = dev->resource + i;
                if (!res->flags)
                        continue;
-               if (res->end == 0xffffffff) {
+               /* On platforms that have PPC_PCI_PROBE_ONLY set, we don't
+                * consider 0 as an unassigned BAR value. It's technically
+                * a valid value, but linux doesn't like it... so when we can
+                * re-assign things, we do so, but if we can't, we keep it
+                * around and hope for the best...
+                */
+               if (res->start == 0 && !(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
                        pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n",
                                 pci_name(dev), i,
                                 (unsigned long long)res->start,
@@ -792,9 +799,10 @@ static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
                for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
                        if ((res = bus->resource[i]) == NULL)
                                continue;
-                       if (!res->flags || bus->self->transparent)
+                       if (!res->flags)
+                               continue;
+                       if (i >= 3 && bus->self->transparent)
                                continue;
-
                        /* On PowerMac, Apple leaves bridge windows open over
                         * an inaccessible region of memory space (0...fffff)
                         * which is somewhat bogus, but that's what they think
@@ -806,7 +814,8 @@ static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
                         * equal to the pci_mem_offset of the host bridge and
                         * their size is smaller than 1M.
                         */
-                       if (res->start == hose->pci_mem_offset &&
+                       if (res->flags & IORESOURCE_MEM &&
+                           res->start == hose->pci_mem_offset &&
                            res->end < 0x100000) {
                                printk(KERN_INFO
                                       "PCI: Closing bogus Apple Firmware"
@@ -1035,7 +1044,7 @@ clear_resource:
        }
 }
 
-static inline int __devinit alloc_resource(struct pci_dev *dev, int idx)
+static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
 {
        struct resource *pr, *r = &dev->resource[idx];
 
@@ -1059,10 +1068,7 @@ static inline int __devinit alloc_resource(struct pci_dev *dev, int idx)
                r->flags |= IORESOURCE_UNSET;
                r->end -= r->start;
                r->start = 0;
-
-               return -EBUSY;
        }
-       return 0;
 }
 
 static void __init pcibios_allocate_resources(int pass)
@@ -1084,12 +1090,8 @@ static void __init pcibios_allocate_resources(int pass)
                                disabled = !(command & PCI_COMMAND_IO);
                        else
                                disabled = !(command & PCI_COMMAND_MEMORY);
-                       if (pass == disabled && alloc_resource(dev, idx)) {
-                               command &= ~(r->flags & (IORESOURCE_IO |
-                                                        IORESOURCE_MEM));
-                               pci_write_config_word(dev,
-                                                     PCI_COMMAND, command);
-                       }
+                       if (pass == disabled)
+                               alloc_resource(dev, idx);
                }
                if (pass)
                        continue;
@@ -1160,41 +1162,9 @@ EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
-       u16 cmd, old_cmd;
-       int idx;
-       struct resource *r;
-
        if (ppc_md.pcibios_enable_device_hook)
                if (ppc_md.pcibios_enable_device_hook(dev))
                        return -EINVAL;
 
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-       old_cmd = cmd;
-       for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
-               /* Only set up the requested stuff */
-               if (!(mask & (1 << idx)))
-                       continue;
-               r = &dev->resource[idx];
-               if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
-                       continue;
-               if ((idx == PCI_ROM_RESOURCE) &&
-                               (!(r->flags & IORESOURCE_ROM_ENABLE)))
-                       continue;
-               if (r->parent == NULL) {
-                       printk(KERN_ERR "PCI: Device %s not available because"
-                              " of resource collisions\n", pci_name(dev));
-                       return -EINVAL;
-               }
-               if (r->flags & IORESOURCE_IO)
-                       cmd |= PCI_COMMAND_IO;
-               if (r->flags & IORESOURCE_MEM)
-                       cmd |= PCI_COMMAND_MEMORY;
-       }
-       if (cmd != old_cmd) {
-               printk("PCI: Enabling device %s (%04x -> %04x)\n",
-                      pci_name(dev), old_cmd, cmd);
-               pci_write_config_word(dev, PCI_COMMAND, cmd);
-       }
-       return 0;
+       return pci_enable_resources(dev, mask);
 }
-