aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_psycho.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r--arch/sparc64/kernel/pci_psycho.c161
1 files changed, 74 insertions, 87 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 0be850e6e580..70a7af092be2 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -146,24 +146,16 @@ static unsigned long stc_error_buf[128];
146static unsigned long stc_tag_buf[16]; 146static unsigned long stc_tag_buf[16];
147static unsigned long stc_line_buf[16]; 147static unsigned long stc_line_buf[16];
148 148
149static void __psycho_check_one_stc(struct pci_pbm_info *pbm, 149static void psycho_check_stc_error(struct pci_pbm_info *pbm)
150 int is_pbm_a)
151{ 150{
152 struct strbuf *strbuf = &pbm->stc; 151 struct strbuf *strbuf = &pbm->stc;
153 unsigned long regbase = pbm->controller_regs;
154 unsigned long err_base, tag_base, line_base; 152 unsigned long err_base, tag_base, line_base;
155 u64 control; 153 u64 control;
156 int i; 154 int i;
157 155
158 if (is_pbm_a) { 156 err_base = strbuf->strbuf_err_stat;
159 err_base = regbase + PSYCHO_STC_ERR_A; 157 tag_base = strbuf->strbuf_tag_diag;
160 tag_base = regbase + PSYCHO_STC_TAG_A; 158 line_base = strbuf->strbuf_line_diag;
161 line_base = regbase + PSYCHO_STC_LINE_A;
162 } else {
163 err_base = regbase + PSYCHO_STC_ERR_B;
164 tag_base = regbase + PSYCHO_STC_TAG_B;
165 line_base = regbase + PSYCHO_STC_LINE_B;
166 }
167 159
168 spin_lock(&stc_buf_lock); 160 spin_lock(&stc_buf_lock);
169 161
@@ -239,15 +231,6 @@ static void __psycho_check_one_stc(struct pci_pbm_info *pbm,
239 spin_unlock(&stc_buf_lock); 231 spin_unlock(&stc_buf_lock);
240} 232}
241 233
242static void __psycho_check_stc_error(struct pci_pbm_info *pbm,
243 unsigned long afsr,
244 unsigned long afar,
245 enum psycho_error_type type)
246{
247 __psycho_check_one_stc(pbm,
248 (pbm == &pbm->parent->pbm_A));
249}
250
251/* When an Uncorrectable Error or a PCI Error happens, we 234/* When an Uncorrectable Error or a PCI Error happens, we
252 * interrogate the IOMMU state to see if it is the cause. 235 * interrogate the IOMMU state to see if it is the cause.
253 */ 236 */
@@ -386,7 +369,7 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm,
386 (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); 369 (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT);
387 } 370 }
388 } 371 }
389 __psycho_check_stc_error(pbm, afsr, afar, type); 372 psycho_check_stc_error(pbm);
390 spin_unlock_irqrestore(&iommu->lock, flags); 373 spin_unlock_irqrestore(&iommu->lock, flags);
391} 374}
392 375
@@ -412,7 +395,6 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm,
412static irqreturn_t psycho_ue_intr(int irq, void *dev_id) 395static irqreturn_t psycho_ue_intr(int irq, void *dev_id)
413{ 396{
414 struct pci_pbm_info *pbm = dev_id; 397 struct pci_pbm_info *pbm = dev_id;
415 struct pci_controller_info *p = pbm->parent;
416 unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR; 398 unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR;
417 unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR; 399 unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR;
418 unsigned long afsr, afar, error_bits; 400 unsigned long afsr, afar, error_bits;
@@ -465,8 +447,9 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id)
465 printk("]\n"); 447 printk("]\n");
466 448
467 /* Interrogate both IOMMUs for error status. */ 449 /* Interrogate both IOMMUs for error status. */
468 psycho_check_iommu_error(&p->pbm_A, afsr, afar, UE_ERR); 450 psycho_check_iommu_error(pbm, afsr, afar, UE_ERR);
469 psycho_check_iommu_error(&p->pbm_B, afsr, afar, UE_ERR); 451 if (pbm->sibling)
452 psycho_check_iommu_error(pbm->sibling, afsr, afar, UE_ERR);
470 453
471 return IRQ_HANDLED; 454 return IRQ_HANDLED;
472} 455}
@@ -573,23 +556,18 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id)
573#define PSYCHO_PCI_AFAR_A 0x2018UL 556#define PSYCHO_PCI_AFAR_A 0x2018UL
574#define PSYCHO_PCI_AFAR_B 0x4018UL 557#define PSYCHO_PCI_AFAR_B 0x4018UL
575 558
576static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm_a) 559static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm)
577{ 560{
578 unsigned long csr_reg, csr, csr_error_bits; 561 unsigned long csr, csr_error_bits;
579 irqreturn_t ret = IRQ_NONE; 562 irqreturn_t ret = IRQ_NONE;
580 u16 stat; 563 u16 stat;
581 564
582 if (is_pbm_a) { 565 csr = psycho_read(pbm->pci_csr);
583 csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL;
584 } else {
585 csr_reg = pbm->controller_regs + PSYCHO_PCIB_CTRL;
586 }
587 csr = psycho_read(csr_reg);
588 csr_error_bits = 566 csr_error_bits =
589 csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR); 567 csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR);
590 if (csr_error_bits) { 568 if (csr_error_bits) {
591 /* Clear the errors. */ 569 /* Clear the errors. */
592 psycho_write(csr_reg, csr); 570 psycho_write(pbm->pci_csr, csr);
593 571
594 /* Log 'em. */ 572 /* Log 'em. */
595 if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR) 573 if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR)
@@ -616,19 +594,12 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
616static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) 594static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
617{ 595{
618 struct pci_pbm_info *pbm = dev_id; 596 struct pci_pbm_info *pbm = dev_id;
619 struct pci_controller_info *p = pbm->parent;
620 unsigned long afsr_reg, afar_reg; 597 unsigned long afsr_reg, afar_reg;
621 unsigned long afsr, afar, error_bits; 598 unsigned long afsr, afar, error_bits;
622 int is_pbm_a, reported; 599 int reported;
623 600
624 is_pbm_a = (pbm == &pbm->parent->pbm_A); 601 afsr_reg = pbm->pci_afsr;
625 if (is_pbm_a) { 602 afar_reg = pbm->pci_afar;
626 afsr_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFSR_A;
627 afar_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFAR_A;
628 } else {
629 afsr_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFSR_B;
630 afar_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFAR_B;
631 }
632 603
633 /* Latch error status. */ 604 /* Latch error status. */
634 afar = psycho_read(afar_reg); 605 afar = psycho_read(afar_reg);
@@ -641,7 +612,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
641 PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA | 612 PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA |
642 PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR); 613 PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR);
643 if (!error_bits) 614 if (!error_bits)
644 return psycho_pcierr_intr_other(pbm, is_pbm_a); 615 return psycho_pcierr_intr_other(pbm);
645 psycho_write(afsr_reg, error_bits); 616 psycho_write(afsr_reg, error_bits);
646 617
647 /* Log the error. */ 618 /* Log the error. */
@@ -923,10 +894,16 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm,
923 pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_A; 894 pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_A;
924 pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_A; 895 pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_A;
925 pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_A; 896 pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_A;
897 pbm->stc.strbuf_err_stat = base + PSYCHO_STC_ERR_A;
898 pbm->stc.strbuf_tag_diag = base + PSYCHO_STC_TAG_A;
899 pbm->stc.strbuf_line_diag= base + PSYCHO_STC_LINE_A;
926 } else { 900 } else {
927 pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_B; 901 pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_B;
928 pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_B; 902 pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_B;
929 pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_B; 903 pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_B;
904 pbm->stc.strbuf_err_stat = base + PSYCHO_STC_ERR_B;
905 pbm->stc.strbuf_tag_diag = base + PSYCHO_STC_TAG_B;
906 pbm->stc.strbuf_line_diag= base + PSYCHO_STC_LINE_B;
930 } 907 }
931 /* PSYCHO's streaming buffer lacks ctx flushing. */ 908 /* PSYCHO's streaming buffer lacks ctx flushing. */
932 pbm->stc.strbuf_ctxflush = 0; 909 pbm->stc.strbuf_ctxflush = 0;
@@ -971,16 +948,10 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm,
971#define PSYCHO_MEMSPACE_B 0x180000000UL 948#define PSYCHO_MEMSPACE_B 0x180000000UL
972#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL 949#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL
973 950
974static void __init psycho_pbm_init(struct pci_controller_info *p, 951static void __init psycho_pbm_init(struct pci_pbm_info *pbm,
975 struct of_device *op, int is_pbm_a) 952 struct of_device *op, int is_pbm_a)
976{ 953{
977 struct device_node *dp = op->node; 954 struct device_node *dp = op->node;
978 struct pci_pbm_info *pbm;
979
980 if (is_pbm_a)
981 pbm = &p->pbm_A;
982 else
983 pbm = &p->pbm_B;
984 955
985 pbm->next = pci_pbm_root; 956 pbm->next = pci_pbm_root;
986 pci_pbm_root = pbm; 957 pci_pbm_root = pbm;
@@ -996,7 +967,6 @@ static void __init psycho_pbm_init(struct pci_controller_info *p,
996 pbm->chip_version = of_getintprop_default(dp, "version#", 0); 967 pbm->chip_version = of_getintprop_default(dp, "version#", 0);
997 pbm->chip_revision = of_getintprop_default(dp, "module-revision#", 0); 968 pbm->chip_revision = of_getintprop_default(dp, "module-revision#", 0);
998 969
999 pbm->parent = p;
1000 pbm->prom_node = dp; 970 pbm->prom_node = dp;
1001 pbm->name = dp->full_name; 971 pbm->name = dp->full_name;
1002 972
@@ -1013,6 +983,17 @@ static void __init psycho_pbm_init(struct pci_controller_info *p,
1013 psycho_scan_bus(pbm, &op->dev); 983 psycho_scan_bus(pbm, &op->dev);
1014} 984}
1015 985
986static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid)
987{
988 struct pci_pbm_info *pbm;
989
990 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
991 if (pbm->portid == upa_portid)
992 return pbm;
993 }
994 return NULL;
995}
996
1016#define PSYCHO_CONFIGSPACE 0x001000000UL 997#define PSYCHO_CONFIGSPACE 0x001000000UL
1017 998
1018static int __devinit psycho_probe(struct of_device *op, 999static int __devinit psycho_probe(struct of_device *op,
@@ -1020,7 +1001,6 @@ static int __devinit psycho_probe(struct of_device *op,
1020{ 1001{
1021 const struct linux_prom64_registers *pr_regs; 1002 const struct linux_prom64_registers *pr_regs;
1022 struct device_node *dp = op->node; 1003 struct device_node *dp = op->node;
1023 struct pci_controller_info *p;
1024 struct pci_pbm_info *pbm; 1004 struct pci_pbm_info *pbm;
1025 struct iommu *iommu; 1005 struct iommu *iommu;
1026 int is_pbm_a, err; 1006 int is_pbm_a, err;
@@ -1028,33 +1008,26 @@ static int __devinit psycho_probe(struct of_device *op,
1028 1008
1029 upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); 1009 upa_portid = of_getintprop_default(dp, "upa-portid", 0xff);
1030 1010
1031 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
1032 struct pci_controller_info *p = pbm->parent;
1033
1034 if (p->pbm_A.portid == upa_portid) {
1035 is_pbm_a = (p->pbm_A.prom_node == NULL);
1036 psycho_pbm_init(p, op, is_pbm_a);
1037 return 0;
1038 }
1039 }
1040
1041 err = -ENOMEM; 1011 err = -ENOMEM;
1042 p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); 1012 pbm = kzalloc(sizeof(*pbm), GFP_KERNEL);
1043 if (!p) { 1013 if (!pbm) {
1044 printk(KERN_ERR PFX "Cannot allocate controller info.\n"); 1014 printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n");
1045 goto out_err; 1015 goto out_err;
1046 } 1016 }
1047 1017
1048 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); 1018 pbm->sibling = psycho_find_sibling(upa_portid);
1049 if (!iommu) { 1019 if (pbm->sibling) {
1050 printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); 1020 iommu = pbm->sibling->iommu;
1051 goto out_free_controller; 1021 } else {
1022 iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL);
1023 if (!iommu) {
1024 printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n");
1025 goto out_free_controller;
1026 }
1052 } 1027 }
1053 1028
1054 p->pbm_A.iommu = p->pbm_B.iommu = iommu; 1029 pbm->iommu = iommu;
1055 1030 pbm->portid = upa_portid;
1056 p->pbm_A.portid = upa_portid;
1057 p->pbm_B.portid = upa_portid;
1058 1031
1059 pr_regs = of_get_property(dp, "reg", NULL); 1032 pr_regs = of_get_property(dp, "reg", NULL);
1060 err = -ENODEV; 1033 err = -ENODEV;
@@ -1063,29 +1036,43 @@ static int __devinit psycho_probe(struct of_device *op,
1063 goto out_free_iommu; 1036 goto out_free_iommu;
1064 } 1037 }
1065 1038
1066 p->pbm_A.controller_regs = pr_regs[2].phys_addr; 1039 is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000);
1067 p->pbm_B.controller_regs = pr_regs[2].phys_addr; 1040
1041 pbm->controller_regs = pr_regs[2].phys_addr;
1042 pbm->config_space = (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE);
1068 1043
1069 p->pbm_A.config_space = p->pbm_B.config_space = 1044 if (is_pbm_a) {
1070 (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); 1045 pbm->pci_afsr = pbm->controller_regs + PSYCHO_PCI_AFSR_A;
1046 pbm->pci_afar = pbm->controller_regs + PSYCHO_PCI_AFAR_A;
1047 pbm->pci_csr = pbm->controller_regs + PSYCHO_PCIA_CTRL;
1048 } else {
1049 pbm->pci_afsr = pbm->controller_regs + PSYCHO_PCI_AFSR_B;
1050 pbm->pci_afar = pbm->controller_regs + PSYCHO_PCI_AFAR_B;
1051 pbm->pci_csr = pbm->controller_regs + PSYCHO_PCIB_CTRL;
1052 }
1071 1053
1072 psycho_controller_hwinit(&p->pbm_A); 1054 psycho_controller_hwinit(pbm);
1055 if (!pbm->sibling) {
1056 err = psycho_iommu_init(pbm);
1057 if (err)
1058 goto out_free_iommu;
1059 }
1073 1060
1074 err = psycho_iommu_init(&p->pbm_A); 1061 psycho_pbm_init(pbm, op, is_pbm_a);
1075 if (err)
1076 goto out_free_iommu;
1077 1062
1078 is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); 1063 if (pbm->sibling)
1064 pbm->sibling->sibling = pbm;
1079 1065
1080 psycho_pbm_init(p, op, is_pbm_a); 1066 dev_set_drvdata(&op->dev, pbm);
1081 1067
1082 return 0; 1068 return 0;
1083 1069
1084out_free_iommu: 1070out_free_iommu:
1085 kfree(p->pbm_A.iommu); 1071 if (!pbm->sibling)
1072 kfree(pbm->iommu);
1086 1073
1087out_free_controller: 1074out_free_controller:
1088 kfree(p); 1075 kfree(pbm);
1089 1076
1090out_err: 1077out_err:
1091 return err; 1078 return err;