aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_psycho.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-05-08 02:06:27 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-05-08 19:41:24 -0400
commit34768bc8329194b14e42ee408a84edfa40059046 (patch)
tree3fff53138966f3a58e796a71c19a3b75de86fbf7 /arch/sparc64/kernel/pci_psycho.c
parent5a4a3e592d0d66653297049373caa7ac5b4febe0 (diff)
[SPARC64] PCI: Use root list of pbm's instead of pci_controller_info's
The idea is to move more and more things into the pbm, with the eventual goal of eliminating the pci_controller_info entirely as there really isn't any need for it. This stage of the transformations requires some reworking of the PCI error interrupt handling. It might be tricky to get rid of the pci_controller_info parenting for a few reasons: 1) When we get an uncorrectable or correctable error we want to interrogate the IOMMU and streaming cache of both PBMs for error status. These errors come from the UPA front-end which is shared between the two PBM PCI bus segments. Historically speaking this is why I choose the datastructure hierarchy of pci_controller_info-->pci_pbm_info 2) The probing does a portid/devhandle match to look for the 'other' pbm, but this is entirely an artifact and can be eliminated trivially. What we could do to solve #1 is to have a "buddy" pointer from one pbm to another. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r--arch/sparc64/kernel/pci_psycho.c107
1 files changed, 49 insertions, 58 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 0f35135a40c5..4801eb441236 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -265,12 +265,12 @@ static unsigned long stc_error_buf[128];
265static unsigned long stc_tag_buf[16]; 265static unsigned long stc_tag_buf[16];
266static unsigned long stc_line_buf[16]; 266static unsigned long stc_line_buf[16];
267 267
268static void __psycho_check_one_stc(struct pci_controller_info *p, 268static void __psycho_check_one_stc(struct pci_pbm_info *pbm,
269 struct pci_pbm_info *pbm,
270 int is_pbm_a) 269 int is_pbm_a)
271{ 270{
271 struct pci_controller_info *p = pbm->parent;
272 struct strbuf *strbuf = &pbm->stc; 272 struct strbuf *strbuf = &pbm->stc;
273 unsigned long regbase = p->pbm_A.controller_regs; 273 unsigned long regbase = pbm->controller_regs;
274 unsigned long err_base, tag_base, line_base; 274 unsigned long err_base, tag_base, line_base;
275 u64 control; 275 u64 control;
276 int i; 276 int i;
@@ -362,20 +362,13 @@ static void __psycho_check_one_stc(struct pci_controller_info *p,
362 spin_unlock(&stc_buf_lock); 362 spin_unlock(&stc_buf_lock);
363} 363}
364 364
365static void __psycho_check_stc_error(struct pci_controller_info *p, 365static void __psycho_check_stc_error(struct pci_pbm_info *pbm,
366 unsigned long afsr, 366 unsigned long afsr,
367 unsigned long afar, 367 unsigned long afar,
368 enum psycho_error_type type) 368 enum psycho_error_type type)
369{ 369{
370 struct pci_pbm_info *pbm; 370 __psycho_check_one_stc(pbm,
371 371 (pbm == &pbm->parent->pbm_A));
372 pbm = &p->pbm_A;
373 if (pbm->stc.strbuf_enabled)
374 __psycho_check_one_stc(p, pbm, 1);
375
376 pbm = &p->pbm_B;
377 if (pbm->stc.strbuf_enabled)
378 __psycho_check_one_stc(p, pbm, 0);
379} 372}
380 373
381/* When an Uncorrectable Error or a PCI Error happens, we 374/* When an Uncorrectable Error or a PCI Error happens, we
@@ -413,12 +406,13 @@ static void __psycho_check_stc_error(struct pci_controller_info *p,
413#define PSYCHO_IOMMU_DATA_VALID (1UL << 30UL) 406#define PSYCHO_IOMMU_DATA_VALID (1UL << 30UL)
414#define PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL) 407#define PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL)
415#define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffUL 408#define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffUL
416static void psycho_check_iommu_error(struct pci_controller_info *p, 409static void psycho_check_iommu_error(struct pci_pbm_info *pbm,
417 unsigned long afsr, 410 unsigned long afsr,
418 unsigned long afar, 411 unsigned long afar,
419 enum psycho_error_type type) 412 enum psycho_error_type type)
420{ 413{
421 struct iommu *iommu = p->pbm_A.iommu; 414 struct pci_controller_info *p = pbm->parent;
415 struct iommu *iommu = pbm->iommu;
422 unsigned long iommu_tag[16]; 416 unsigned long iommu_tag[16];
423 unsigned long iommu_data[16]; 417 unsigned long iommu_data[16];
424 unsigned long flags; 418 unsigned long flags;
@@ -465,7 +459,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p,
465 psycho_write(iommu->iommu_control, 459 psycho_write(iommu->iommu_control,
466 control | PSYCHO_IOMMU_CTRL_DENAB); 460 control | PSYCHO_IOMMU_CTRL_DENAB);
467 for (i = 0; i < 16; i++) { 461 for (i = 0; i < 16; i++) {
468 unsigned long base = p->pbm_A.controller_regs; 462 unsigned long base = pbm->controller_regs;
469 463
470 iommu_tag[i] = 464 iommu_tag[i] =
471 psycho_read(base + PSYCHO_IOMMU_TAG + (i * 8UL)); 465 psycho_read(base + PSYCHO_IOMMU_TAG + (i * 8UL));
@@ -516,7 +510,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p,
516 (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); 510 (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT);
517 } 511 }
518 } 512 }
519 __psycho_check_stc_error(p, afsr, afar, type); 513 __psycho_check_stc_error(pbm, afsr, afar, type);
520 spin_unlock_irqrestore(&iommu->lock, flags); 514 spin_unlock_irqrestore(&iommu->lock, flags);
521} 515}
522 516
@@ -541,9 +535,10 @@ static void psycho_check_iommu_error(struct pci_controller_info *p,
541 535
542static irqreturn_t psycho_ue_intr(int irq, void *dev_id) 536static irqreturn_t psycho_ue_intr(int irq, void *dev_id)
543{ 537{
544 struct pci_controller_info *p = dev_id; 538 struct pci_pbm_info *pbm = dev_id;
545 unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFSR; 539 struct pci_controller_info *p = pbm->parent;
546 unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFAR; 540 unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR;
541 unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR;
547 unsigned long afsr, afar, error_bits; 542 unsigned long afsr, afar, error_bits;
548 int reported; 543 int reported;
549 544
@@ -593,8 +588,9 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id)
593 printk("(none)"); 588 printk("(none)");
594 printk("]\n"); 589 printk("]\n");
595 590
596 /* Interrogate IOMMU for error status. */ 591 /* Interrogate both IOMMUs for error status. */
597 psycho_check_iommu_error(p, afsr, afar, UE_ERR); 592 psycho_check_iommu_error(&p->pbm_A, afsr, afar, UE_ERR);
593 psycho_check_iommu_error(&p->pbm_B, afsr, afar, UE_ERR);
598 594
599 return IRQ_HANDLED; 595 return IRQ_HANDLED;
600} 596}
@@ -618,9 +614,10 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id)
618 614
619static irqreturn_t psycho_ce_intr(int irq, void *dev_id) 615static irqreturn_t psycho_ce_intr(int irq, void *dev_id)
620{ 616{
621 struct pci_controller_info *p = dev_id; 617 struct pci_pbm_info *pbm = dev_id;
622 unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFSR; 618 struct pci_controller_info *p = pbm->parent;
623 unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFAR; 619 unsigned long afsr_reg = pbm->controller_regs + PSYCHO_CE_AFSR;
620 unsigned long afar_reg = pbm->controller_regs + PSYCHO_CE_AFAR;
624 unsigned long afsr, afar, error_bits; 621 unsigned long afsr, afar, error_bits;
625 int reported; 622 int reported;
626 623
@@ -823,11 +820,11 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
823 * a bug in the IOMMU support code or a PCI device driver. 820 * a bug in the IOMMU support code or a PCI device driver.
824 */ 821 */
825 if (error_bits & (PSYCHO_PCIAFSR_PTA | PSYCHO_PCIAFSR_STA)) { 822 if (error_bits & (PSYCHO_PCIAFSR_PTA | PSYCHO_PCIAFSR_STA)) {
826 psycho_check_iommu_error(p, afsr, afar, PCI_ERR); 823 psycho_check_iommu_error(pbm, afsr, afar, PCI_ERR);
827 pci_scan_for_target_abort(p, pbm, pbm->pci_bus); 824 pci_scan_for_target_abort(pbm->parent, pbm, pbm->pci_bus);
828 } 825 }
829 if (error_bits & (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_SMA)) 826 if (error_bits & (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_SMA))
830 pci_scan_for_master_abort(p, pbm, pbm->pci_bus); 827 pci_scan_for_master_abort(pbm->parent, pbm, pbm->pci_bus);
831 828
832 /* For excessive retries, PSYCHO/PBM will abort the device 829 /* For excessive retries, PSYCHO/PBM will abort the device
833 * and there is no way to specifically check for excessive 830 * and there is no way to specifically check for excessive
@@ -837,7 +834,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
837 */ 834 */
838 835
839 if (error_bits & (PSYCHO_PCIAFSR_PPERR | PSYCHO_PCIAFSR_SPERR)) 836 if (error_bits & (PSYCHO_PCIAFSR_PPERR | PSYCHO_PCIAFSR_SPERR))
840 pci_scan_for_parity_error(p, pbm, pbm->pci_bus); 837 pci_scan_for_parity_error(pbm->parent, pbm, pbm->pci_bus);
841 838
842 return IRQ_HANDLED; 839 return IRQ_HANDLED;
843} 840}
@@ -847,34 +844,33 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
847#define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ 844#define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */
848#define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ 845#define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */
849#define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ 846#define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */
850static void psycho_register_error_handlers(struct pci_controller_info *p) 847static void psycho_register_error_handlers(struct pci_pbm_info *pbm)
851{ 848{
852 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
853 struct of_device *op = of_find_device_by_node(pbm->prom_node); 849 struct of_device *op = of_find_device_by_node(pbm->prom_node);
854 unsigned long base = p->pbm_A.controller_regs; 850 unsigned long base = pbm->controller_regs;
855 u64 tmp; 851 u64 tmp;
856 852
857 if (!op) 853 if (!op)
858 return; 854 return;
859 855
860 /* Psycho interrupt property order is: 856 /* Psycho interrupt property order is:
861 * 0: PCIERR PBM B INO 857 * 0: PCIERR INO for this PBM
862 * 1: UE ERR 858 * 1: UE ERR
863 * 2: CE ERR 859 * 2: CE ERR
864 * 3: POWER FAIL 860 * 3: POWER FAIL
865 * 4: SPARE HARDWARE 861 * 4: SPARE HARDWARE
866 * 5: PCIERR PBM A INO 862 * 5: POWER MANAGEMENT
867 */ 863 */
868 864
869 if (op->num_irqs < 6) 865 if (op->num_irqs < 6)
870 return; 866 return;
871 867
872 request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED, "PSYCHO UE", p); 868 request_irq(op->irqs[1], psycho_ue_intr, 0,
873 request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED, "PSYCHO CE", p); 869 "PSYCHO_UE", pbm);
874 request_irq(op->irqs[5], psycho_pcierr_intr, IRQF_SHARED, 870 request_irq(op->irqs[2], psycho_ce_intr, 0,
875 "PSYCHO PCIERR-A", &p->pbm_A); 871 "PSYCHO_CE", pbm);
876 request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED, 872 request_irq(op->irqs[0], psycho_pcierr_intr, 0,
877 "PSYCHO PCIERR-B", &p->pbm_B); 873 "PSYCHO_PCIERR", pbm);
878 874
879 /* Enable UE and CE interrupts for controller. */ 875 /* Enable UE and CE interrupts for controller. */
880 psycho_write(base + PSYCHO_ECC_CTRL, 876 psycho_write(base + PSYCHO_ECC_CTRL,
@@ -918,25 +914,16 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
918 pci_config_write8(addr, 64); 914 pci_config_write8(addr, 64);
919} 915}
920 916
921static void pbm_scan_bus(struct pci_controller_info *p, 917static void psycho_scan_bus(struct pci_pbm_info *pbm)
922 struct pci_pbm_info *pbm)
923{ 918{
919 pbm_config_busmastering(pbm);
920 pbm->is_66mhz_capable = 0;
924 pbm->pci_bus = pci_scan_one_pbm(pbm); 921 pbm->pci_bus = pci_scan_one_pbm(pbm);
925}
926
927static void psycho_scan_bus(struct pci_controller_info *p)
928{
929 pbm_config_busmastering(&p->pbm_B);
930 p->pbm_B.is_66mhz_capable = 0;
931 pbm_config_busmastering(&p->pbm_A);
932 p->pbm_A.is_66mhz_capable = 1;
933 pbm_scan_bus(p, &p->pbm_B);
934 pbm_scan_bus(p, &p->pbm_A);
935 922
936 /* After the PCI bus scan is complete, we can register 923 /* After the PCI bus scan is complete, we can register
937 * the error interrupt handlers. 924 * the error interrupt handlers.
938 */ 925 */
939 psycho_register_error_handlers(p); 926 psycho_register_error_handlers(pbm);
940} 927}
941 928
942static void psycho_iommu_init(struct pci_controller_info *p) 929static void psycho_iommu_init(struct pci_controller_info *p)
@@ -1096,6 +1083,11 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1096 else 1083 else
1097 pbm = &p->pbm_B; 1084 pbm = &p->pbm_B;
1098 1085
1086 pbm->next = pci_pbm_root;
1087 pci_pbm_root = pbm;
1088
1089 pbm->scan_bus = psycho_scan_bus;
1090
1099 pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; 1091 pbm->chip_type = PBM_CHIP_TYPE_PSYCHO;
1100 pbm->chip_version = 0; 1092 pbm->chip_version = 0;
1101 prop = of_find_property(dp, "version#", NULL); 1093 prop = of_find_property(dp, "version#", NULL);
@@ -1127,6 +1119,7 @@ void psycho_init(struct device_node *dp, char *model_name)
1127{ 1119{
1128 struct linux_prom64_registers *pr_regs; 1120 struct linux_prom64_registers *pr_regs;
1129 struct pci_controller_info *p; 1121 struct pci_controller_info *p;
1122 struct pci_pbm_info *pbm;
1130 struct iommu *iommu; 1123 struct iommu *iommu;
1131 struct property *prop; 1124 struct property *prop;
1132 u32 upa_portid; 1125 u32 upa_portid;
@@ -1137,7 +1130,9 @@ void psycho_init(struct device_node *dp, char *model_name)
1137 if (prop) 1130 if (prop)
1138 upa_portid = *(u32 *) prop->value; 1131 upa_portid = *(u32 *) prop->value;
1139 1132
1140 for(p = pci_controller_root; p; p = p->next) { 1133 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
1134 struct pci_controller_info *p = pbm->parent;
1135
1141 if (p->pbm_A.portid == upa_portid) { 1136 if (p->pbm_A.portid == upa_portid) {
1142 is_pbm_a = (p->pbm_A.prom_node == NULL); 1137 is_pbm_a = (p->pbm_A.prom_node == NULL);
1143 psycho_pbm_init(p, dp, is_pbm_a); 1138 psycho_pbm_init(p, dp, is_pbm_a);
@@ -1157,13 +1152,9 @@ void psycho_init(struct device_node *dp, char *model_name)
1157 } 1152 }
1158 p->pbm_A.iommu = p->pbm_B.iommu = iommu; 1153 p->pbm_A.iommu = p->pbm_B.iommu = iommu;
1159 1154
1160 p->next = pci_controller_root;
1161 pci_controller_root = p;
1162
1163 p->pbm_A.portid = upa_portid; 1155 p->pbm_A.portid = upa_portid;
1164 p->pbm_B.portid = upa_portid; 1156 p->pbm_B.portid = upa_portid;
1165 p->index = pci_num_controllers++; 1157 p->index = pci_num_controllers++;
1166 p->scan_bus = psycho_scan_bus;
1167 p->pci_ops = &psycho_ops; 1158 p->pci_ops = &psycho_ops;
1168 1159
1169 prop = of_find_property(dp, "reg", NULL); 1160 prop = of_find_property(dp, "reg", NULL);