Merge branch 'intx' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/misc-2.6
[pandora-kernel.git] / arch / powerpc / kernel / pci_64.c
index 78d3c0f..6fa9a0a 100644 (file)
 unsigned long pci_probe_only = 1;
 int pci_assign_all_buses = 0;
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
 static void fixup_resource(struct resource *res, struct pci_dev *dev);
 static void do_bus_setup(struct pci_bus *bus);
 static void phbs_remap_io(void);
-#endif
 
 /* 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),
@@ -63,7 +61,7 @@ void iSeries_pcibios_init(void);
 
 LIST_HEAD(hose_list);
 
-struct dma_mapping_ops pci_dma_ops;
+struct dma_mapping_ops *pci_dma_ops;
 EXPORT_SYMBOL(pci_dma_ops);
 
 int global_phb_number;         /* Global phb counter */
@@ -199,13 +197,23 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
        pci_setup_pci_controller(phb);
        phb->arch_data = dev;
        phb->is_dynamic = mem_init_done;
-       if (dev)
-               PHB_SET_NODE(phb, of_node_to_nid(dev));
+       if (dev) {
+               int nid = of_node_to_nid(dev);
+
+               if (nid < 0 || !node_online(nid))
+                       nid = -1;
+
+               PHB_SET_NODE(phb, nid);
+       }
        return phb;
 }
 
 void pcibios_free_controller(struct pci_controller *phb)
 {
+       spin_lock(&hose_spinlock);
+       list_del(&phb->list_node);
+       spin_unlock(&hose_spinlock);
+
        if (phb->is_dynamic)
                kfree(phb);
 }
@@ -245,7 +253,6 @@ static void __init pcibios_claim_of_setup(void)
                pcibios_claim_one_bus(b);
 }
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
 static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
 {
        const u32 *prop;
@@ -323,7 +330,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
        struct pci_dev *dev;
        const char *type;
 
-       dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
        if (!dev)
                return NULL;
        type = get_property(node, "device_type", NULL);
@@ -332,7 +339,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
 
        DBG("    create device, devfn: %x, type: %s\n", devfn, type);
 
-       memset(dev, 0, sizeof(struct pci_dev));
        dev->bus = bus;
        dev->sysdata = node;
        dev->dev.parent = bus->bridge;
@@ -500,7 +506,6 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
                pci_scan_child_bus(bus);
 }
 EXPORT_SYMBOL(of_scan_pci_bridge);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
 
 void __devinit scan_phb(struct pci_controller *hose)
 {
@@ -511,7 +516,7 @@ void __devinit scan_phb(struct pci_controller *hose)
 
        DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
 
-       bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node);
+       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",
                       hose->global_number);
@@ -534,7 +539,7 @@ void __devinit scan_phb(struct pci_controller *hose)
        }
 
        mode = PCI_PROBE_NORMAL;
-#ifdef CONFIG_PPC_MULTIPLATFORM
+
        if (node && ppc_md.pci_probe_mode)
                mode = ppc_md.pci_probe_mode(bus);
        DBG("    probe mode: %d\n", mode);
@@ -542,7 +547,7 @@ void __devinit scan_phb(struct pci_controller *hose)
                bus->subordinate = hose->last_busno;
                of_scan_bus(node, bus);
        }
-#endif /* CONFIG_PPC_MULTIPLATFORM */
+
        if (mode == PCI_PROBE_NORMAL)
                hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
 }
@@ -586,11 +591,9 @@ static int __init pcibios_init(void)
        if (ppc64_isabridge_dev != NULL)
                printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
        if (!firmware_has_feature(FW_FEATURE_ISERIES))
                /* map in PCI I/O space */
                phbs_remap_io();
-#endif
 
        printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
 
@@ -867,8 +870,6 @@ void pcibios_add_platform_entries(struct pci_dev *pdev)
        device_create_file(&pdev->dev, &dev_attr_devspec);
 }
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
-
 #define ISA_SPACE_MASK 0x1
 #define ISA_SPACE_IO 0x1
 
@@ -969,11 +970,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
                res = NULL;
                pci_space = ranges[0];
                pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
-
-               cpu_phys_addr = ranges[3];
-               if (na >= 2)
-                       cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
-
+               cpu_phys_addr = of_translate_address(dev, &ranges[3]);
                size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
                ranges += np;
                if (size == 0)
@@ -1139,7 +1136,7 @@ int unmap_bus_range(struct pci_bus *bus)
        
        if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
                return 1;
-       if (iounmap_explicit((void __iomem *) start_virt, size))
+       if (__iounmap_explicit((void __iomem *) start_virt, size))
                return 1;
 
        return 0;
@@ -1207,23 +1204,52 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
 }
 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),
+           sd->of_node ? sd->of_node->full_name : "<none>");
+
+       sd->dma_ops = pci_dma_ops;
+#ifdef CONFIG_NUMA
+       sd->numa_node = pcibus_to_node(dev->bus);
+#else
+       sd->numa_node = -1;
+#endif
+       if (ppc_md.pci_dma_dev_setup)
+               ppc_md.pci_dma_dev_setup(dev);
+}
+EXPORT_SYMBOL(pcibios_setup_new_device);
 
 static void __devinit do_bus_setup(struct pci_bus *bus)
 {
        struct pci_dev *dev;
 
-       ppc_md.iommu_bus_setup(bus);
+       if (ppc_md.pci_dma_bus_setup)
+               ppc_md.pci_dma_bus_setup(bus);
 
        list_for_each_entry(dev, &bus->devices, bus_list)
-               ppc_md.iommu_dev_setup(dev);
+               pcibios_setup_new_device(dev);
 
-       if (ppc_md.irq_bus_setup)
-               ppc_md.irq_bus_setup(bus);
+       /* 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) {
@@ -1337,8 +1363,6 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
        return NULL;
 }
 
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
        struct pci_controller *hose, *tmp;