]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kernel/pci-common.c
powerpc: Remove FW_FEATURE ISERIES from arch code
[karo-tx-linux.git] / arch / powerpc / kernel / pci-common.c
index 458ed3bee663ef0d1befcc6c717cf0b689a7166f..d0373bcb7c9dcebd42e0b8baddf48c881b375018 100644 (file)
@@ -38,7 +38,6 @@
 #include <asm/byteorder.h>
 #include <asm/machdep.h>
 #include <asm/ppc-pci.h>
-#include <asm/firmware.h>
 #include <asm/eeh.h>
 
 static DEFINE_SPINLOCK(hose_spinlock);
@@ -214,25 +213,11 @@ char __devinit *pcibios_setup(char *str)
  * If the interrupt is used, then gets the interrupt line from the
  * openfirmware and sets it in the pci_dev and pci_config line.
  */
-int pci_read_irq_line(struct pci_dev *pci_dev)
+static int pci_read_irq_line(struct pci_dev *pci_dev)
 {
        struct of_irq oirq;
        unsigned int virq;
 
-       /* The current device-tree that iSeries generates from the HV
-        * PCI informations doesn't contain proper interrupt routing,
-        * and all the fallback would do is print out crap, so we
-        * don't attempt to resolve the interrupts here at all, some
-        * iSeries specific fixup does it.
-        *
-        * In the long run, we will hopefully fix the generated device-tree
-        * instead.
-        */
-#ifdef CONFIG_PPC_ISERIES
-       if (firmware_has_feature(FW_FEATURE_ISERIES))
-               return -1;
-#endif
-
        pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
 
 #ifdef DEBUG
@@ -283,7 +268,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
 
        return 0;
 }
-EXPORT_SYMBOL(pci_read_irq_line);
 
 /*
  * Platform support for /proc/bus/pci/X/Y mmap()s,
@@ -921,18 +905,22 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
                struct resource *res = dev->resource + i;
                if (!res->flags)
                        continue;
-               /* On platforms that have 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 we're going to re-assign everything, we mark all resources
+                * as unset (and 0-base them). In addition, we mark BARs starting
+                * at 0 as unset as well, except if PCI_PROBE_ONLY is also set
+                * since in that case, we don't want to re-assign anything
                 */
-               if (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY)) {
-                       pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n",
-                                pci_name(dev), i,
-                                (unsigned long long)res->start,
-                                (unsigned long long)res->end,
-                                (unsigned int)res->flags);
+               if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) ||
+                   (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
+                       /* Only print message if not re-assigning */
+                       if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC))
+                               pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] "
+                                        "is unassigned\n",
+                                        pci_name(dev), i,
+                                        (unsigned long long)res->start,
+                                        (unsigned long long)res->end,
+                                        (unsigned int)res->flags);
                        res->end -= res->start;
                        res->start = 0;
                        res->flags |= IORESOURCE_UNSET;
@@ -1042,6 +1030,16 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
                if (i >= 3 && bus->self->transparent)
                        continue;
 
+               /* If we are going to re-assign everything, mark the resource
+                * as unset and move it down to 0
+                */
+               if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
+                       res->flags |= IORESOURCE_UNSET;
+                       res->end -= res->start;
+                       res->start = 0;
+                       continue;
+               }
+
                pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
                         pci_name(dev), i,
                         (unsigned long long)res->start,\
@@ -1118,6 +1116,11 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
        }
 }
 
+void pcibios_set_master(struct pci_dev *dev)
+{
+       /* No special bus mastering setup handling */
+}
+
 void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
        /* When called from the generic PCI probe, read PCI<->PCI bridge
@@ -1262,18 +1265,15 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
        pci_bus_for_each_resource(bus, res, i) {
                if (!res || !res->flags || res->start > res->end || res->parent)
                        continue;
+
+               /* If the resource was left unset at this point, we clear it */
+               if (res->flags & IORESOURCE_UNSET)
+                       goto clear_resource;
+
                if (bus->parent == NULL)
                        pr = (res->flags & IORESOURCE_IO) ?
                                &ioport_resource : &iomem_resource;
                else {
-                       /* Don't bother with non-root busses when
-                        * re-assigning all resources. We clear the
-                        * resource flags as if they were colliding
-                        * and as such ensure proper re-allocation
-                        * later.
-                        */
-                       if (pci_has_flag(PCI_REASSIGN_ALL_RSRC))
-                               goto clear_resource;
                        pr = pci_find_parent_resource(bus->self, res);
                        if (pr == res) {
                                /* this happens when the generic PCI
@@ -1304,9 +1304,9 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
                        if (reparent_resources(pr, res) == 0)
                                continue;
                }
-               printk(KERN_WARNING "PCI: Cannot allocate resource region "
-                      "%d of PCI bridge %d, will remap\n", i, bus->number);
-clear_resource:
+               pr_warning("PCI: Cannot allocate resource region "
+                          "%d of PCI bridge %d, will remap\n", i, bus->number);
+       clear_resource:
                res->start = res->end = 0;
                res->flags = 0;
        }
@@ -1451,16 +1451,11 @@ void __init pcibios_resource_survey(void)
 {
        struct pci_bus *b;
 
-       /* Allocate and assign resources. If we re-assign everything, then
-        * we skip the allocate phase
-        */
+       /* Allocate and assign resources */
        list_for_each_entry(b, &pci_root_buses, node)
                pcibios_allocate_bus_resources(b);
-
-       if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
-               pcibios_allocate_resources(0);
-               pcibios_allocate_resources(1);
-       }
+       pcibios_allocate_resources(0);
+       pcibios_allocate_resources(1);
 
        /* Before we start assigning unassigned resource, we try to reserve
         * the low IO area and the VGA memory area if they intersect the
@@ -1555,14 +1550,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
        return pci_enable_resources(dev, mask);
 }
 
-void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
+static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources)
 {
-       struct pci_bus *bus = hose->bus;
        struct resource *res;
        int i;
 
        /* Hookup PHB IO resource */
-       bus->resource[0] = res = &hose->io_resource;
+       res = &hose->io_resource;
 
        if (!res->flags) {
                printk(KERN_WARNING "PCI: I/O resource not set for host"
@@ -1580,6 +1574,7 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
                 (unsigned long long)res->start,
                 (unsigned long long)res->end,
                 (unsigned long)res->flags);
+       pci_add_resource(resources, res);
 
        /* Hookup PHB Memory resources */
        for (i = 0; i < 3; ++i) {
@@ -1597,12 +1592,12 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
                        res->flags = IORESOURCE_MEM;
 #endif /* CONFIG_PPC32 */
                }
-               bus->resource[i+1] = res;
 
                pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
                         (unsigned long long)res->start,
                         (unsigned long long)res->end,
                         (unsigned long)res->flags);
+               pci_add_resource(resources, res);
        }
 
        pr_debug("PCI: PHB MEM offset     = %016llx\n",
@@ -1696,6 +1691,7 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
  */
 void __devinit pcibios_scan_phb(struct pci_controller *hose)
 {
+       LIST_HEAD(resources);
        struct pci_bus *bus;
        struct device_node *node = hose->dn;
        int mode;
@@ -1703,22 +1699,24 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
        pr_debug("PCI: Scanning PHB %s\n",
                 node ? node->full_name : "<NO NAME>");
 
+       /* Get some IO space for the new PHB */
+       pcibios_setup_phb_io_space(hose);
+
+       /* Wire up PHB bus resources */
+       pcibios_setup_phb_resources(hose, &resources);
+
        /* Create an empty bus for the toplevel */
-       bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
+       bus = pci_create_root_bus(hose->parent, hose->first_busno,
+                                 hose->ops, hose, &resources);
        if (bus == NULL) {
                pr_err("Failed to create bus for PCI domain %04x\n",
                        hose->global_number);
+               pci_free_resource_list(&resources);
                return;
        }
        bus->secondary = hose->first_busno;
        hose->bus = bus;
 
-       /* Get some IO space for the new PHB */
-       pcibios_setup_phb_io_space(hose);
-
-       /* Wire up PHB bus resources */
-       pcibios_setup_phb_resources(hose);
-
        /* Get probe mode and perform scan */
        mode = PCI_PROBE_NORMAL;
        if (node && ppc_md.pci_probe_mode)
@@ -1732,6 +1730,12 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
        if (mode == PCI_PROBE_NORMAL)
                hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
 
+       /* Platform gets a chance to do some global fixups before
+        * we proceed to resource allocation
+        */
+       if (ppc_md.pcibios_fixup_phb)
+               ppc_md.pcibios_fixup_phb(hose);
+
        /* Configure PCI Express settings */
        if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
                struct pci_bus *child;
@@ -1747,10 +1751,13 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
 static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
 {
        int i, class = dev->class >> 8;
+       /* When configured as agent, programing interface = 1 */
+       int prog_if = dev->class & 0xf;
 
        if ((class == PCI_CLASS_PROCESSOR_POWERPC ||
             class == PCI_CLASS_BRIDGE_OTHER) &&
                (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) &&
+               (prog_if == 0) &&
                (dev->bus->parent == NULL)) {
                for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
                        dev->resource[i].start = 0;