aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_schizo.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-28 01:39:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-30 03:27:34 -0400
commitad7ad57c6127042c411353dddb723765964815db (patch)
tree600484291d9cfa68d54dc9b230f5bd115f495213 /arch/sparc64/kernel/pci_schizo.c
parentc7f439b99efbea74c70a5531f92566db5a6731f2 (diff)
[SPARC64]: Fix conflicts in SBUS/PCI/EBUS/ISA DMA handling.
Fully unify all of the DMA ops so that subordinate bus types to the DMA operation providers (such as ebus, isa, of_device) can work transparently. Basically, we just make sure that for every system device we create, the dev->archdata 'iommu' and 'stc' fields are filled in. Then we have two platform variants of the DMA ops, one for SUN4U which actually programs the real hardware, and one for SUN4V which makes hypervisor calls. This also fixes the crashes in parport_pc on sparc64, reported by Meelis Roos. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_schizo.c')
-rw-r--r--arch/sparc64/kernel/pci_schizo.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index ae76898bbe2b..3c30bfa1f3a3 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -1148,14 +1148,14 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm)
1148#define SCHIZO_IOMMU_FLUSH (0x00210UL) 1148#define SCHIZO_IOMMU_FLUSH (0x00210UL)
1149#define SCHIZO_IOMMU_CTXFLUSH (0x00218UL) 1149#define SCHIZO_IOMMU_CTXFLUSH (0x00218UL)
1150 1150
1151static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) 1151static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1152{ 1152{
1153 struct iommu *iommu = pbm->iommu; 1153 struct iommu *iommu = pbm->iommu;
1154 unsigned long i, tagbase, database; 1154 unsigned long i, tagbase, database;
1155 struct property *prop; 1155 struct property *prop;
1156 u32 vdma[2], dma_mask; 1156 u32 vdma[2], dma_mask;
1157 int tsbsize, err;
1157 u64 control; 1158 u64 control;
1158 int tsbsize;
1159 1159
1160 prop = of_find_property(pbm->prom_node, "virtual-dma", NULL); 1160 prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
1161 if (prop) { 1161 if (prop) {
@@ -1195,6 +1195,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1195 iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; 1195 iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
1196 iommu->iommu_tsbbase = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE; 1196 iommu->iommu_tsbbase = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;
1197 iommu->iommu_flush = pbm->pbm_regs + SCHIZO_IOMMU_FLUSH; 1197 iommu->iommu_flush = pbm->pbm_regs + SCHIZO_IOMMU_FLUSH;
1198 iommu->iommu_tags = iommu->iommu_flush + (0xa580UL - 0x0210UL);
1198 iommu->iommu_ctxflush = pbm->pbm_regs + SCHIZO_IOMMU_CTXFLUSH; 1199 iommu->iommu_ctxflush = pbm->pbm_regs + SCHIZO_IOMMU_CTXFLUSH;
1199 1200
1200 /* We use the main control/status register of SCHIZO as the write 1201 /* We use the main control/status register of SCHIZO as the write
@@ -1219,7 +1220,9 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1219 /* Leave diag mode enabled for full-flushing done 1220 /* Leave diag mode enabled for full-flushing done
1220 * in pci_iommu.c 1221 * in pci_iommu.c
1221 */ 1222 */
1222 pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask); 1223 err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
1224 if (err)
1225 return err;
1223 1226
1224 schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table)); 1227 schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table));
1225 1228
@@ -1236,6 +1239,8 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1236 1239
1237 control |= SCHIZO_IOMMU_CTRL_ENAB; 1240 control |= SCHIZO_IOMMU_CTRL_ENAB;
1238 schizo_write(iommu->iommu_control, control); 1241 schizo_write(iommu->iommu_control, control);
1242
1243 return 0;
1239} 1244}
1240 1245
1241#define SCHIZO_PCI_IRQ_RETRY (0x1a00UL) 1246#define SCHIZO_PCI_IRQ_RETRY (0x1a00UL)
@@ -1328,14 +1333,14 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1328 } 1333 }
1329} 1334}
1330 1335
1331static void schizo_pbm_init(struct pci_controller_info *p, 1336static int schizo_pbm_init(struct pci_controller_info *p,
1332 struct device_node *dp, u32 portid, 1337 struct device_node *dp, u32 portid,
1333 int chip_type) 1338 int chip_type)
1334{ 1339{
1335 const struct linux_prom64_registers *regs; 1340 const struct linux_prom64_registers *regs;
1336 struct pci_pbm_info *pbm; 1341 struct pci_pbm_info *pbm;
1337 const char *chipset_name; 1342 const char *chipset_name;
1338 int is_pbm_a; 1343 int is_pbm_a, err;
1339 1344
1340 switch (chip_type) { 1345 switch (chip_type) {
1341 case PBM_CHIP_TYPE_TOMATILLO: 1346 case PBM_CHIP_TYPE_TOMATILLO:
@@ -1406,8 +1411,13 @@ static void schizo_pbm_init(struct pci_controller_info *p,
1406 1411
1407 pci_get_pbm_props(pbm); 1412 pci_get_pbm_props(pbm);
1408 1413
1409 schizo_pbm_iommu_init(pbm); 1414 err = schizo_pbm_iommu_init(pbm);
1415 if (err)
1416 return err;
1417
1410 schizo_pbm_strbuf_init(pbm); 1418 schizo_pbm_strbuf_init(pbm);
1419
1420 return 0;
1411} 1421}
1412 1422
1413static inline int portid_compare(u32 x, u32 y, int chip_type) 1423static inline int portid_compare(u32 x, u32 y, int chip_type)
@@ -1431,34 +1441,38 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ
1431 1441
1432 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { 1442 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
1433 if (portid_compare(pbm->portid, portid, chip_type)) { 1443 if (portid_compare(pbm->portid, portid, chip_type)) {
1434 schizo_pbm_init(pbm->parent, dp, portid, chip_type); 1444 if (schizo_pbm_init(pbm->parent, dp,
1445 portid, chip_type))
1446 goto fatal_memory_error;
1435 return; 1447 return;
1436 } 1448 }
1437 } 1449 }
1438 1450
1439 p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); 1451 p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
1440 if (!p) 1452 if (!p)
1441 goto memfail; 1453 goto fatal_memory_error;
1442 1454
1443 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); 1455 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC);
1444 if (!iommu) 1456 if (!iommu)
1445 goto memfail; 1457 goto fatal_memory_error;
1446 1458
1447 p->pbm_A.iommu = iommu; 1459 p->pbm_A.iommu = iommu;
1448 1460
1449 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); 1461 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC);
1450 if (!iommu) 1462 if (!iommu)
1451 goto memfail; 1463 goto fatal_memory_error;
1452 1464
1453 p->pbm_B.iommu = iommu; 1465 p->pbm_B.iommu = iommu;
1454 1466
1455 /* Like PSYCHO we have a 2GB aligned area for memory space. */ 1467 /* Like PSYCHO we have a 2GB aligned area for memory space. */
1456 pci_memspace_mask = 0x7fffffffUL; 1468 pci_memspace_mask = 0x7fffffffUL;
1457 1469
1458 schizo_pbm_init(p, dp, portid, chip_type); 1470 if (schizo_pbm_init(p, dp, portid, chip_type))
1471 goto fatal_memory_error;
1472
1459 return; 1473 return;
1460 1474
1461memfail: 1475fatal_memory_error:
1462 prom_printf("SCHIZO: Fatal memory allocation error.\n"); 1476 prom_printf("SCHIZO: Fatal memory allocation error.\n");
1463 prom_halt(); 1477 prom_halt();
1464} 1478}