]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sparc64/kernel/pci_schizo.c
Merge branch 'sg' of git://git.kernel.dk/linux-2.6-block
[linux-2.6-omap-h63xx.git] / arch / sparc64 / kernel / pci_schizo.c
index e375d72b8eed0acf1ab8b46a7038008325512c33..9546ba9f5dee5c5b16b76c77c1324aeacb484b68 100644 (file)
@@ -104,125 +104,6 @@ static void *schizo_pci_config_mkaddr(struct pci_pbm_info *pbm,
                 SCHIZO_CONFIG_ENCODE(bus, devfn, where));
 }
 
-/* Just make sure the bus number is in range.  */
-static int schizo_out_of_range(struct pci_pbm_info *pbm,
-                              unsigned char bus,
-                              unsigned char devfn)
-{
-       if (bus < pbm->pci_first_busno ||
-           bus > pbm->pci_last_busno)
-               return 1;
-       return 0;
-}
-
-/* SCHIZO PCI configuration space accessors. */
-
-static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                              int where, int size, u32 *value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-       u16 tmp16;
-       u8 tmp8;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
-                                                   size, value);
-       switch (size) {
-       case 1:
-               *value = 0xff;
-               break;
-       case 2:
-               *value = 0xffff;
-               break;
-       case 4:
-               *value = 0xffffffff;
-               break;
-       }
-
-       addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       if (schizo_out_of_range(pbm, bus, devfn))
-               return PCIBIOS_SUCCESSFUL;
-       switch (size) {
-       case 1:
-               pci_config_read8((u8 *)addr, &tmp8);
-               *value = tmp8;
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_read_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read16((u16 *)addr, &tmp16);
-               *value = tmp16;
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_read_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read32(addr, value);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                               int where, int size, u32 value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
-                                                    size, value);
-       addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       if (schizo_out_of_range(pbm, bus, devfn))
-               return PCIBIOS_SUCCESSFUL;
-
-       switch (size) {
-       case 1:
-               pci_config_write8((u8 *)addr, value);
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_write_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_write16((u16 *)addr, value);
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_write_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-
-               pci_config_write32(addr, value);
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops schizo_ops = {
-       .read =         schizo_read_pci_cfg,
-       .write =        schizo_write_pci_cfg,
-};
-
 /* SCHIZO error handling support. */
 enum schizo_error_type {
        UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR
@@ -1267,14 +1148,14 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm)
 #define SCHIZO_IOMMU_FLUSH             (0x00210UL)
 #define SCHIZO_IOMMU_CTXFLUSH          (0x00218UL)
 
-static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
+static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
 {
        struct iommu *iommu = pbm->iommu;
        unsigned long i, tagbase, database;
        struct property *prop;
        u32 vdma[2], dma_mask;
+       int tsbsize, err;
        u64 control;
-       int tsbsize;
 
        prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
        if (prop) {
@@ -1314,6 +1195,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
        iommu->iommu_control  = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
        iommu->iommu_tsbbase  = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;
        iommu->iommu_flush    = pbm->pbm_regs + SCHIZO_IOMMU_FLUSH;
+       iommu->iommu_tags     = iommu->iommu_flush + (0xa580UL - 0x0210UL);
        iommu->iommu_ctxflush = pbm->pbm_regs + SCHIZO_IOMMU_CTXFLUSH;
 
        /* We use the main control/status register of SCHIZO as the write
@@ -1338,7 +1220,9 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
        /* Leave diag mode enabled for full-flushing done
         * in pci_iommu.c
         */
-       pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
+       err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
+       if (err)
+               return err;
 
        schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table));
 
@@ -1355,6 +1239,8 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
 
        control |= SCHIZO_IOMMU_CTRL_ENAB;
        schizo_write(iommu->iommu_control, control);
+
+       return 0;
 }
 
 #define SCHIZO_PCI_IRQ_RETRY   (0x1a00UL)
@@ -1447,14 +1333,14 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
        }
 }
 
-static void schizo_pbm_init(struct pci_controller_info *p,
-                           struct device_node *dp, u32 portid,
-                           int chip_type)
+static int schizo_pbm_init(struct pci_controller_info *p,
+                          struct device_node *dp, u32 portid,
+                          int chip_type)
 {
        const struct linux_prom64_registers *regs;
        struct pci_pbm_info *pbm;
        const char *chipset_name;
-       int is_pbm_a;
+       int is_pbm_a, err;
 
        switch (chip_type) {
        case PBM_CHIP_TYPE_TOMATILLO:
@@ -1494,7 +1380,8 @@ static void schizo_pbm_init(struct pci_controller_info *p,
        pci_pbm_root = pbm;
 
        pbm->scan_bus = schizo_scan_bus;
-       pbm->pci_ops = &schizo_ops;
+       pbm->pci_ops = &sun4u_pci_ops;
+       pbm->config_space_reg_bits = 8;
 
        pbm->index = pci_num_pbms++;
 
@@ -1524,8 +1411,13 @@ static void schizo_pbm_init(struct pci_controller_info *p,
 
        pci_get_pbm_props(pbm);
 
-       schizo_pbm_iommu_init(pbm);
+       err = schizo_pbm_iommu_init(pbm);
+       if (err)
+               return err;
+
        schizo_pbm_strbuf_init(pbm);
+
+       return 0;
 }
 
 static inline int portid_compare(u32 x, u32 y, int chip_type)
@@ -1549,34 +1441,35 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ
 
        for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
                if (portid_compare(pbm->portid, portid, chip_type)) {
-                       schizo_pbm_init(pbm->parent, dp, portid, chip_type);
+                       if (schizo_pbm_init(pbm->parent, dp,
+                                           portid, chip_type))
+                               goto fatal_memory_error;
                        return;
                }
        }
 
        p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
        if (!p)
-               goto memfail;
+               goto fatal_memory_error;
 
        iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC);
        if (!iommu)
-               goto memfail;
+               goto fatal_memory_error;
 
        p->pbm_A.iommu = iommu;
 
        iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC);
        if (!iommu)
-               goto memfail;
+               goto fatal_memory_error;
 
        p->pbm_B.iommu = iommu;
 
-       /* Like PSYCHO we have a 2GB aligned area for memory space. */
-       pci_memspace_mask = 0x7fffffffUL;
+       if (schizo_pbm_init(p, dp, portid, chip_type))
+               goto fatal_memory_error;
 
-       schizo_pbm_init(p, dp, portid, chip_type);
        return;
 
-memfail:
+fatal_memory_error:
        prom_printf("SCHIZO: Fatal memory allocation error.\n");
        prom_halt();
 }