diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc64/kernel/pci.c | 15 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 117 |
2 files changed, 84 insertions, 48 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 83c50a62970d..73f1d42d4866 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -167,9 +167,6 @@ void pci_config_write32(u32 *addr, u32 val) | |||
167 | /* Probe for all PCI controllers in the system. */ | 167 | /* Probe for all PCI controllers in the system. */ |
168 | extern void sabre_init(struct device_node *, const char *); | 168 | extern void sabre_init(struct device_node *, const char *); |
169 | extern void psycho_init(struct device_node *, const char *); | 169 | extern void psycho_init(struct device_node *, const char *); |
170 | extern void schizo_init(struct device_node *, const char *); | ||
171 | extern void schizo_plus_init(struct device_node *, const char *); | ||
172 | extern void tomatillo_init(struct device_node *, const char *); | ||
173 | extern void sun4v_pci_init(struct device_node *, const char *); | 170 | extern void sun4v_pci_init(struct device_node *, const char *); |
174 | extern void fire_pci_init(struct device_node *, const char *); | 171 | extern void fire_pci_init(struct device_node *, const char *); |
175 | 172 | ||
@@ -182,12 +179,6 @@ static struct { | |||
182 | { "pci108e,a001", sabre_init }, | 179 | { "pci108e,a001", sabre_init }, |
183 | { "SUNW,psycho", psycho_init }, | 180 | { "SUNW,psycho", psycho_init }, |
184 | { "pci108e,8000", psycho_init }, | 181 | { "pci108e,8000", psycho_init }, |
185 | { "SUNW,schizo", schizo_init }, | ||
186 | { "pci108e,8001", schizo_init }, | ||
187 | { "SUNW,schizo+", schizo_plus_init }, | ||
188 | { "pci108e,8002", schizo_plus_init }, | ||
189 | { "SUNW,tomatillo", tomatillo_init }, | ||
190 | { "pci108e,a801", tomatillo_init }, | ||
191 | { "SUNW,sun4v-pci", sun4v_pci_init }, | 182 | { "SUNW,sun4v-pci", sun4v_pci_init }, |
192 | { "pciex108e,80f0", fire_pci_init }, | 183 | { "pciex108e,80f0", fire_pci_init }, |
193 | }; | 184 | }; |
@@ -795,8 +786,10 @@ static void __init pci_scan_each_controller_bus(void) | |||
795 | { | 786 | { |
796 | struct pci_pbm_info *pbm; | 787 | struct pci_pbm_info *pbm; |
797 | 788 | ||
798 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) | 789 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
799 | pbm->scan_bus(pbm); | 790 | if (pbm->scan_bus) |
791 | pbm->scan_bus(pbm); | ||
792 | } | ||
800 | } | 793 | } |
801 | 794 | ||
802 | static int __init pcibios_init(void) | 795 | static int __init pcibios_init(void) |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 9248c6737f0e..b95dd548583a 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support. | 1 | /* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support. |
2 | * | 2 | * |
3 | * Copyright (C) 2001, 2002, 2003, 2007 David S. Miller (davem@davemloft.net) | 3 | * Copyright (C) 2001, 2002, 2003, 2007, 2008 David S. Miller (davem@davemloft.net) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
@@ -13,14 +13,15 @@ | |||
13 | 13 | ||
14 | #include <asm/iommu.h> | 14 | #include <asm/iommu.h> |
15 | #include <asm/irq.h> | 15 | #include <asm/irq.h> |
16 | #include <asm/upa.h> | ||
17 | #include <asm/pstate.h> | 16 | #include <asm/pstate.h> |
18 | #include <asm/prom.h> | 17 | #include <asm/prom.h> |
19 | #include <asm/oplib.h> | ||
20 | 18 | ||
21 | #include "pci_impl.h" | 19 | #include "pci_impl.h" |
22 | #include "iommu_common.h" | 20 | #include "iommu_common.h" |
23 | 21 | ||
22 | #define DRIVER_NAME "schizo" | ||
23 | #define PFX DRIVER_NAME ": " | ||
24 | |||
24 | /* All SCHIZO registers are 64-bits. The following accessor | 25 | /* All SCHIZO registers are 64-bits. The following accessor |
25 | * routines are how they are accessed. The REG parameter | 26 | * routines are how they are accessed. The REG parameter |
26 | * is a physical address. | 27 | * is a physical address. |
@@ -1084,7 +1085,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
1084 | pci_config_write8(addr, 64); | 1085 | pci_config_write8(addr, 64); |
1085 | } | 1086 | } |
1086 | 1087 | ||
1087 | static void __init schizo_scan_bus(struct pci_pbm_info *pbm) | 1088 | static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm) |
1088 | { | 1089 | { |
1089 | pbm_config_busmastering(pbm); | 1090 | pbm_config_busmastering(pbm); |
1090 | pbm->is_66mhz_capable = | 1091 | pbm->is_66mhz_capable = |
@@ -1187,9 +1188,9 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1187 | break; | 1188 | break; |
1188 | 1189 | ||
1189 | default: | 1190 | default: |
1190 | prom_printf("SCHIZO: strange virtual-dma size.\n"); | 1191 | printk(KERN_ERR PFX "Strange virtual-dma size.\n"); |
1191 | prom_halt(); | 1192 | return -EINVAL; |
1192 | }; | 1193 | } |
1193 | 1194 | ||
1194 | /* Register addresses, SCHIZO has iommu ctx flushing. */ | 1195 | /* Register addresses, SCHIZO has iommu ctx flushing. */ |
1195 | iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; | 1196 | iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; |
@@ -1212,7 +1213,7 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1212 | 1213 | ||
1213 | tagbase = SCHIZO_IOMMU_TAG, database = SCHIZO_IOMMU_DATA; | 1214 | tagbase = SCHIZO_IOMMU_TAG, database = SCHIZO_IOMMU_DATA; |
1214 | 1215 | ||
1215 | for(i = 0; i < 16; i++) { | 1216 | for (i = 0; i < 16; i++) { |
1216 | schizo_write(pbm->pbm_regs + tagbase + (i * 8UL), 0); | 1217 | schizo_write(pbm->pbm_regs + tagbase + (i * 8UL), 0); |
1217 | schizo_write(pbm->pbm_regs + database + (i * 8UL), 0); | 1218 | schizo_write(pbm->pbm_regs + database + (i * 8UL), 0); |
1218 | } | 1219 | } |
@@ -1222,8 +1223,10 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1222 | */ | 1223 | */ |
1223 | err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask, | 1224 | err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask, |
1224 | pbm->numa_node); | 1225 | pbm->numa_node); |
1225 | if (err) | 1226 | if (err) { |
1227 | printk(KERN_ERR PFX "iommu_table_init() fails with %d\n", err); | ||
1226 | return err; | 1228 | return err; |
1229 | } | ||
1227 | 1230 | ||
1228 | schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table)); | 1231 | schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table)); |
1229 | 1232 | ||
@@ -1236,7 +1239,7 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1236 | case 128: | 1239 | case 128: |
1237 | control |= SCHIZO_IOMMU_TSBSZ_128K; | 1240 | control |= SCHIZO_IOMMU_TSBSZ_128K; |
1238 | break; | 1241 | break; |
1239 | }; | 1242 | } |
1240 | 1243 | ||
1241 | control |= SCHIZO_IOMMU_CTRL_ENAB; | 1244 | control |= SCHIZO_IOMMU_CTRL_ENAB; |
1242 | schizo_write(iommu->iommu_control, control); | 1245 | schizo_write(iommu->iommu_control, control); |
@@ -1334,9 +1337,9 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) | |||
1334 | } | 1337 | } |
1335 | } | 1338 | } |
1336 | 1339 | ||
1337 | static int __init schizo_pbm_init(struct pci_controller_info *p, | 1340 | static int __devinit schizo_pbm_init(struct pci_controller_info *p, |
1338 | struct device_node *dp, u32 portid, | 1341 | struct device_node *dp, u32 portid, |
1339 | int chip_type) | 1342 | int chip_type) |
1340 | { | 1343 | { |
1341 | const struct linux_prom64_registers *regs; | 1344 | const struct linux_prom64_registers *regs; |
1342 | struct pci_pbm_info *pbm; | 1345 | struct pci_pbm_info *pbm; |
@@ -1382,7 +1385,6 @@ static int __init schizo_pbm_init(struct pci_controller_info *p, | |||
1382 | 1385 | ||
1383 | pbm->numa_node = -1; | 1386 | pbm->numa_node = -1; |
1384 | 1387 | ||
1385 | pbm->scan_bus = schizo_scan_bus; | ||
1386 | pbm->pci_ops = &sun4u_pci_ops; | 1388 | pbm->pci_ops = &sun4u_pci_ops; |
1387 | pbm->config_space_reg_bits = 8; | 1389 | pbm->config_space_reg_bits = 8; |
1388 | 1390 | ||
@@ -1420,6 +1422,8 @@ static int __init schizo_pbm_init(struct pci_controller_info *p, | |||
1420 | 1422 | ||
1421 | schizo_pbm_strbuf_init(pbm); | 1423 | schizo_pbm_strbuf_init(pbm); |
1422 | 1424 | ||
1425 | schizo_scan_bus(pbm); | ||
1426 | |||
1423 | return 0; | 1427 | return 0; |
1424 | } | 1428 | } |
1425 | 1429 | ||
@@ -1433,8 +1437,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) | |||
1433 | return (x == y); | 1437 | return (x == y); |
1434 | } | 1438 | } |
1435 | 1439 | ||
1436 | static void __init __schizo_init(struct device_node *dp, char *model_name, | 1440 | static int __devinit __schizo_init(struct device_node *dp, unsigned long chip_type) |
1437 | int chip_type) | ||
1438 | { | 1441 | { |
1439 | struct pci_controller_info *p; | 1442 | struct pci_controller_info *p; |
1440 | struct pci_pbm_info *pbm; | 1443 | struct pci_pbm_info *pbm; |
@@ -1447,48 +1450,88 @@ static void __init __schizo_init(struct device_node *dp, char *model_name, | |||
1447 | if (portid_compare(pbm->portid, portid, chip_type)) { | 1450 | if (portid_compare(pbm->portid, portid, chip_type)) { |
1448 | if (schizo_pbm_init(pbm->parent, dp, | 1451 | if (schizo_pbm_init(pbm->parent, dp, |
1449 | portid, chip_type)) | 1452 | portid, chip_type)) |
1450 | goto fatal_memory_error; | 1453 | return -ENOMEM; |
1451 | return; | 1454 | return 0; |
1452 | } | 1455 | } |
1453 | } | 1456 | } |
1454 | 1457 | ||
1455 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | 1458 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); |
1456 | if (!p) | 1459 | if (!p) { |
1457 | goto fatal_memory_error; | 1460 | printk(KERN_ERR PFX "Cannot allocate controller info.\n"); |
1461 | goto out_free; | ||
1462 | } | ||
1458 | 1463 | ||
1459 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 1464 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); |
1460 | if (!iommu) | 1465 | if (!iommu) { |
1461 | goto fatal_memory_error; | 1466 | printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); |
1467 | goto out_free; | ||
1468 | } | ||
1462 | 1469 | ||
1463 | p->pbm_A.iommu = iommu; | 1470 | p->pbm_A.iommu = iommu; |
1464 | 1471 | ||
1465 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 1472 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); |
1466 | if (!iommu) | 1473 | if (!iommu) { |
1467 | goto fatal_memory_error; | 1474 | printk(KERN_ERR PFX "Cannot allocate PBM B iommu.\n"); |
1475 | goto out_free; | ||
1476 | } | ||
1468 | 1477 | ||
1469 | p->pbm_B.iommu = iommu; | 1478 | p->pbm_B.iommu = iommu; |
1470 | 1479 | ||
1471 | if (schizo_pbm_init(p, dp, portid, chip_type)) | 1480 | if (schizo_pbm_init(p, dp, portid, chip_type)) |
1472 | goto fatal_memory_error; | 1481 | goto out_free; |
1473 | 1482 | ||
1474 | return; | 1483 | return 0; |
1475 | 1484 | ||
1476 | fatal_memory_error: | 1485 | out_free: |
1477 | prom_printf("SCHIZO: Fatal memory allocation error.\n"); | 1486 | if (p) { |
1478 | prom_halt(); | 1487 | if (p->pbm_A.iommu) |
1488 | kfree(p->pbm_A.iommu); | ||
1489 | if (p->pbm_B.iommu) | ||
1490 | kfree(p->pbm_B.iommu); | ||
1491 | kfree(p); | ||
1492 | } | ||
1493 | return -ENOMEM; | ||
1479 | } | 1494 | } |
1480 | 1495 | ||
1481 | void __init schizo_init(struct device_node *dp, char *model_name) | 1496 | static int __devinit schizo_probe(struct of_device *op, |
1497 | const struct of_device_id *match) | ||
1482 | { | 1498 | { |
1483 | __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO); | 1499 | return __schizo_init(op->node, (unsigned long) match->data); |
1484 | } | 1500 | } |
1485 | 1501 | ||
1486 | void __init schizo_plus_init(struct device_node *dp, char *model_name) | 1502 | /* The ordering of this table is very important. Some Tomatillo |
1487 | { | 1503 | * nodes announce that they are compatible with both pci108e,a801 |
1488 | __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); | 1504 | * and pci108e,8001. So list the chips in reverse chronological |
1489 | } | 1505 | * order. |
1506 | */ | ||
1507 | static struct of_device_id schizo_match[] = { | ||
1508 | { | ||
1509 | .name = "pci", | ||
1510 | .compatible = "pci108e,a801", | ||
1511 | .data = (void *) PBM_CHIP_TYPE_TOMATILLO, | ||
1512 | }, | ||
1513 | { | ||
1514 | .name = "pci", | ||
1515 | .compatible = "pci108e,8002", | ||
1516 | .data = (void *) PBM_CHIP_TYPE_SCHIZO_PLUS, | ||
1517 | }, | ||
1518 | { | ||
1519 | .name = "pci", | ||
1520 | .compatible = "pci108e,8001", | ||
1521 | .data = (void *) PBM_CHIP_TYPE_SCHIZO, | ||
1522 | }, | ||
1523 | {}, | ||
1524 | }; | ||
1490 | 1525 | ||
1491 | void __init tomatillo_init(struct device_node *dp, char *model_name) | 1526 | static struct of_platform_driver schizo_driver = { |
1527 | .name = DRIVER_NAME, | ||
1528 | .match_table = schizo_match, | ||
1529 | .probe = schizo_probe, | ||
1530 | }; | ||
1531 | |||
1532 | static int __init schizo_init(void) | ||
1492 | { | 1533 | { |
1493 | __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO); | 1534 | return of_register_driver(&schizo_driver, &of_bus_type); |
1494 | } | 1535 | } |
1536 | |||
1537 | subsys_initcall(schizo_init); | ||