vserver 2.0 rc7
[linux-2.6.git] / arch / sparc64 / kernel / pci_schizo.c
index 9f0a34f..5753175 100644 (file)
@@ -326,9 +326,9 @@ static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
        return ret;
 }
 
-static unsigned int __init schizo_irq_build(struct pci_pbm_info *pbm,
-                                           struct pci_dev *pdev,
-                                           unsigned int ino)
+static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
+                                    struct pci_dev *pdev,
+                                    unsigned int ino)
 {
        struct ino_bucket *bucket;
        unsigned long imap, iclr;
@@ -382,19 +382,57 @@ static unsigned long stc_error_buf[128];
 static unsigned long stc_tag_buf[16];
 static unsigned long stc_line_buf[16];
 
-/* These offsets look weird because I keep in pbm->controller_regs
- * the second PROM register property minus 0x10000 which is the
- * base of the Safari and UPA64S registers of SCHIZO.
- */
-#define SCHIZO_PBM_A_REGS_OFF  (0x600000UL - 0x400000UL)
-#define SCHIZO_PBM_B_REGS_OFF  (0x700000UL - 0x400000UL)
+#define SCHIZO_UE_INO          0x30 /* Uncorrectable ECC error */
+#define SCHIZO_CE_INO          0x31 /* Correctable ECC error */
+#define SCHIZO_PCIERR_A_INO    0x32 /* PBM A PCI bus error */
+#define SCHIZO_PCIERR_B_INO    0x33 /* PBM B PCI bus error */
+#define SCHIZO_SERR_INO                0x34 /* Safari interface error */
+
+struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino)
+{
+       ino &= IMAP_INO;
+       if (p->pbm_A.ino_bitmap & (1UL << ino))
+               return &p->pbm_A;
+       if (p->pbm_B.ino_bitmap & (1UL << ino))
+               return &p->pbm_B;
+
+       printk("PCI%d: No ino_bitmap entry for ino[%x], bitmaps "
+              "PBM_A[%016lx] PBM_B[%016lx]",
+              p->index, ino,
+              p->pbm_A.ino_bitmap,
+              p->pbm_B.ino_bitmap);
+       printk("PCI%d: Using PBM_A, report this problem immediately.\n",
+              p->index);
+
+       return &p->pbm_A;
+}
 
-static void schizo_clear_other_err_intr(int irq)
+static void schizo_clear_other_err_intr(struct pci_controller_info *p, int irq)
 {
-       struct ino_bucket *bucket = __bucket(irq);
-       unsigned long iclr = bucket->iclr;
+       struct pci_pbm_info *pbm;
+       struct ino_bucket *bucket;
+       unsigned long iclr;
+
+       /* Do not clear the interrupt for the other PCI bus.
+        *
+        * This "ACK both PBM IRQs" only needs to be performed
+        * for chip-wide error interrupts.
+        */
+       if ((irq & IMAP_INO) == SCHIZO_PCIERR_A_INO ||
+           (irq & IMAP_INO) == SCHIZO_PCIERR_B_INO)
+               return;
+
+       pbm = pbm_for_ino(p, irq);
+       if (pbm == &p->pbm_A)
+               pbm = &p->pbm_B;
+       else
+               pbm = &p->pbm_A;
+
+       irq = schizo_irq_build(pbm, NULL,
+                              (pbm->portid << 6) | (irq & IMAP_INO));
+       bucket = __bucket(irq);
+       iclr = bucket->iclr;
 
-       iclr += (SCHIZO_PBM_B_REGS_OFF - SCHIZO_PBM_A_REGS_OFF);
        upa_writel(ICLR_IDLE, iclr);
 }
 
@@ -728,7 +766,7 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
        /* Interrogate IOMMU for error status. */
        schizo_check_iommu_error(p, UE_ERR);
 
-       schizo_clear_other_err_intr(irq);
+       schizo_clear_other_err_intr(p, irq);
 
        return IRQ_HANDLED;
 }
@@ -819,7 +857,7 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
                printk("(none)");
        printk("]\n");
 
-       schizo_clear_other_err_intr(irq);
+       schizo_clear_other_err_intr(p, irq);
 
        return IRQ_HANDLED;
 }
@@ -856,9 +894,9 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
 #define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) /* Safari */
 #define SCHIZO_PCICTRL_SERR    (1UL << 34UL) /* Safari/Tomatillo */
 #define SCHIZO_PCICTRL_PCISPD  (1UL << 33UL) /* Safari */
-#define SCHIZO_PCICTRL_MRM_PREF        (1UL << 28UL) /* Tomatillo */
-#define SCHIZO_PCICTRL_RDO_PREF        (1UL << 27UL) /* Tomatillo */
-#define SCHIZO_PCICTRL_RDL_PREF        (1UL << 26UL) /* Tomatillo */
+#define SCHIZO_PCICTRL_MRM_PREF        (1UL << 30UL) /* Tomatillo */
+#define SCHIZO_PCICTRL_RDO_PREF        (1UL << 29UL) /* Tomatillo */
+#define SCHIZO_PCICTRL_RDL_PREF        (1UL << 28UL) /* Tomatillo */
 #define SCHIZO_PCICTRL_PTO     (3UL << 24UL) /* Safari/Tomatillo */
 #define SCHIZO_PCICTRL_PTO_SHIFT 24UL
 #define SCHIZO_PCICTRL_TRWSW   (7UL << 21UL) /* Tomatillo */
@@ -1040,7 +1078,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
        if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR))
                pci_scan_for_parity_error(p, pbm, pbm->pci_bus);
 
-       schizo_clear_other_err_intr(irq);
+       schizo_clear_other_err_intr(p, irq);
 
        return IRQ_HANDLED;
 }
@@ -1097,7 +1135,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
                printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n",
                       p->index, errlog);
 
-               schizo_clear_other_err_intr(irq);
+               schizo_clear_other_err_intr(p, irq);
                return IRQ_HANDLED;
        }
 
@@ -1105,7 +1143,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
               p->index);
        schizo_check_iommu_error(p, SAFARI_ERR);
 
-       schizo_clear_other_err_intr(irq);
+       schizo_clear_other_err_intr(p, irq);
        return IRQ_HANDLED;
 }
 
@@ -1120,26 +1158,6 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
 #define SCHIZO_SAFARI_IRQCTRL  0x10010UL
 #define  SCHIZO_SAFIRQCTRL_EN   0x8000000000000000UL
 
-#define SCHIZO_UE_INO          0x30 /* Uncorrectable ECC error */
-#define SCHIZO_CE_INO          0x31 /* Correctable ECC error */
-#define SCHIZO_PCIERR_A_INO    0x32 /* PBM A PCI bus error */
-#define SCHIZO_PCIERR_B_INO    0x33 /* PBM B PCI bus error */
-#define SCHIZO_SERR_INO                0x34 /* Safari interface error */
-
-struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino)
-{
-       ino &= IMAP_INO;
-       if (p->pbm_A.ino_bitmap & (1UL << ino))
-               return &p->pbm_A;
-       if (p->pbm_B.ino_bitmap & (1UL << ino))
-               return &p->pbm_B;
-       prom_printf("TOMATILLO%d: No entry in ino bitmap for %d\n",
-                   p->index, ino);
-       prom_halt();
-       /* NOTREACHED */
-       return NULL;
-}
-
 /* How the Tomatillo IRQs are routed around is pure guesswork here.
  *
  * All the Tomatillo devices I see in prtconf dumps seem to have only
@@ -1554,7 +1572,7 @@ static void __init schizo_base_address_update(struct pci_dev *pdev, int resource
               (((u32)(res->start - root->start)) & ~size));
        if (resource == PCI_ROM_RESOURCE) {
                reg |= PCI_ROM_ADDRESS_ENABLE;
-               res->flags |= PCI_ROM_ADDRESS_ENABLE;
+               res->flags |= IORESOURCE_ROM_ENABLE;
        }
        pci_write_config_dword(pdev, where, reg);
 
@@ -1735,7 +1753,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
 
        /* Setup initial software IOMMU state. */
        spin_lock_init(&iommu->lock);
-       iommu->iommu_cur_ctx = 0;
+       iommu->ctx_lowest_free = 1;
 
        /* Register addresses, SCHIZO has iommu ctx flushing. */
        iommu->iommu_control  = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
@@ -1887,7 +1905,7 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
 
        tmp &= ~SCHIZO_PCICTRL_PTO;
        if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
-           pbm->chip_version == 0x2)
+           pbm->chip_version >= 0x2)
                tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT;
        else
                tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT;
@@ -1895,8 +1913,16 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
        if (!prom_getbool(pbm->prom_node, "no-bus-parking"))
                tmp |= SCHIZO_PCICTRL_PARK;
 
+       if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
+           pbm->chip_version <= 0x1)
+               tmp |= (1UL << 61);
+       else
+               tmp &= ~(1UL << 61);
+
        if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO)
-               tmp |= SCHIZO_PCICTRL_MRM_PREF;
+               tmp |= (SCHIZO_PCICTRL_MRM_PREF |
+                       SCHIZO_PCICTRL_RDO_PREF |
+                       SCHIZO_PCICTRL_RDL_PREF);
 
        schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp);