aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-30 05:30:24 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-30 05:30:24 -0400
commit6d19c88f53bb3471a15152ea4fbdbebd36c0046c (patch)
tree8857194ba714fde8f32c76e2fb7b089ca525e63f
parentc510b9bfa1c34c1452f7a4389ff6de4f72a78193 (diff)
sparc64: Convert SCHIZO PCI controller driver into a real driver.
The idea is to convert all of the PCI controller drivers into genuine OF drivers, then we can get rid of this terrible probing table and infrastructure in arch/sparc64/kernel/pci.c Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/pci.c15
-rw-r--r--arch/sparc64/kernel/pci_schizo.c117
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. */
168extern void sabre_init(struct device_node *, const char *); 168extern void sabre_init(struct device_node *, const char *);
169extern void psycho_init(struct device_node *, const char *); 169extern void psycho_init(struct device_node *, const char *);
170extern void schizo_init(struct device_node *, const char *);
171extern void schizo_plus_init(struct device_node *, const char *);
172extern void tomatillo_init(struct device_node *, const char *);
173extern void sun4v_pci_init(struct device_node *, const char *); 170extern void sun4v_pci_init(struct device_node *, const char *);
174extern void fire_pci_init(struct device_node *, const char *); 171extern 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
802static int __init pcibios_init(void) 795static 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
1087static void __init schizo_scan_bus(struct pci_pbm_info *pbm) 1088static 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
1337static int __init schizo_pbm_init(struct pci_controller_info *p, 1340static 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
1436static void __init __schizo_init(struct device_node *dp, char *model_name, 1440static 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
1476fatal_memory_error: 1485out_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
1481void __init schizo_init(struct device_node *dp, char *model_name) 1496static 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
1486void __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 */
1507static 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
1491void __init tomatillo_init(struct device_node *dp, char *model_name) 1526static struct of_platform_driver schizo_driver = {
1527 .name = DRIVER_NAME,
1528 .match_table = schizo_match,
1529 .probe = schizo_probe,
1530};
1531
1532static 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
1537subsys_initcall(schizo_init);