aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_schizo.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/pci_schizo.c')
-rw-r--r--arch/sparc64/kernel/pci_schizo.c84
1 files changed, 37 insertions, 47 deletions
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index e1c565744d3f..67e3640bc69a 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -358,11 +358,12 @@ static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm,
358 spin_unlock_irqrestore(&iommu->lock, flags); 358 spin_unlock_irqrestore(&iommu->lock, flags);
359} 359}
360 360
361static void schizo_check_iommu_error(struct pci_controller_info *p, 361static void schizo_check_iommu_error(struct pci_pbm_info *pbm,
362 enum schizo_error_type type) 362 enum schizo_error_type type)
363{ 363{
364 schizo_check_iommu_error_pbm(&p->pbm_A, type); 364 schizo_check_iommu_error_pbm(pbm, type);
365 schizo_check_iommu_error_pbm(&p->pbm_B, type); 365 if (pbm->sibling)
366 schizo_check_iommu_error_pbm(pbm->sibling, type);
366} 367}
367 368
368/* Uncorrectable ECC error status gathering. */ 369/* Uncorrectable ECC error status gathering. */
@@ -387,7 +388,6 @@ static void schizo_check_iommu_error(struct pci_controller_info *p,
387static irqreturn_t schizo_ue_intr(int irq, void *dev_id) 388static irqreturn_t schizo_ue_intr(int irq, void *dev_id)
388{ 389{
389 struct pci_pbm_info *pbm = dev_id; 390 struct pci_pbm_info *pbm = dev_id;
390 struct pci_controller_info *p = pbm->parent;
391 unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR; 391 unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR;
392 unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR; 392 unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR;
393 unsigned long afsr, afar, error_bits; 393 unsigned long afsr, afar, error_bits;
@@ -450,7 +450,7 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id)
450 printk("]\n"); 450 printk("]\n");
451 451
452 /* Interrogate IOMMU for error status. */ 452 /* Interrogate IOMMU for error status. */
453 schizo_check_iommu_error(p, UE_ERR); 453 schizo_check_iommu_error(pbm, UE_ERR);
454 454
455 return IRQ_HANDLED; 455 return IRQ_HANDLED;
456} 456}
@@ -651,7 +651,6 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
651static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) 651static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id)
652{ 652{
653 struct pci_pbm_info *pbm = dev_id; 653 struct pci_pbm_info *pbm = dev_id;
654 struct pci_controller_info *p = pbm->parent;
655 unsigned long afsr_reg, afar_reg, base; 654 unsigned long afsr_reg, afar_reg, base;
656 unsigned long afsr, afar, error_bits; 655 unsigned long afsr, afar, error_bits;
657 int reported; 656 int reported;
@@ -745,7 +744,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id)
745 * a bug in the IOMMU support code or a PCI device driver. 744 * a bug in the IOMMU support code or a PCI device driver.
746 */ 745 */
747 if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { 746 if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) {
748 schizo_check_iommu_error(p, PCI_ERR); 747 schizo_check_iommu_error(pbm, PCI_ERR);
749 pci_scan_for_target_abort(pbm, pbm->pci_bus); 748 pci_scan_for_target_abort(pbm, pbm->pci_bus);
750 } 749 }
751 if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) 750 if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA))
@@ -806,7 +805,6 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id)
806static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) 805static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id)
807{ 806{
808 struct pci_pbm_info *pbm = dev_id; 807 struct pci_pbm_info *pbm = dev_id;
809 struct pci_controller_info *p = pbm->parent;
810 u64 errlog; 808 u64 errlog;
811 809
812 errlog = schizo_read(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG); 810 errlog = schizo_read(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG);
@@ -822,7 +820,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id)
822 820
823 printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", 821 printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n",
824 pbm->name); 822 pbm->name);
825 schizo_check_iommu_error(p, SAFARI_ERR); 823 schizo_check_iommu_error(pbm, SAFARI_ERR);
826 824
827 return IRQ_HANDLED; 825 return IRQ_HANDLED;
828} 826}
@@ -1329,13 +1327,12 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1329 } 1327 }
1330} 1328}
1331 1329
1332static int __devinit schizo_pbm_init(struct pci_controller_info *p, 1330static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm,
1333 struct of_device *op, u32 portid, 1331 struct of_device *op, u32 portid,
1334 int chip_type) 1332 int chip_type)
1335{ 1333{
1336 const struct linux_prom64_registers *regs; 1334 const struct linux_prom64_registers *regs;
1337 struct device_node *dp = op->node; 1335 struct device_node *dp = op->node;
1338 struct pci_pbm_info *pbm;
1339 const char *chipset_name; 1336 const char *chipset_name;
1340 int is_pbm_a, err; 1337 int is_pbm_a, err;
1341 1338
@@ -1368,10 +1365,6 @@ static int __devinit schizo_pbm_init(struct pci_controller_info *p,
1368 regs = of_get_property(dp, "reg", NULL); 1365 regs = of_get_property(dp, "reg", NULL);
1369 1366
1370 is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000); 1367 is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000);
1371 if (is_pbm_a)
1372 pbm = &p->pbm_A;
1373 else
1374 pbm = &p->pbm_B;
1375 1368
1376 pbm->next = pci_pbm_root; 1369 pbm->next = pci_pbm_root;
1377 pci_pbm_root = pbm; 1370 pci_pbm_root = pbm;
@@ -1384,7 +1377,6 @@ static int __devinit schizo_pbm_init(struct pci_controller_info *p,
1384 pbm->index = pci_num_pbms++; 1377 pbm->index = pci_num_pbms++;
1385 1378
1386 pbm->portid = portid; 1379 pbm->portid = portid;
1387 pbm->parent = p;
1388 pbm->prom_node = dp; 1380 pbm->prom_node = dp;
1389 1381
1390 pbm->chip_type = chip_type; 1382 pbm->chip_type = chip_type;
@@ -1430,10 +1422,21 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
1430 return (x == y); 1422 return (x == y);
1431} 1423}
1432 1424
1425static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid,
1426 int chip_type)
1427{
1428 struct pci_pbm_info *pbm;
1429
1430 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
1431 if (portid_compare(pbm->portid, portid, chip_type))
1432 return pbm;
1433 }
1434 return NULL;
1435}
1436
1433static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) 1437static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type)
1434{ 1438{
1435 struct device_node *dp = op->node; 1439 struct device_node *dp = op->node;
1436 struct pci_controller_info *p;
1437 struct pci_pbm_info *pbm; 1440 struct pci_pbm_info *pbm;
1438 struct iommu *iommu; 1441 struct iommu *iommu;
1439 u32 portid; 1442 u32 portid;
@@ -1442,50 +1445,37 @@ static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type
1442 portid = of_getintprop_default(dp, "portid", 0xff); 1445 portid = of_getintprop_default(dp, "portid", 0xff);
1443 1446
1444 err = -ENOMEM; 1447 err = -ENOMEM;
1445 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { 1448 pbm = kzalloc(sizeof(*pbm), GFP_KERNEL);
1446 if (portid_compare(pbm->portid, portid, chip_type)) { 1449 if (!pbm) {
1447 if (schizo_pbm_init(pbm->parent, op, 1450 printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n");
1448 portid, chip_type))
1449 goto out_err;
1450 return 0;
1451 }
1452 }
1453
1454 p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
1455 if (!p) {
1456 printk(KERN_ERR PFX "Cannot allocate controller info.\n");
1457 goto out_err; 1451 goto out_err;
1458 } 1452 }
1459 1453
1460 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); 1454 pbm->sibling = schizo_find_sibling(portid, chip_type);
1455
1456 iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL);
1461 if (!iommu) { 1457 if (!iommu) {
1462 printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); 1458 printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n");
1463 goto out_free_controller; 1459 goto out_free_pbm;
1464 } 1460 }
1465 1461
1466 p->pbm_A.iommu = iommu; 1462 pbm->iommu = iommu;
1467 1463
1468 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); 1464 if (schizo_pbm_init(pbm, op, portid, chip_type))
1469 if (!iommu) { 1465 goto out_free_iommu;
1470 printk(KERN_ERR PFX "Cannot allocate PBM B iommu.\n");
1471 goto out_free_iommu_A;
1472 }
1473 1466
1474 p->pbm_B.iommu = iommu; 1467 if (pbm->sibling)
1468 pbm->sibling->sibling = pbm;
1475 1469
1476 if (schizo_pbm_init(p, op, portid, chip_type)) 1470 dev_set_drvdata(&op->dev, pbm);
1477 goto out_free_iommu_B;
1478 1471
1479 return 0; 1472 return 0;
1480 1473
1481out_free_iommu_B: 1474out_free_iommu:
1482 kfree(p->pbm_B.iommu); 1475 kfree(pbm->iommu);
1483
1484out_free_iommu_A:
1485 kfree(p->pbm_A.iommu);
1486 1476
1487out_free_controller: 1477out_free_pbm:
1488 kfree(p); 1478 kfree(pbm);
1489 1479
1490out_err: 1480out_err:
1491 return err; 1481 return err;