]> err.no Git - linux-2.6/commitdiff
[SPARC64]: Consolidate PCI mem/io resource determination.
authorDavid S. Miller <davem@sunset.davemloft.net>
Fri, 9 Mar 2007 05:55:49 +0000 (21:55 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Thu, 26 Apr 2007 08:55:11 +0000 (01:55 -0700)
It can be done for every PCI configuration using OF properties.

Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_impl.h
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/pci_sun4v.c

index 0d3c95df0d95ba2392b17cfc0f6c90032f52f29b..4945d700a7690b399d5cbe22587b463b1cfda591 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: pci_common.c,v 1.29 2002/02/01 00:56:03 davem Exp $
- * pci_common.c: PCI controller common support.
+/* pci_common.c: PCI controller common support.
  *
- * Copyright (C) 1999 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/string.h>
@@ -16,8 +15,8 @@
 
 #include "pci_impl.h"
 
-void pci_register_legacy_regions(struct resource *io_res,
-                                struct resource *mem_res)
+static void pci_register_legacy_regions(struct resource *io_res,
+                                       struct resource *mem_res)
 {
        struct resource *p;
 
@@ -53,6 +52,91 @@ void pci_register_legacy_regions(struct resource *io_res,
        request_resource(mem_res, p);
 }
 
+static void pci_register_iommu_region(struct pci_pbm_info *pbm)
+{
+       u32 *vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL);
+
+       if (vdma) {
+               struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL);
+
+               if (!rp) {
+                       prom_printf("Cannot allocate IOMMU resource.\n");
+                       prom_halt();
+               }
+               rp->name = "IOMMU";
+               rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
+               rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
+               rp->flags = IORESOURCE_BUSY;
+               request_resource(&pbm->mem_space, rp);
+       }
+}
+
+void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
+{
+       int i, saw_mem, saw_io;
+
+       saw_mem = saw_io = 0;
+       for (i = 0; i < pbm->num_pbm_ranges; i++) {
+               struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i];
+               unsigned long a;
+               int type;
+
+               type = (pr->child_phys_hi >> 24) & 0x3;
+               a = (((unsigned long)pr->parent_phys_hi << 32UL) |
+                    ((unsigned long)pr->parent_phys_lo  <<  0UL));
+
+               switch (type) {
+               case 0:
+                       /* PCI config space, 16MB */
+                       pbm->config_space = a;
+                       break;
+
+               case 1:
+                       /* 16-bit IO space, 16MB */
+                       pbm->io_space.start = a;
+                       pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL);
+                       pbm->io_space.flags = IORESOURCE_IO;
+                       saw_io = 1;
+                       break;
+
+               case 2:
+                       /* 32-bit MEM space, 2GB */
+                       pbm->mem_space.start = a;
+                       pbm->mem_space.end = a + (0x80000000UL - 1UL);
+                       pbm->mem_space.flags = IORESOURCE_MEM;
+                       saw_mem = 1;
+                       break;
+
+               case 3:
+                       /* XXX 64-bit MEM handling XXX */
+
+               default:
+                       break;
+               };
+       }
+
+       if (!saw_io || !saw_mem) {
+               prom_printf("%s: Fatal error, missing %s PBM range.\n",
+                           pbm->name,
+                           (!saw_io ? "IO" : "MEM"));
+               prom_halt();
+       }
+
+       printk("%s: PCI IO[%lx] MEM[%lx]\n",
+              pbm->name,
+              pbm->io_space.start,
+              pbm->mem_space.start);
+
+       pbm->io_space.name = pbm->mem_space.name = pbm->name;
+
+       request_resource(&ioport_resource, &pbm->io_space);
+       request_resource(&iomem_resource, &pbm->mem_space);
+
+       pci_register_legacy_regions(&pbm->io_space,
+                                   &pbm->mem_space);
+       pci_register_iommu_region(pbm);
+}
+
 /* Generic helper routines for PCI error reporting. */
 void pci_scan_for_target_abort(struct pci_controller_info *p,
                               struct pci_pbm_info *pbm,
index c4ba702e1fd91abbbbac6cc300e8d8b484d0a65b..c6714548d8230b1aa6f7df4c6f6f22db4dc63484 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: pci_impl.h,v 1.9 2001/06/13 06:34:30 davem Exp $
- * pci_impl.h: Helper definitions for PCI controller support.
+/* pci_impl.h: Helper definitions for PCI controller support.
  *
- * Copyright (C) 1999 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #ifndef PCI_IMPL_H
@@ -19,8 +18,7 @@ extern int pci_num_controllers;
 
 /* PCI bus scanning and fixup support. */
 extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm);
-extern void pci_register_legacy_regions(struct resource *io_res,
-                                       struct resource *mem_res);
+extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
 
 /* Error reporting support. */
 extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *);
index 12ea30d30b2f20e5b38be75892471ffae8a4c093..c08681b7a44e6660bc9b16de694d7a89cf079eb4 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: pci_psycho.c,v 1.33 2002/02/01 00:58:33 davem Exp $
- * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
+/* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
  *
- * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
+ * Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1998, 1999 Eddie C. Dost   (ecd@skynet.be)
  * Copyright (C) 1999 Jakub Jelinek   (jakub@redhat.com)
  */
@@ -1072,19 +1071,6 @@ static void psycho_controller_hwinit(struct pci_controller_info *p)
        psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp);
 }
 
-static void pbm_register_toplevel_resources(struct pci_controller_info *p,
-                                           struct pci_pbm_info *pbm)
-{
-       char *name = pbm->name;
-
-       pbm->io_space.name = pbm->mem_space.name = name;
-
-       request_resource(&ioport_resource, &pbm->io_space);
-       request_resource(&iomem_resource, &pbm->mem_space);
-       pci_register_legacy_regions(&pbm->io_space,
-                                   &pbm->mem_space);
-}
-
 static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
                                   struct pci_pbm_info *pbm,
                                   int is_pbm_a)
@@ -1155,13 +1141,9 @@ static void psycho_pbm_init(struct pci_controller_info *p,
        if (is_pbm_a) {
                pbm = &p->pbm_A;
                pbm->pci_first_slot = 1;
-               pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_A;
-               pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_A;
        } else {
                pbm = &p->pbm_B;
                pbm->pci_first_slot = 2;
-               pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_B;
-               pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_B;
        }
 
        pbm->chip_type = PBM_CHIP_TYPE_PSYCHO;
@@ -1174,17 +1156,12 @@ static void psycho_pbm_init(struct pci_controller_info *p,
        if (prop)
                pbm->chip_revision = *(int *) prop->value;
 
-       pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE;
-       pbm->io_space.flags = IORESOURCE_IO;
-       pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE;
-       pbm->mem_space.flags = IORESOURCE_MEM;
+       pci_determine_mem_io_space(pbm);
 
        pbm->parent = p;
        pbm->prom_node = dp;
        pbm->name = dp->full_name;
 
-       pbm_register_toplevel_resources(p, pbm);
-
        printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
               pbm->name,
               pbm->chip_version, pbm->chip_revision);
index f4e346092a53addabcf8698bb461b6fadd022739..2dad171b54e2dceab09112b5fe2f32489ffee5c3 100644 (file)
@@ -1045,10 +1045,9 @@ static void sabre_iommu_init(struct pci_controller_info *p,
        sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
 }
 
-static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end)
+static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp)
 {
        struct pci_pbm_info *pbm;
-       struct resource *rp;
 
        pbm = &p->pbm_A;
        pbm->name = dp->full_name;
@@ -1061,38 +1060,7 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
        pbm->pci_first_busno = p->pci_first_busno;
        pbm->pci_last_busno = p->pci_last_busno;
 
-       pbm->io_space.name = pbm->mem_space.name = pbm->name;
-
-       pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE;
-       pbm->io_space.end   = pbm->io_space.start + (1UL << 24) - 1UL;
-       pbm->io_space.flags = IORESOURCE_IO;
-
-       pbm->mem_space.start = (p->pbm_A.controller_regs + SABRE_MEMSPACE);
-       pbm->mem_space.end = (pbm->mem_space.start + ((1UL << 32UL) - 1UL));
-       pbm->mem_space.flags = IORESOURCE_MEM;
-
-       if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
-               prom_printf("Cannot register Sabre's IO space.\n");
-               prom_halt();
-       }
-       if (request_resource(&iomem_resource, &pbm->mem_space) < 0) {
-               prom_printf("Cannot register Sabre's MEM space.\n");
-               prom_halt();
-       }
-
-       rp = kmalloc(sizeof(*rp), GFP_KERNEL);
-       if (!rp) {
-               prom_printf("Cannot allocate IOMMU resource.\n");
-               prom_halt();
-       }
-       rp->name = "IOMMU";
-       rp->start = pbm->mem_space.start + (unsigned long) dma_start;
-       rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL;
-       rp->flags = IORESOURCE_BUSY;
-       request_resource(&pbm->mem_space, rp);
-
-       pci_register_legacy_regions(&pbm->io_space,
-                                   &pbm->mem_space);
+       pci_determine_mem_io_space(pbm);
 }
 
 void sabre_init(struct device_node *dp, char *model_name)
@@ -1212,5 +1180,5 @@ void sabre_init(struct device_node *dp, char *model_name)
        /*
         * Look for APB underneath.
         */
-       sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]);
+       sabre_pbm_init(p, dp);
 }
index 332cfd9736b70264adcd9e9d9907b556346ae5fb..79ad2688317b1b532261333347efd7ca8dd4e951 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: pci_schizo.c,v 1.24 2002/01/23 11:27:32 davem Exp $
- * pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support.
+/* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support.
  *
- * Copyright (C) 2001, 2002, 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2001, 2002, 2003, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/kernel.h>
@@ -1304,79 +1303,6 @@ static void schizo_resource_adjust(struct pci_dev *pdev,
        res->end += root->start;
 }
 
-/* Use ranges property to determine where PCI MEM, I/O, and Config
- * space are for this PCI bus module.
- */
-static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm)
-{
-       int i, saw_cfg, saw_mem, saw_io;
-
-       saw_cfg = saw_mem = saw_io = 0;
-       for (i = 0; i < pbm->num_pbm_ranges; i++) {
-               struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i];
-               unsigned long a;
-               int type;
-
-               type = (pr->child_phys_hi >> 24) & 0x3;
-               a = (((unsigned long)pr->parent_phys_hi << 32UL) |
-                    ((unsigned long)pr->parent_phys_lo  <<  0UL));
-
-               switch (type) {
-               case 0:
-                       /* PCI config space, 16MB */
-                       pbm->config_space = a;
-                       saw_cfg = 1;
-                       break;
-
-               case 1:
-                       /* 16-bit IO space, 16MB */
-                       pbm->io_space.start = a;
-                       pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL);
-                       pbm->io_space.flags = IORESOURCE_IO;
-                       saw_io = 1;
-                       break;
-
-               case 2:
-                       /* 32-bit MEM space, 2GB */
-                       pbm->mem_space.start = a;
-                       pbm->mem_space.end = a + (0x80000000UL - 1UL);
-                       pbm->mem_space.flags = IORESOURCE_MEM;
-                       saw_mem = 1;
-                       break;
-
-               default:
-                       break;
-               };
-       }
-
-       if (!saw_cfg || !saw_io || !saw_mem) {
-               prom_printf("%s: Fatal error, missing %s PBM range.\n",
-                           pbm->name,
-                           ((!saw_cfg ?
-                             "CFG" :
-                             (!saw_io ?
-                              "IO" : "MEM"))));
-               prom_halt();
-       }
-
-       printk("%s: PCI CFG[%lx] IO[%lx] MEM[%lx]\n",
-              pbm->name,
-              pbm->config_space,
-              pbm->io_space.start,
-              pbm->mem_space.start);
-}
-
-static void pbm_register_toplevel_resources(struct pci_controller_info *p,
-                                           struct pci_pbm_info *pbm)
-{
-       pbm->io_space.name = pbm->mem_space.name = pbm->name;
-
-       request_resource(&ioport_resource, &pbm->io_space);
-       request_resource(&iomem_resource, &pbm->mem_space);
-       pci_register_legacy_regions(&pbm->io_space,
-                                   &pbm->mem_space);
-}
-
 #define SCHIZO_STRBUF_CONTROL          (0x02800UL)
 #define SCHIZO_STRBUF_FLUSH            (0x02808UL)
 #define SCHIZO_STRBUF_FSYNC            (0x02810UL)
@@ -1679,8 +1605,7 @@ static void schizo_pbm_init(struct pci_controller_info *p,
        pbm->num_pbm_ranges =
                (len / sizeof(struct linux_prom_pci_ranges));
 
-       schizo_determine_mem_io_space(pbm);
-       pbm_register_toplevel_resources(p, pbm);
+       pci_determine_mem_io_space(pbm);
 
        pbm->pbm_intmap = of_get_property(dp, "interrupt-map", &len);
        if (pbm->pbm_intmap) {
index eec7def379dc835f994f78396ac46da823a8b003..e1af009617cf5a014bd5751318eb0acbc1c34b36 100644 (file)
@@ -1,6 +1,6 @@
 /* pci_sun4v.c: SUN4V specific PCI controller support.
  *
- * Copyright (C) 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/kernel.h>
@@ -751,72 +751,6 @@ static void pci_sun4v_resource_adjust(struct pci_dev *pdev,
        res->end += root->start;
 }
 
-/* Use ranges property to determine where PCI MEM, I/O, and Config
- * space are for this PCI bus module.
- */
-static void pci_sun4v_determine_mem_io_space(struct pci_pbm_info *pbm)
-{
-       int i, saw_mem, saw_io;
-
-       saw_mem = saw_io = 0;
-       for (i = 0; i < pbm->num_pbm_ranges; i++) {
-               struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i];
-               unsigned long a;
-               int type;
-
-               type = (pr->child_phys_hi >> 24) & 0x3;
-               a = (((unsigned long)pr->parent_phys_hi << 32UL) |
-                    ((unsigned long)pr->parent_phys_lo  <<  0UL));
-
-               switch (type) {
-               case 1:
-                       /* 16-bit IO space, 16MB */
-                       pbm->io_space.start = a;
-                       pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL);
-                       pbm->io_space.flags = IORESOURCE_IO;
-                       saw_io = 1;
-                       break;
-
-               case 2:
-                       /* 32-bit MEM space, 2GB */
-                       pbm->mem_space.start = a;
-                       pbm->mem_space.end = a + (0x80000000UL - 1UL);
-                       pbm->mem_space.flags = IORESOURCE_MEM;
-                       saw_mem = 1;
-                       break;
-
-               case 3:
-                       /* XXX 64-bit MEM handling XXX */
-
-               default:
-                       break;
-               };
-       }
-
-       if (!saw_io || !saw_mem) {
-               prom_printf("%s: Fatal error, missing %s PBM range.\n",
-                           pbm->name,
-                           (!saw_io ? "IO" : "MEM"));
-               prom_halt();
-       }
-
-       printk("%s: PCI IO[%lx] MEM[%lx]\n",
-              pbm->name,
-              pbm->io_space.start,
-              pbm->mem_space.start);
-}
-
-static void pbm_register_toplevel_resources(struct pci_controller_info *p,
-                                           struct pci_pbm_info *pbm)
-{
-       pbm->io_space.name = pbm->mem_space.name = pbm->name;
-
-       request_resource(&ioport_resource, &pbm->io_space);
-       request_resource(&iomem_resource, &pbm->mem_space);
-       pci_register_legacy_regions(&pbm->io_space,
-                                   &pbm->mem_space);
-}
-
 static unsigned long probe_existing_entries(struct pci_pbm_info *pbm,
                                            struct pci_iommu *iommu)
 {
@@ -1396,8 +1330,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
        for (i = 0; i < pbm->num_pbm_ranges; i++)
                pbm->pbm_ranges[i].parent_phys_hi &= 0x0fffffff;
 
-       pci_sun4v_determine_mem_io_space(pbm);
-       pbm_register_toplevel_resources(p, pbm);
+       pci_determine_mem_io_space(pbm);
 
        prop = of_find_property(dp, "interrupt-map", &len);
        pbm->pbm_intmap = prop->value;