aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_sabre.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2006-06-29 18:07:37 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-29 19:37:38 -0400
commit2b1e59787198e75fb2ffb3bb4fb247da1c55ac12 (patch)
tree96d74048849b310135e0c79f663b16c52186caa5 /arch/sparc64/kernel/pci_sabre.c
parentc3a8b85f5ac2c21f4ef75e87bfe55ee7a753ffcf (diff)
[SPARC64]: of_device layer IRQ resolution
Do IRQ determination generically by parsing the PROM properties, and using IRQ controller drivers for final resolution. One immediate positive effect is that all of the IRQ frobbing in the EBUS, ISA, and PCI controller layers has been eliminated. We just look up the of_device and use the properly computed value. The PCI controller irq_build() routines are gone and no longer used. Unfortunately sbus_build_irq() has to remain as there is a direct reference to this in the sunzilog driver. That can be killed off once the sparc32 side of this is written and the sunzilog driver is transformed into an "of" bus driver. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_sabre.c')
-rw-r--r--arch/sparc64/kernel/pci_sabre.c158
1 files changed, 23 insertions, 135 deletions
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 26f194ce4400..5e087b0fb4c9 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -485,114 +485,6 @@ static struct pci_ops sabre_ops = {
485 .write = sabre_write_pci_cfg, 485 .write = sabre_write_pci_cfg,
486}; 486};
487 487
488static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
489{
490 unsigned int bus = (ino & 0x10) >> 4;
491 unsigned int slot = (ino & 0x0c) >> 2;
492
493 if (bus == 0)
494 return SABRE_IMAP_A_SLOT0 + (slot * 8);
495 else
496 return SABRE_IMAP_B_SLOT0 + (slot * 8);
497}
498
499static unsigned long __onboard_imap_off[] = {
500/*0x20*/ SABRE_IMAP_SCSI,
501/*0x21*/ SABRE_IMAP_ETH,
502/*0x22*/ SABRE_IMAP_BPP,
503/*0x23*/ SABRE_IMAP_AU_REC,
504/*0x24*/ SABRE_IMAP_AU_PLAY,
505/*0x25*/ SABRE_IMAP_PFAIL,
506/*0x26*/ SABRE_IMAP_KMS,
507/*0x27*/ SABRE_IMAP_FLPY,
508/*0x28*/ SABRE_IMAP_SHW,
509/*0x29*/ SABRE_IMAP_KBD,
510/*0x2a*/ SABRE_IMAP_MS,
511/*0x2b*/ SABRE_IMAP_SER,
512/*0x2c*/ 0 /* reserved */,
513/*0x2d*/ 0 /* reserved */,
514/*0x2e*/ SABRE_IMAP_UE,
515/*0x2f*/ SABRE_IMAP_CE,
516/*0x30*/ SABRE_IMAP_PCIERR,
517};
518#define SABRE_ONBOARD_IRQ_BASE 0x20
519#define SABRE_ONBOARD_IRQ_LAST 0x30
520#define sabre_onboard_imap_offset(__ino) \
521 __onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE]
522
523#define sabre_iclr_offset(ino) \
524 ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \
525 (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
526
527/* When a device lives behind a bridge deeper in the PCI bus topology
528 * than APB, a special sequence must run to make sure all pending DMA
529 * transfers at the time of IRQ delivery are visible in the coherency
530 * domain by the cpu. This sequence is to perform a read on the far
531 * side of the non-APB bridge, then perform a read of Sabre's DMA
532 * write-sync register.
533 */
534static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
535{
536 struct pci_dev *pdev = _arg1;
537 unsigned long sync_reg = (unsigned long) _arg2;
538 u16 _unused;
539
540 pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused);
541 sabre_read(sync_reg);
542}
543
544static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
545 struct pci_dev *pdev,
546 unsigned int ino)
547{
548 unsigned long imap, iclr;
549 unsigned long imap_off, iclr_off;
550 int inofixup = 0;
551 int virt_irq;
552
553 ino &= PCI_IRQ_INO;
554 if (ino < SABRE_ONBOARD_IRQ_BASE) {
555 /* PCI slot */
556 imap_off = sabre_pcislot_imap_offset(ino);
557 } else {
558 /* onboard device */
559 if (ino > SABRE_ONBOARD_IRQ_LAST) {
560 prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino);
561 prom_halt();
562 }
563 imap_off = sabre_onboard_imap_offset(ino);
564 }
565
566 /* Now build the IRQ bucket. */
567 imap = pbm->controller_regs + imap_off;
568 imap += 4;
569
570 iclr_off = sabre_iclr_offset(ino);
571 iclr = pbm->controller_regs + iclr_off;
572 iclr += 4;
573
574 if ((ino & 0x20) == 0)
575 inofixup = ino & 0x03;
576
577 virt_irq = build_irq(inofixup, iclr, imap);
578
579 if (pdev) {
580 struct pcidev_cookie *pcp = pdev->sysdata;
581
582 if (pdev->bus->number != pcp->pbm->pci_first_busno) {
583 struct pci_controller_info *p = pcp->pbm->parent;
584
585 irq_install_pre_handler(virt_irq,
586 sabre_wsync_handler,
587 pdev,
588 (void *)
589 p->pbm_A.controller_regs +
590 SABRE_WRSYNC);
591 }
592 }
593 return virt_irq;
594}
595
596/* SABRE error handling support. */ 488/* SABRE error handling support. */
597static void sabre_check_iommu_error(struct pci_controller_info *p, 489static void sabre_check_iommu_error(struct pci_controller_info *p,
598 unsigned long afsr, 490 unsigned long afsr,
@@ -929,17 +821,30 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
929 return IRQ_HANDLED; 821 return IRQ_HANDLED;
930} 822}
931 823
932/* XXX What about PowerFail/PowerManagement??? -DaveM */
933#define SABRE_UE_INO 0x2e
934#define SABRE_CE_INO 0x2f
935#define SABRE_PCIERR_INO 0x30
936static void sabre_register_error_handlers(struct pci_controller_info *p) 824static void sabre_register_error_handlers(struct pci_controller_info *p)
937{ 825{
938 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 826 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
827 struct device_node *dp = pbm->prom_node;
828 struct of_device *op;
939 unsigned long base = pbm->controller_regs; 829 unsigned long base = pbm->controller_regs;
940 unsigned long irq, portid = pbm->portid;
941 u64 tmp; 830 u64 tmp;
942 831
832 if (pbm->chip_type == PBM_CHIP_TYPE_SABRE)
833 dp = dp->parent;
834
835 op = of_find_device_by_node(dp);
836 if (!op)
837 return;
838
839 /* Sabre/Hummingbird IRQ property layout is:
840 * 0: PCI ERR
841 * 1: UE ERR
842 * 2: CE ERR
843 * 3: POWER FAIL
844 */
845 if (op->num_irqs < 4)
846 return;
847
943 /* We clear the error bits in the appropriate AFSR before 848 /* We clear the error bits in the appropriate AFSR before
944 * registering the handler so that we don't get spurious 849 * registering the handler so that we don't get spurious
945 * interrupts. 850 * interrupts.
@@ -948,32 +853,16 @@ static void sabre_register_error_handlers(struct pci_controller_info *p)
948 (SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR | 853 (SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
949 SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR | 854 SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
950 SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE)); 855 SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE));
951 irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_UE_INO); 856
952 if (request_irq(irq, sabre_ue_intr, 857 request_irq(op->irqs[1], sabre_ue_intr, SA_SHIRQ, "SABRE UE", p);
953 SA_SHIRQ, "SABRE UE", p) < 0) {
954 prom_printf("SABRE%d: Cannot register UE interrupt.\n",
955 p->index);
956 prom_halt();
957 }
958 858
959 sabre_write(base + SABRE_CE_AFSR, 859 sabre_write(base + SABRE_CE_AFSR,
960 (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | 860 (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
961 SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); 861 SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR));
962 irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_CE_INO);
963 if (request_irq(irq, sabre_ce_intr,
964 SA_SHIRQ, "SABRE CE", p) < 0) {
965 prom_printf("SABRE%d: Cannot register CE interrupt.\n",
966 p->index);
967 prom_halt();
968 }
969 862
970 irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_PCIERR_INO); 863 request_irq(op->irqs[2], sabre_ce_intr, SA_SHIRQ, "SABRE CE", p);
971 if (request_irq(irq, sabre_pcierr_intr, 864 request_irq(op->irqs[0], sabre_pcierr_intr, SA_SHIRQ,
972 SA_SHIRQ, "SABRE PCIERR", p) < 0) { 865 "SABRE PCIERR", p);
973 prom_printf("SABRE%d: Cannot register PciERR interrupt.\n",
974 p->index);
975 prom_halt();
976 }
977 866
978 tmp = sabre_read(base + SABRE_PCICTRL); 867 tmp = sabre_read(base + SABRE_PCICTRL);
979 tmp |= SABRE_PCICTRL_ERREN; 868 tmp |= SABRE_PCICTRL_ERREN;
@@ -1492,7 +1381,6 @@ void sabre_init(struct device_node *dp, char *model_name)
1492 p->index = pci_num_controllers++; 1381 p->index = pci_num_controllers++;
1493 p->pbms_same_domain = 1; 1382 p->pbms_same_domain = 1;
1494 p->scan_bus = sabre_scan_bus; 1383 p->scan_bus = sabre_scan_bus;
1495 p->irq_build = sabre_irq_build;
1496 p->base_address_update = sabre_base_address_update; 1384 p->base_address_update = sabre_base_address_update;
1497 p->resource_adjust = sabre_resource_adjust; 1385 p->resource_adjust = sabre_resource_adjust;
1498 p->pci_ops = &sabre_ops; 1386 p->pci_ops = &sabre_ops;