diff options
Diffstat (limited to 'arch/sparc64/kernel/pci_schizo.c')
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 352 |
1 files changed, 149 insertions, 203 deletions
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 91a7385e5d32..e375d72b8eed 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -10,12 +10,13 @@ | |||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | 12 | ||
13 | #include <asm/pbm.h> | ||
14 | #include <asm/iommu.h> | 13 | #include <asm/iommu.h> |
15 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
16 | #include <asm/upa.h> | 15 | #include <asm/upa.h> |
17 | #include <asm/pstate.h> | 16 | #include <asm/pstate.h> |
18 | #include <asm/prom.h> | 17 | #include <asm/prom.h> |
18 | #include <asm/of_device.h> | ||
19 | #include <asm/oplib.h> | ||
19 | 20 | ||
20 | #include "pci_impl.h" | 21 | #include "pci_impl.h" |
21 | #include "iommu_common.h" | 22 | #include "iommu_common.h" |
@@ -238,25 +239,6 @@ static unsigned long stc_line_buf[16]; | |||
238 | #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ | 239 | #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ |
239 | #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ | 240 | #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ |
240 | 241 | ||
241 | struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino) | ||
242 | { | ||
243 | ino &= IMAP_INO; | ||
244 | if (p->pbm_A.ino_bitmap & (1UL << ino)) | ||
245 | return &p->pbm_A; | ||
246 | if (p->pbm_B.ino_bitmap & (1UL << ino)) | ||
247 | return &p->pbm_B; | ||
248 | |||
249 | printk("PCI%d: No ino_bitmap entry for ino[%x], bitmaps " | ||
250 | "PBM_A[%016lx] PBM_B[%016lx]", | ||
251 | p->index, ino, | ||
252 | p->pbm_A.ino_bitmap, | ||
253 | p->pbm_B.ino_bitmap); | ||
254 | printk("PCI%d: Using PBM_A, report this problem immediately.\n", | ||
255 | p->index); | ||
256 | |||
257 | return &p->pbm_A; | ||
258 | } | ||
259 | |||
260 | #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ | 242 | #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ |
261 | #define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */ | 243 | #define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */ |
262 | #define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */ | 244 | #define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */ |
@@ -522,9 +504,10 @@ static void schizo_check_iommu_error(struct pci_controller_info *p, | |||
522 | 504 | ||
523 | static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | 505 | static irqreturn_t schizo_ue_intr(int irq, void *dev_id) |
524 | { | 506 | { |
525 | struct pci_controller_info *p = dev_id; | 507 | struct pci_pbm_info *pbm = dev_id; |
526 | unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFSR; | 508 | struct pci_controller_info *p = pbm->parent; |
527 | unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFAR; | 509 | unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR; |
510 | unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR; | ||
528 | unsigned long afsr, afar, error_bits; | 511 | unsigned long afsr, afar, error_bits; |
529 | int reported, limit; | 512 | int reported, limit; |
530 | 513 | ||
@@ -549,28 +532,28 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | |||
549 | schizo_write(afsr_reg, error_bits); | 532 | schizo_write(afsr_reg, error_bits); |
550 | 533 | ||
551 | /* Log the error. */ | 534 | /* Log the error. */ |
552 | printk("PCI%d: Uncorrectable Error, primary error type[%s]\n", | 535 | printk("%s: Uncorrectable Error, primary error type[%s]\n", |
553 | p->index, | 536 | pbm->name, |
554 | (((error_bits & SCHIZO_UEAFSR_PPIO) ? | 537 | (((error_bits & SCHIZO_UEAFSR_PPIO) ? |
555 | "PIO" : | 538 | "PIO" : |
556 | ((error_bits & SCHIZO_UEAFSR_PDRD) ? | 539 | ((error_bits & SCHIZO_UEAFSR_PDRD) ? |
557 | "DMA Read" : | 540 | "DMA Read" : |
558 | ((error_bits & SCHIZO_UEAFSR_PDWR) ? | 541 | ((error_bits & SCHIZO_UEAFSR_PDWR) ? |
559 | "DMA Write" : "???"))))); | 542 | "DMA Write" : "???"))))); |
560 | printk("PCI%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", | 543 | printk("%s: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", |
561 | p->index, | 544 | pbm->name, |
562 | (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, | 545 | (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, |
563 | (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, | 546 | (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, |
564 | (afsr & SCHIZO_UEAFSR_AID) >> 24UL); | 547 | (afsr & SCHIZO_UEAFSR_AID) >> 24UL); |
565 | printk("PCI%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", | 548 | printk("%s: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", |
566 | p->index, | 549 | pbm->name, |
567 | (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, | 550 | (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, |
568 | (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, | 551 | (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, |
569 | (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, | 552 | (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, |
570 | (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, | 553 | (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, |
571 | (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); | 554 | (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); |
572 | printk("PCI%d: UE AFAR [%016lx]\n", p->index, afar); | 555 | printk("%s: UE AFAR [%016lx]\n", pbm->name, afar); |
573 | printk("PCI%d: UE Secondary errors [", p->index); | 556 | printk("%s: UE Secondary errors [", pbm->name); |
574 | reported = 0; | 557 | reported = 0; |
575 | if (afsr & SCHIZO_UEAFSR_SPIO) { | 558 | if (afsr & SCHIZO_UEAFSR_SPIO) { |
576 | reported++; | 559 | reported++; |
@@ -610,9 +593,9 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | |||
610 | 593 | ||
611 | static irqreturn_t schizo_ce_intr(int irq, void *dev_id) | 594 | static irqreturn_t schizo_ce_intr(int irq, void *dev_id) |
612 | { | 595 | { |
613 | struct pci_controller_info *p = dev_id; | 596 | struct pci_pbm_info *pbm = dev_id; |
614 | unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFSR; | 597 | unsigned long afsr_reg = pbm->controller_regs + SCHIZO_CE_AFSR; |
615 | unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFAR; | 598 | unsigned long afar_reg = pbm->controller_regs + SCHIZO_CE_AFAR; |
616 | unsigned long afsr, afar, error_bits; | 599 | unsigned long afsr, afar, error_bits; |
617 | int reported, limit; | 600 | int reported, limit; |
618 | 601 | ||
@@ -637,8 +620,8 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id) | |||
637 | schizo_write(afsr_reg, error_bits); | 620 | schizo_write(afsr_reg, error_bits); |
638 | 621 | ||
639 | /* Log the error. */ | 622 | /* Log the error. */ |
640 | printk("PCI%d: Correctable Error, primary error type[%s]\n", | 623 | printk("%s: Correctable Error, primary error type[%s]\n", |
641 | p->index, | 624 | pbm->name, |
642 | (((error_bits & SCHIZO_CEAFSR_PPIO) ? | 625 | (((error_bits & SCHIZO_CEAFSR_PPIO) ? |
643 | "PIO" : | 626 | "PIO" : |
644 | ((error_bits & SCHIZO_CEAFSR_PDRD) ? | 627 | ((error_bits & SCHIZO_CEAFSR_PDRD) ? |
@@ -649,20 +632,20 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id) | |||
649 | /* XXX Use syndrome and afar to print out module string just like | 632 | /* XXX Use syndrome and afar to print out module string just like |
650 | * XXX UDB CE trap handler does... -DaveM | 633 | * XXX UDB CE trap handler does... -DaveM |
651 | */ | 634 | */ |
652 | printk("PCI%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", | 635 | printk("%s: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", |
653 | p->index, | 636 | pbm->name, |
654 | (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, | 637 | (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, |
655 | (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, | 638 | (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, |
656 | (afsr & SCHIZO_UEAFSR_AID) >> 24UL); | 639 | (afsr & SCHIZO_UEAFSR_AID) >> 24UL); |
657 | printk("PCI%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", | 640 | printk("%s: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", |
658 | p->index, | 641 | pbm->name, |
659 | (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, | 642 | (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, |
660 | (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, | 643 | (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, |
661 | (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, | 644 | (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, |
662 | (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, | 645 | (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, |
663 | (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); | 646 | (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); |
664 | printk("PCI%d: CE AFAR [%016lx]\n", p->index, afar); | 647 | printk("%s: CE AFAR [%016lx]\n", pbm->name, afar); |
665 | printk("PCI%d: CE Secondary errors [", p->index); | 648 | printk("%s: CE Secondary errors [", pbm->name); |
666 | reported = 0; | 649 | reported = 0; |
667 | if (afsr & SCHIZO_CEAFSR_SPIO) { | 650 | if (afsr & SCHIZO_CEAFSR_SPIO) { |
668 | reported++; | 651 | reported++; |
@@ -881,10 +864,10 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | |||
881 | */ | 864 | */ |
882 | if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { | 865 | if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { |
883 | schizo_check_iommu_error(p, PCI_ERR); | 866 | schizo_check_iommu_error(p, PCI_ERR); |
884 | pci_scan_for_target_abort(p, pbm, pbm->pci_bus); | 867 | pci_scan_for_target_abort(pbm, pbm->pci_bus); |
885 | } | 868 | } |
886 | if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) | 869 | if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) |
887 | pci_scan_for_master_abort(p, pbm, pbm->pci_bus); | 870 | pci_scan_for_master_abort(pbm, pbm->pci_bus); |
888 | 871 | ||
889 | /* For excessive retries, PSYCHO/PBM will abort the device | 872 | /* For excessive retries, PSYCHO/PBM will abort the device |
890 | * and there is no way to specifically check for excessive | 873 | * and there is no way to specifically check for excessive |
@@ -894,7 +877,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | |||
894 | */ | 877 | */ |
895 | 878 | ||
896 | if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) | 879 | if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) |
897 | pci_scan_for_parity_error(p, pbm, pbm->pci_bus); | 880 | pci_scan_for_parity_error(pbm, pbm->pci_bus); |
898 | 881 | ||
899 | return IRQ_HANDLED; | 882 | return IRQ_HANDLED; |
900 | } | 883 | } |
@@ -940,22 +923,23 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | |||
940 | */ | 923 | */ |
941 | static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) | 924 | static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) |
942 | { | 925 | { |
943 | struct pci_controller_info *p = dev_id; | 926 | struct pci_pbm_info *pbm = dev_id; |
927 | struct pci_controller_info *p = pbm->parent; | ||
944 | u64 errlog; | 928 | u64 errlog; |
945 | 929 | ||
946 | errlog = schizo_read(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRLOG); | 930 | errlog = schizo_read(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG); |
947 | schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRLOG, | 931 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG, |
948 | errlog & ~(SAFARI_ERRLOG_ERROUT)); | 932 | errlog & ~(SAFARI_ERRLOG_ERROUT)); |
949 | 933 | ||
950 | if (!(errlog & BUS_ERROR_UNMAP)) { | 934 | if (!(errlog & BUS_ERROR_UNMAP)) { |
951 | printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", | 935 | printk("%s: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", |
952 | p->index, errlog); | 936 | pbm->name, errlog); |
953 | 937 | ||
954 | return IRQ_HANDLED; | 938 | return IRQ_HANDLED; |
955 | } | 939 | } |
956 | 940 | ||
957 | printk("PCI%d: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", | 941 | printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", |
958 | p->index); | 942 | pbm->name); |
959 | schizo_check_iommu_error(p, SAFARI_ERR); | 943 | schizo_check_iommu_error(p, SAFARI_ERR); |
960 | 944 | ||
961 | return IRQ_HANDLED; | 945 | return IRQ_HANDLED; |
@@ -972,6 +956,16 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) | |||
972 | #define SCHIZO_SAFARI_IRQCTRL 0x10010UL | 956 | #define SCHIZO_SAFARI_IRQCTRL 0x10010UL |
973 | #define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL | 957 | #define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL |
974 | 958 | ||
959 | static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) | ||
960 | { | ||
961 | ino &= IMAP_INO; | ||
962 | |||
963 | if (pbm->ino_bitmap & (1UL << ino)) | ||
964 | return 1; | ||
965 | |||
966 | return 0; | ||
967 | } | ||
968 | |||
975 | /* How the Tomatillo IRQs are routed around is pure guesswork here. | 969 | /* How the Tomatillo IRQs are routed around is pure guesswork here. |
976 | * | 970 | * |
977 | * All the Tomatillo devices I see in prtconf dumps seem to have only | 971 | * All the Tomatillo devices I see in prtconf dumps seem to have only |
@@ -986,11 +980,11 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) | |||
986 | * PCI bus units of the same Tomatillo. I still have not really | 980 | * PCI bus units of the same Tomatillo. I still have not really |
987 | * figured this out... | 981 | * figured this out... |
988 | */ | 982 | */ |
989 | static void tomatillo_register_error_handlers(struct pci_controller_info *p) | 983 | static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) |
990 | { | 984 | { |
991 | struct pci_pbm_info *pbm; | 985 | struct of_device *op = of_find_device_by_node(pbm->prom_node); |
992 | struct of_device *op; | ||
993 | u64 tmp, err_mask, err_no_mask; | 986 | u64 tmp, err_mask, err_no_mask; |
987 | int err; | ||
994 | 988 | ||
995 | /* Tomatillo IRQ property layout is: | 989 | /* Tomatillo IRQ property layout is: |
996 | * 0: PCIERR | 990 | * 0: PCIERR |
@@ -1000,44 +994,42 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1000 | * 4: POWER FAIL? | 994 | * 4: POWER FAIL? |
1001 | */ | 995 | */ |
1002 | 996 | ||
1003 | pbm = pbm_for_ino(p, SCHIZO_UE_INO); | 997 | if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) { |
1004 | op = of_find_device_by_node(pbm->prom_node); | 998 | err = request_irq(op->irqs[1], schizo_ue_intr, 0, |
1005 | if (op) | 999 | "TOMATILLO_UE", pbm); |
1006 | request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED, | 1000 | if (err) |
1007 | "TOMATILLO_UE", p); | 1001 | printk(KERN_WARNING "%s: Could not register UE, " |
1008 | 1002 | "err=%d\n", pbm->name, err); | |
1009 | pbm = pbm_for_ino(p, SCHIZO_CE_INO); | 1003 | } |
1010 | op = of_find_device_by_node(pbm->prom_node); | 1004 | if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) { |
1011 | if (op) | 1005 | err = request_irq(op->irqs[2], schizo_ce_intr, 0, |
1012 | request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED, | 1006 | "TOMATILLO_CE", pbm); |
1013 | "TOMATILLO CE", p); | 1007 | if (err) |
1014 | 1008 | printk(KERN_WARNING "%s: Could not register CE, " | |
1015 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); | 1009 | "err=%d\n", pbm->name, err); |
1016 | op = of_find_device_by_node(pbm->prom_node); | 1010 | } |
1017 | if (op) | 1011 | err = 0; |
1018 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1012 | if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) { |
1019 | "TOMATILLO PCIERR-A", pbm); | 1013 | err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1020 | 1014 | "TOMATILLO_PCIERR", pbm); | |
1021 | 1015 | } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) { | |
1022 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); | 1016 | err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1023 | op = of_find_device_by_node(pbm->prom_node); | 1017 | "TOMATILLO_PCIERR", pbm); |
1024 | if (op) | 1018 | } |
1025 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1019 | if (err) |
1026 | "TOMATILLO PCIERR-B", pbm); | 1020 | printk(KERN_WARNING "%s: Could not register PCIERR, " |
1027 | 1021 | "err=%d\n", pbm->name, err); | |
1028 | pbm = pbm_for_ino(p, SCHIZO_SERR_INO); | 1022 | |
1029 | op = of_find_device_by_node(pbm->prom_node); | 1023 | if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) { |
1030 | if (op) | 1024 | err = request_irq(op->irqs[3], schizo_safarierr_intr, 0, |
1031 | request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED, | 1025 | "TOMATILLO_SERR", pbm); |
1032 | "TOMATILLO SERR", p); | 1026 | if (err) |
1027 | printk(KERN_WARNING "%s: Could not register SERR, " | ||
1028 | "err=%d\n", pbm->name, err); | ||
1029 | } | ||
1033 | 1030 | ||
1034 | /* Enable UE and CE interrupts for controller. */ | 1031 | /* Enable UE and CE interrupts for controller. */ |
1035 | schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, | 1032 | schizo_write(pbm->controller_regs + SCHIZO_ECC_CTRL, |
1036 | (SCHIZO_ECCCTRL_EE | | ||
1037 | SCHIZO_ECCCTRL_UE | | ||
1038 | SCHIZO_ECCCTRL_CE)); | ||
1039 | |||
1040 | schizo_write(p->pbm_B.controller_regs + SCHIZO_ECC_CTRL, | ||
1041 | (SCHIZO_ECCCTRL_EE | | 1033 | (SCHIZO_ECCCTRL_EE | |
1042 | SCHIZO_ECCCTRL_UE | | 1034 | SCHIZO_ECCCTRL_UE | |
1043 | SCHIZO_ECCCTRL_CE)); | 1035 | SCHIZO_ECCCTRL_CE)); |
@@ -1053,15 +1045,10 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1053 | 1045 | ||
1054 | err_no_mask = SCHIZO_PCICTRL_DTO_ERR; | 1046 | err_no_mask = SCHIZO_PCICTRL_DTO_ERR; |
1055 | 1047 | ||
1056 | tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); | 1048 | tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); |
1057 | tmp |= err_mask; | ||
1058 | tmp &= ~err_no_mask; | ||
1059 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp); | ||
1060 | |||
1061 | tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL); | ||
1062 | tmp |= err_mask; | 1049 | tmp |= err_mask; |
1063 | tmp &= ~err_no_mask; | 1050 | tmp &= ~err_no_mask; |
1064 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); | 1051 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); |
1065 | 1052 | ||
1066 | err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | | 1053 | err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | |
1067 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | | 1054 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | |
@@ -1070,8 +1057,7 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1070 | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | | 1057 | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | |
1071 | SCHIZO_PCIAFSR_STTO); | 1058 | SCHIZO_PCIAFSR_STTO); |
1072 | 1059 | ||
1073 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, err_mask); | 1060 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_AFSR, err_mask); |
1074 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, err_mask); | ||
1075 | 1061 | ||
1076 | err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR | | 1062 | err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR | |
1077 | BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD | | 1063 | BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD | |
@@ -1083,22 +1069,18 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1083 | BUS_ERROR_APERR | BUS_ERROR_UNMAP | | 1069 | BUS_ERROR_APERR | BUS_ERROR_UNMAP | |
1084 | BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT); | 1070 | BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT); |
1085 | 1071 | ||
1086 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, | 1072 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL, |
1087 | (SCHIZO_SAFERRCTRL_EN | err_mask)); | ||
1088 | schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRCTRL, | ||
1089 | (SCHIZO_SAFERRCTRL_EN | err_mask)); | 1073 | (SCHIZO_SAFERRCTRL_EN | err_mask)); |
1090 | 1074 | ||
1091 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, | 1075 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_IRQCTRL, |
1092 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); | ||
1093 | schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_IRQCTRL, | ||
1094 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); | 1076 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); |
1095 | } | 1077 | } |
1096 | 1078 | ||
1097 | static void schizo_register_error_handlers(struct pci_controller_info *p) | 1079 | static void schizo_register_error_handlers(struct pci_pbm_info *pbm) |
1098 | { | 1080 | { |
1099 | struct pci_pbm_info *pbm; | 1081 | struct of_device *op = of_find_device_by_node(pbm->prom_node); |
1100 | struct of_device *op; | ||
1101 | u64 tmp, err_mask, err_no_mask; | 1082 | u64 tmp, err_mask, err_no_mask; |
1083 | int err; | ||
1102 | 1084 | ||
1103 | /* Schizo IRQ property layout is: | 1085 | /* Schizo IRQ property layout is: |
1104 | * 0: PCIERR | 1086 | * 0: PCIERR |
@@ -1108,39 +1090,42 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1108 | * 4: POWER FAIL? | 1090 | * 4: POWER FAIL? |
1109 | */ | 1091 | */ |
1110 | 1092 | ||
1111 | pbm = pbm_for_ino(p, SCHIZO_UE_INO); | 1093 | if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) { |
1112 | op = of_find_device_by_node(pbm->prom_node); | 1094 | err = request_irq(op->irqs[1], schizo_ue_intr, 0, |
1113 | if (op) | 1095 | "SCHIZO_UE", pbm); |
1114 | request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED, | 1096 | if (err) |
1115 | "SCHIZO_UE", p); | 1097 | printk(KERN_WARNING "%s: Could not register UE, " |
1116 | 1098 | "err=%d\n", pbm->name, err); | |
1117 | pbm = pbm_for_ino(p, SCHIZO_CE_INO); | 1099 | } |
1118 | op = of_find_device_by_node(pbm->prom_node); | 1100 | if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) { |
1119 | if (op) | 1101 | err = request_irq(op->irqs[2], schizo_ce_intr, 0, |
1120 | request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED, | 1102 | "SCHIZO_CE", pbm); |
1121 | "SCHIZO CE", p); | 1103 | if (err) |
1122 | 1104 | printk(KERN_WARNING "%s: Could not register CE, " | |
1123 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); | 1105 | "err=%d\n", pbm->name, err); |
1124 | op = of_find_device_by_node(pbm->prom_node); | 1106 | } |
1125 | if (op) | 1107 | err = 0; |
1126 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1108 | if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) { |
1127 | "SCHIZO PCIERR-A", pbm); | 1109 | err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1128 | 1110 | "SCHIZO_PCIERR", pbm); | |
1129 | 1111 | } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) { | |
1130 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); | 1112 | err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1131 | op = of_find_device_by_node(pbm->prom_node); | 1113 | "SCHIZO_PCIERR", pbm); |
1132 | if (op) | 1114 | } |
1133 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1115 | if (err) |
1134 | "SCHIZO PCIERR-B", pbm); | 1116 | printk(KERN_WARNING "%s: Could not register PCIERR, " |
1135 | 1117 | "err=%d\n", pbm->name, err); | |
1136 | pbm = pbm_for_ino(p, SCHIZO_SERR_INO); | 1118 | |
1137 | op = of_find_device_by_node(pbm->prom_node); | 1119 | if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) { |
1138 | if (op) | 1120 | err = request_irq(op->irqs[3], schizo_safarierr_intr, 0, |
1139 | request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED, | 1121 | "SCHIZO_SERR", pbm); |
1140 | "SCHIZO SERR", p); | 1122 | if (err) |
1123 | printk(KERN_WARNING "%s: Could not register SERR, " | ||
1124 | "err=%d\n", pbm->name, err); | ||
1125 | } | ||
1141 | 1126 | ||
1142 | /* Enable UE and CE interrupts for controller. */ | 1127 | /* Enable UE and CE interrupts for controller. */ |
1143 | schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, | 1128 | schizo_write(pbm->controller_regs + SCHIZO_ECC_CTRL, |
1144 | (SCHIZO_ECCCTRL_EE | | 1129 | (SCHIZO_ECCCTRL_EE | |
1145 | SCHIZO_ECCCTRL_UE | | 1130 | SCHIZO_ECCCTRL_UE | |
1146 | SCHIZO_ECCCTRL_CE)); | 1131 | SCHIZO_ECCCTRL_CE)); |
@@ -1159,25 +1144,12 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1159 | /* Enable PCI Error interrupts and clear error | 1144 | /* Enable PCI Error interrupts and clear error |
1160 | * bits for each PBM. | 1145 | * bits for each PBM. |
1161 | */ | 1146 | */ |
1162 | tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); | 1147 | tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); |
1163 | tmp |= err_mask; | ||
1164 | tmp &= ~err_no_mask; | ||
1165 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp); | ||
1166 | |||
1167 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, | ||
1168 | (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | | ||
1169 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | | ||
1170 | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | | ||
1171 | SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA | | ||
1172 | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | | ||
1173 | SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS)); | ||
1174 | |||
1175 | tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL); | ||
1176 | tmp |= err_mask; | 1148 | tmp |= err_mask; |
1177 | tmp &= ~err_no_mask; | 1149 | tmp &= ~err_no_mask; |
1178 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); | 1150 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); |
1179 | 1151 | ||
1180 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, | 1152 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_AFSR, |
1181 | (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | | 1153 | (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | |
1182 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | | 1154 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | |
1183 | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | | 1155 | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | |
@@ -1210,11 +1182,8 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1210 | BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB); | 1182 | BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB); |
1211 | #endif | 1183 | #endif |
1212 | 1184 | ||
1213 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, | 1185 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL, |
1214 | (SCHIZO_SAFERRCTRL_EN | err_mask)); | 1186 | (SCHIZO_SAFERRCTRL_EN | err_mask)); |
1215 | |||
1216 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, | ||
1217 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); | ||
1218 | } | 1187 | } |
1219 | 1188 | ||
1220 | static void pbm_config_busmastering(struct pci_pbm_info *pbm) | 1189 | static void pbm_config_busmastering(struct pci_pbm_info *pbm) |
@@ -1234,27 +1203,19 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
1234 | pci_config_write8(addr, 64); | 1203 | pci_config_write8(addr, 64); |
1235 | } | 1204 | } |
1236 | 1205 | ||
1237 | static void schizo_scan_bus(struct pci_controller_info *p) | 1206 | static void schizo_scan_bus(struct pci_pbm_info *pbm) |
1238 | { | 1207 | { |
1239 | pbm_config_busmastering(&p->pbm_B); | 1208 | pbm_config_busmastering(pbm); |
1240 | p->pbm_B.is_66mhz_capable = | 1209 | pbm->is_66mhz_capable = |
1241 | (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL) | 1210 | (of_find_property(pbm->prom_node, "66mhz-capable", NULL) |
1242 | != NULL); | ||
1243 | pbm_config_busmastering(&p->pbm_A); | ||
1244 | p->pbm_A.is_66mhz_capable = | ||
1245 | (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL) | ||
1246 | != NULL); | 1211 | != NULL); |
1247 | 1212 | ||
1248 | p->pbm_B.pci_bus = pci_scan_one_pbm(&p->pbm_B); | 1213 | pbm->pci_bus = pci_scan_one_pbm(pbm); |
1249 | p->pbm_A.pci_bus = pci_scan_one_pbm(&p->pbm_A); | ||
1250 | 1214 | ||
1251 | /* After the PCI bus scan is complete, we can register | 1215 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) |
1252 | * the error interrupt handlers. | 1216 | tomatillo_register_error_handlers(pbm); |
1253 | */ | ||
1254 | if (p->pbm_B.chip_type == PBM_CHIP_TYPE_TOMATILLO) | ||
1255 | tomatillo_register_error_handlers(p); | ||
1256 | else | 1217 | else |
1257 | schizo_register_error_handlers(p); | 1218 | schizo_register_error_handlers(pbm); |
1258 | } | 1219 | } |
1259 | 1220 | ||
1260 | #define SCHIZO_STRBUF_CONTROL (0x02800UL) | 1221 | #define SCHIZO_STRBUF_CONTROL (0x02800UL) |
@@ -1491,10 +1452,8 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1491 | int chip_type) | 1452 | int chip_type) |
1492 | { | 1453 | { |
1493 | const struct linux_prom64_registers *regs; | 1454 | const struct linux_prom64_registers *regs; |
1494 | const unsigned int *busrange; | ||
1495 | struct pci_pbm_info *pbm; | 1455 | struct pci_pbm_info *pbm; |
1496 | const char *chipset_name; | 1456 | const char *chipset_name; |
1497 | const u32 *ino_bitmap; | ||
1498 | int is_pbm_a; | 1457 | int is_pbm_a; |
1499 | 1458 | ||
1500 | switch (chip_type) { | 1459 | switch (chip_type) { |
@@ -1531,6 +1490,14 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1531 | else | 1490 | else |
1532 | pbm = &p->pbm_B; | 1491 | pbm = &p->pbm_B; |
1533 | 1492 | ||
1493 | pbm->next = pci_pbm_root; | ||
1494 | pci_pbm_root = pbm; | ||
1495 | |||
1496 | pbm->scan_bus = schizo_scan_bus; | ||
1497 | pbm->pci_ops = &schizo_ops; | ||
1498 | |||
1499 | pbm->index = pci_num_pbms++; | ||
1500 | |||
1534 | pbm->portid = portid; | 1501 | pbm->portid = portid; |
1535 | pbm->parent = p; | 1502 | pbm->parent = p; |
1536 | pbm->prom_node = dp; | 1503 | pbm->prom_node = dp; |
@@ -1555,13 +1522,7 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1555 | 1522 | ||
1556 | pci_determine_mem_io_space(pbm); | 1523 | pci_determine_mem_io_space(pbm); |
1557 | 1524 | ||
1558 | ino_bitmap = of_get_property(dp, "ino-bitmap", NULL); | 1525 | pci_get_pbm_props(pbm); |
1559 | pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | | ||
1560 | ((u64)ino_bitmap[0] << 0UL)); | ||
1561 | |||
1562 | busrange = of_get_property(dp, "bus-range", NULL); | ||
1563 | pbm->pci_first_busno = busrange[0]; | ||
1564 | pbm->pci_last_busno = busrange[1]; | ||
1565 | 1526 | ||
1566 | schizo_pbm_iommu_init(pbm); | 1527 | schizo_pbm_iommu_init(pbm); |
1567 | schizo_pbm_strbuf_init(pbm); | 1528 | schizo_pbm_strbuf_init(pbm); |
@@ -1580,23 +1541,15 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) | |||
1580 | static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) | 1541 | static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) |
1581 | { | 1542 | { |
1582 | struct pci_controller_info *p; | 1543 | struct pci_controller_info *p; |
1544 | struct pci_pbm_info *pbm; | ||
1583 | struct iommu *iommu; | 1545 | struct iommu *iommu; |
1584 | u32 portid; | 1546 | u32 portid; |
1585 | 1547 | ||
1586 | portid = of_getintprop_default(dp, "portid", 0xff); | 1548 | portid = of_getintprop_default(dp, "portid", 0xff); |
1587 | 1549 | ||
1588 | for (p = pci_controller_root; p; p = p->next) { | 1550 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
1589 | struct pci_pbm_info *pbm; | ||
1590 | |||
1591 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | ||
1592 | continue; | ||
1593 | |||
1594 | pbm = (p->pbm_A.prom_node ? | ||
1595 | &p->pbm_A : | ||
1596 | &p->pbm_B); | ||
1597 | |||
1598 | if (portid_compare(pbm->portid, portid, chip_type)) { | 1551 | if (portid_compare(pbm->portid, portid, chip_type)) { |
1599 | schizo_pbm_init(p, dp, portid, chip_type); | 1552 | schizo_pbm_init(pbm->parent, dp, portid, chip_type); |
1600 | return; | 1553 | return; |
1601 | } | 1554 | } |
1602 | } | 1555 | } |
@@ -1617,13 +1570,6 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ | |||
1617 | 1570 | ||
1618 | p->pbm_B.iommu = iommu; | 1571 | p->pbm_B.iommu = iommu; |
1619 | 1572 | ||
1620 | p->next = pci_controller_root; | ||
1621 | pci_controller_root = p; | ||
1622 | |||
1623 | p->index = pci_num_controllers++; | ||
1624 | p->scan_bus = schizo_scan_bus; | ||
1625 | p->pci_ops = &schizo_ops; | ||
1626 | |||
1627 | /* Like PSYCHO we have a 2GB aligned area for memory space. */ | 1573 | /* Like PSYCHO we have a 2GB aligned area for memory space. */ |
1628 | pci_memspace_mask = 0x7fffffffUL; | 1574 | pci_memspace_mask = 0x7fffffffUL; |
1629 | 1575 | ||