Merge branches 'release', 'asus', 'sony-laptop' and 'thinkpad' into release
[pandora-kernel.git] / arch / powerpc / kernel / pci_64.c
index f5c4628..5275074 100644 (file)
 #endif
 
 unsigned long pci_probe_only = 1;
-int pci_assign_all_buses = 0;
-
-static void fixup_resource(struct resource *res, struct pci_dev *dev);
-static void do_bus_setup(struct pci_bus *bus);
 
 /* pci_io_base -- the base address from which io bars are offsets.
  * This is the lowest I/O base address (so bar values are always positive),
@@ -94,127 +90,6 @@ static void fixup_broken_pcnet32(struct pci_dev* dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
 
-void  pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-                             struct resource *res)
-{
-       unsigned long offset = 0;
-       struct pci_controller *hose = pci_bus_to_host(dev->bus);
-
-       if (!hose)
-               return;
-
-       if (res->flags & IORESOURCE_IO)
-               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-
-       if (res->flags & IORESOURCE_MEM)
-               offset = hose->pci_mem_offset;
-
-       region->start = res->start - offset;
-       region->end = res->end - offset;
-}
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-                             struct pci_bus_region *region)
-{
-       unsigned long offset = 0;
-       struct pci_controller *hose = pci_bus_to_host(dev->bus);
-
-       if (!hose)
-               return;
-
-       if (res->flags & IORESOURCE_IO)
-               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-
-       if (res->flags & IORESOURCE_MEM)
-               offset = hose->pci_mem_offset;
-
-       res->start = region->start + offset;
-       res->end = region->end + offset;
-}
-
-#ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-#endif
-
-/*
- * We need to avoid collisions with `mirrored' VGA ports
- * and other strange ISA hardware, so we always want the
- * addresses to be allocated in the 0x000-0x0ff region
- * modulo 0x400.
- *
- * Why? Because some silly external IO cards only decode
- * the low 10 bits of the IO address. The 0x00-0xff region
- * is reserved for motherboard devices that decode all 16
- * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
- * but we want to try to avoid allocating at 0x2900-0x2bff
- * which might have be mirrored at 0x0100-0x03ff..
- */
-void pcibios_align_resource(void *data, struct resource *res,
-                           resource_size_t size, resource_size_t align)
-{
-       struct pci_dev *dev = data;
-       struct pci_controller *hose = pci_bus_to_host(dev->bus);
-       resource_size_t start = res->start;
-       unsigned long alignto;
-
-       if (res->flags & IORESOURCE_IO) {
-               unsigned long offset = (unsigned long)hose->io_base_virt -
-                                       _IO_BASE;
-               /* Make sure we start at our min on all hoses */
-               if (start - offset < PCIBIOS_MIN_IO)
-                       start = PCIBIOS_MIN_IO + offset;
-
-               /*
-                * Put everything into 0x00-0xff region modulo 0x400
-                */
-               if (start & 0x300)
-                       start = (start + 0x3ff) & ~0x3ff;
-
-       } else if (res->flags & IORESOURCE_MEM) {
-               /* Make sure we start at our min on all hoses */
-               if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM)
-                       start = PCIBIOS_MIN_MEM + hose->pci_mem_offset;
-
-               /* Align to multiple of size of minimum base.  */
-               alignto = max(0x1000UL, align);
-               start = ALIGN(start, alignto);
-       }
-
-       res->start = start;
-}
-
-void __devinit pcibios_claim_one_bus(struct pci_bus *b)
-{
-       struct pci_dev *dev;
-       struct pci_bus *child_bus;
-
-       list_for_each_entry(dev, &b->devices, bus_list) {
-               int i;
-
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       struct resource *r = &dev->resource[i];
-
-                       if (r->parent || !r->start || !r->flags)
-                               continue;
-                       pci_claim_resource(dev, i);
-               }
-       }
-
-       list_for_each_entry(child_bus, &b->children, node)
-               pcibios_claim_one_bus(child_bus);
-}
-#ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
-#endif
-
-static void __init pcibios_claim_of_setup(void)
-{
-       struct pci_bus *b;
-
-       list_for_each_entry(b, &pci_root_buses, node)
-               pcibios_claim_one_bus(b);
-}
 
 static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
 {
@@ -282,7 +157,6 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
                res->end = base + size - 1;
                res->flags = flags;
                res->name = pci_name(dev);
-               fixup_resource(res, dev);
        }
 }
 
@@ -351,16 +225,17 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
 EXPORT_SYMBOL(of_create_pci_dev);
 
 void __devinit of_scan_bus(struct device_node *node,
-                                 struct pci_bus *bus)
+                          struct pci_bus *bus)
 {
-       struct device_node *child = NULL;
+       struct device_node *child;
        const u32 *reg;
        int reglen, devfn;
        struct pci_dev *dev;
 
        DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
 
-       while ((child = of_get_next_child(node, child)) != NULL) {
+       /* Scan direct children */
+       for_each_child_of_node(node, child) {
                DBG("  * %s\n", child->full_name);
                reg = of_get_property(child, "reg", &reglen);
                if (reg == NULL || reglen < 20)
@@ -371,19 +246,26 @@ void __devinit of_scan_bus(struct device_node *node,
                dev = of_create_pci_dev(child, bus, devfn);
                if (!dev)
                        continue;
-               DBG("dev header type: %x\n", dev->hdr_type);
+               DBG("    dev header type: %x\n", dev->hdr_type);
+       }
 
+       /* Ally all fixups */
+       pcibios_fixup_of_probed_bus(bus);
+
+       /* Now scan child busses */
+       list_for_each_entry(dev, &bus->devices, bus_list) {
                if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
-                   dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
-                       of_scan_pci_bridge(child, dev);
+                   dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
+                       struct device_node *child = pci_device_to_OF_node(dev);
+                       if (dev)
+                               of_scan_pci_bridge(child, dev);
+               }
        }
-
-       do_bus_setup(bus);
 }
 EXPORT_SYMBOL(of_scan_bus);
 
 void __devinit of_scan_pci_bridge(struct device_node *node,
-                               struct pci_dev *dev)
+                                 struct pci_dev *dev)
 {
        struct pci_bus *bus;
        const u32 *busrange, *ranges;
@@ -453,7 +335,6 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
                res->start = of_read_number(&ranges[1], 2);
                res->end = res->start + size - 1;
                res->flags = flags;
-               fixup_resource(res, dev);
        }
        sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
                bus->number);
@@ -476,10 +357,10 @@ void __devinit scan_phb(struct pci_controller *hose)
        struct pci_bus *bus;
        struct device_node *node = hose->dn;
        int i, mode;
-       struct resource *res;
 
-       DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
+       DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
 
+       /* Create an empty bus for the toplevel */
        bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
        if (bus == NULL) {
                printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
@@ -489,26 +370,27 @@ void __devinit scan_phb(struct pci_controller *hose)
        bus->secondary = hose->first_busno;
        hose->bus = bus;
 
+       /* Get some IO space for the new PHB */
        pcibios_map_io_space(bus);
 
-       bus->resource[0] = res = &hose->io_resource;
-       if (res->flags && request_resource(&ioport_resource, res)) {
-               printk(KERN_ERR "Failed to request PCI IO region "
-                      "on PCI domain %04x\n", hose->global_number);
-               DBG("res->start = 0x%016lx, res->end = 0x%016lx\n",
-                   res->start, res->end);
-       }
-
+       /* Wire up PHB bus resources */
+       DBG("PCI: PHB IO resource    = %016lx-%016lx [%lx]\n",
+           hose->io_resource.start, hose->io_resource.end,
+           hose->io_resource.flags);
+       bus->resource[0] = &hose->io_resource;
        for (i = 0; i < 3; ++i) {
-               res = &hose->mem_resources[i];
-               bus->resource[i+1] = res;
-               if (res->flags && request_resource(&iomem_resource, res))
-                       printk(KERN_ERR "Failed to request PCI memory region "
-                              "on PCI domain %04x\n", hose->global_number);
+               DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
+                   hose->mem_resources[i].start,
+                   hose->mem_resources[i].end,
+                   hose->mem_resources[i].flags);
+               bus->resource[i+1] = &hose->mem_resources[i];
        }
+       DBG("PCI: PHB MEM offset     = %016lx\n", hose->pci_mem_offset);
+       DBG("PCI: PHB IO  offset     = %08lx\n",
+           (unsigned long)hose->io_base_virt - _IO_BASE);
 
+       /* Get probe mode and perform scan */
        mode = PCI_PROBE_NORMAL;
-
        if (node && ppc_md.pci_probe_mode)
                mode = ppc_md.pci_probe_mode(bus);
        DBG("    probe mode: %d\n", mode);
@@ -525,12 +407,15 @@ static int __init pcibios_init(void)
 {
        struct pci_controller *hose, *tmp;
 
+       printk(KERN_INFO "PCI: Probing PCI hardware\n");
+
        /* For now, override phys_mem_access_prot. If we need it,
         * later, we may move that initialization to each ppc_md
         */
        ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
 
-       printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
+       if (pci_probe_only)
+               ppc_pci_flags |= PPC_PCI_PROBE_ONLY;
 
        /* Scan all of the recorded PCI controllers.  */
        list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
@@ -538,17 +423,8 @@ static int __init pcibios_init(void)
                pci_bus_add_devices(hose->bus);
        }
 
-       if (pci_probe_only)
-               pcibios_claim_of_setup();
-       else
-               /* FIXME: `else' will be removed when
-                  pci_assign_unassigned_resources() is able to work
-                  correctly with [partially] allocated PCI tree. */
-               pci_assign_unassigned_resources();
-
-       /* Call machine dependent final fixup */
-       if (ppc_md.pcibios_fixup)
-               ppc_md.pcibios_fixup();
+       /* Call common code to handle resource allocation */
+       pcibios_resource_survey();
 
        printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
 
@@ -557,44 +433,6 @@ static int __init pcibios_init(void)
 
 subsys_initcall(pcibios_init);
 
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
-       u16 cmd, oldcmd;
-       int i;
-
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-       oldcmd = cmd;
-
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *res = &dev->resource[i];
-
-               /* Only set up the requested stuff */
-               if (!(mask & (1<<i)))
-                       continue;
-
-               if (res->flags & IORESOURCE_IO)
-                       cmd |= PCI_COMMAND_IO;
-               if (res->flags & IORESOURCE_MEM)
-                       cmd |= PCI_COMMAND_MEMORY;
-       }
-
-       if (cmd != oldcmd) {
-               printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n",
-                      pci_name(dev), cmd);
-                /* Enable the appropriate bits in the PCI command register.  */
-               pci_write_config_word(dev, PCI_COMMAND, cmd);
-       }
-       return 0;
-}
-
-/* Decide whether to display the domain number in /proc */
-int pci_proc_domain(struct pci_bus *bus)
-{
-       struct pci_controller *hose = pci_bus_to_host(bus);
-       return hose->buid != 0;
-}
-
-
 #ifdef CONFIG_HOTPLUG
 
 int pcibios_unmap_io_space(struct pci_bus *bus)
@@ -710,51 +548,13 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
 }
 EXPORT_SYMBOL_GPL(pcibios_map_io_space);
 
-static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
-{
-       struct pci_controller *hose = pci_bus_to_host(dev->bus);
-       unsigned long offset;
-
-       if (res->flags & IORESOURCE_IO) {
-               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-               res->start += offset;
-               res->end += offset;
-       } else if (res->flags & IORESOURCE_MEM) {
-               res->start += hose->pci_mem_offset;
-               res->end += hose->pci_mem_offset;
-       }
-}
-
-void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
-                                             struct pci_bus *bus)
-{
-       /* Update device resources.  */
-       int i;
-
-       DBG("%s: Fixup resources:\n", pci_name(dev));
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *res = &dev->resource[i];
-               if (!res->flags)
-                       continue;
-
-               DBG("  0x%02x < %08lx:0x%016lx...0x%016lx\n",
-                   i, res->flags, res->start, res->end);
-
-               fixup_resource(res, dev);
-
-               DBG("       > %08lx:0x%016lx...0x%016lx\n",
-                   res->flags, res->start, res->end);
-       }
-}
-EXPORT_SYMBOL(pcibios_fixup_device_resources);
-
 void __devinit pcibios_setup_new_device(struct pci_dev *dev)
 {
        struct dev_archdata *sd = &dev->dev.archdata;
 
        sd->of_node = pci_device_to_OF_node(dev);
 
-       DBG("PCI device %s OF node: %s\n", pci_name(dev),
+       DBG("PCI: device %s OF node: %s\n", pci_name(dev),
            sd->of_node ? sd->of_node->full_name : "<none>");
 
        sd->dma_ops = pci_dma_ops;
@@ -768,7 +568,7 @@ void __devinit pcibios_setup_new_device(struct pci_dev *dev)
 }
 EXPORT_SYMBOL(pcibios_setup_new_device);
 
-static void __devinit do_bus_setup(struct pci_bus *bus)
+void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
 {
        struct pci_dev *dev;
 
@@ -777,42 +577,7 @@ static void __devinit do_bus_setup(struct pci_bus *bus)
 
        list_for_each_entry(dev, &bus->devices, bus_list)
                pcibios_setup_new_device(dev);
-
-       /* Read default IRQs and fixup if necessary */
-       list_for_each_entry(dev, &bus->devices, bus_list) {
-               pci_read_irq_line(dev);
-               if (ppc_md.pci_irq_fixup)
-                       ppc_md.pci_irq_fixup(dev);
-       }
-}
-
-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
-{
-       struct pci_dev *dev = bus->self;
-       struct device_node *np;
-
-       np = pci_bus_to_OF_node(bus);
-
-       DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>");
-
-       if (dev && pci_probe_only &&
-           (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
-               /* This is a subordinate bridge */
-
-               pci_read_bridge_bases(bus);
-               pcibios_fixup_device_resources(dev, bus);
-       }
-
-       do_bus_setup(bus);
-
-       if (!pci_probe_only)
-               return;
-
-       list_for_each_entry(dev, &bus->devices, bus_list)
-               if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
-                       pcibios_fixup_device_resources(dev, bus);
 }
-EXPORT_SYMBOL(pcibios_fixup_bus);
 
 unsigned long pci_address_to_pio(phys_addr_t address)
 {