fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / sparc64 / kernel / pci_schizo.c
index b70e45f..66911b1 100644 (file)
@@ -15,6 +15,8 @@
 #include <asm/iommu.h>
 #include <asm/irq.h>
 #include <asm/upa.h>
+#include <asm/pstate.h>
+#include <asm/prom.h>
 
 #include "pci_impl.h"
 #include "iommu_common.h"
 #define SCHIZO_STRBUF_CTRL_ENAB    0x0000000000000001UL /* Streaming Buffer Enable */
 
 /* IOMMU control register. */
-#define SCHIZO_IOMMU_CTRL_RESV     0xfffffffff9000000 /* Reserved                      */
-#define SCHIZO_IOMMU_CTRL_XLTESTAT 0x0000000006000000 /* Translation Error Status      */
-#define SCHIZO_IOMMU_CTRL_XLTEERR  0x0000000001000000 /* Translation Error encountered */
-#define SCHIZO_IOMMU_CTRL_LCKEN    0x0000000000800000 /* Enable translation locking    */
-#define SCHIZO_IOMMU_CTRL_LCKPTR   0x0000000000780000 /* Translation lock pointer      */
-#define SCHIZO_IOMMU_CTRL_TSBSZ    0x0000000000070000 /* TSB Size                      */
-#define SCHIZO_IOMMU_TSBSZ_1K      0x0000000000000000 /* TSB Table 1024 8-byte entries */
-#define SCHIZO_IOMMU_TSBSZ_2K      0x0000000000010000 /* TSB Table 2048 8-byte entries */
-#define SCHIZO_IOMMU_TSBSZ_4K      0x0000000000020000 /* TSB Table 4096 8-byte entries */
-#define SCHIZO_IOMMU_TSBSZ_8K      0x0000000000030000 /* TSB Table 8192 8-byte entries */
-#define SCHIZO_IOMMU_TSBSZ_16K     0x0000000000040000 /* TSB Table 16k 8-byte entries  */
-#define SCHIZO_IOMMU_TSBSZ_32K     0x0000000000050000 /* TSB Table 32k 8-byte entries  */
-#define SCHIZO_IOMMU_TSBSZ_64K     0x0000000000060000 /* TSB Table 64k 8-byte entries  */
-#define SCHIZO_IOMMU_TSBSZ_128K    0x0000000000070000 /* TSB Table 128k 8-byte entries */
-#define SCHIZO_IOMMU_CTRL_RESV2    0x000000000000fff8 /* Reserved                      */
-#define SCHIZO_IOMMU_CTRL_TBWSZ    0x0000000000000004 /* Assumed page size, 0=8k 1=64k */
-#define SCHIZO_IOMMU_CTRL_DENAB    0x0000000000000002 /* Diagnostic mode enable        */
-#define SCHIZO_IOMMU_CTRL_ENAB     0x0000000000000001 /* IOMMU Enable                  */
+#define SCHIZO_IOMMU_CTRL_RESV     0xfffffffff9000000UL /* Reserved                      */
+#define SCHIZO_IOMMU_CTRL_XLTESTAT 0x0000000006000000UL /* Translation Error Status      */
+#define SCHIZO_IOMMU_CTRL_XLTEERR  0x0000000001000000UL /* Translation Error encountered */
+#define SCHIZO_IOMMU_CTRL_LCKEN    0x0000000000800000UL /* Enable translation locking    */
+#define SCHIZO_IOMMU_CTRL_LCKPTR   0x0000000000780000UL /* Translation lock pointer      */
+#define SCHIZO_IOMMU_CTRL_TSBSZ    0x0000000000070000UL /* TSB Size                      */
+#define SCHIZO_IOMMU_TSBSZ_1K      0x0000000000000000UL /* TSB Table 1024 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_2K      0x0000000000010000UL /* TSB Table 2048 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_4K      0x0000000000020000UL /* TSB Table 4096 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_8K      0x0000000000030000UL /* TSB Table 8192 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_16K     0x0000000000040000UL /* TSB Table 16k 8-byte entries  */
+#define SCHIZO_IOMMU_TSBSZ_32K     0x0000000000050000UL /* TSB Table 32k 8-byte entries  */
+#define SCHIZO_IOMMU_TSBSZ_64K     0x0000000000060000UL /* TSB Table 64k 8-byte entries  */
+#define SCHIZO_IOMMU_TSBSZ_128K    0x0000000000070000UL /* TSB Table 128k 8-byte entries */
+#define SCHIZO_IOMMU_CTRL_RESV2    0x000000000000fff8UL /* Reserved                      */
+#define SCHIZO_IOMMU_CTRL_TBWSZ    0x0000000000000004UL /* Assumed page size, 0=8k 1=64k */
+#define SCHIZO_IOMMU_CTRL_DENAB    0x0000000000000002UL /* Diagnostic mode enable        */
+#define SCHIZO_IOMMU_CTRL_ENAB     0x0000000000000001UL /* IOMMU Enable                  */
 
 /* Schizo config space address format is nearly identical to
  * that of PSYCHO:
@@ -215,187 +217,39 @@ static struct pci_ops schizo_ops = {
        .write =        schizo_write_pci_cfg,
 };
 
-/* SCHIZO interrupt mapping support.  Unlike Psycho, for this controller the
- * imap/iclr registers are per-PBM.
- */
-#define SCHIZO_IMAP_BASE       0x1000UL
-#define SCHIZO_ICLR_BASE       0x1400UL
-
-static unsigned long schizo_imap_offset(unsigned long ino)
-{
-       return SCHIZO_IMAP_BASE + (ino * 8UL);
-}
-
-static unsigned long schizo_iclr_offset(unsigned long ino)
-{
-       return SCHIZO_ICLR_BASE + (ino * 8UL);
-}
-
-/* PCI SCHIZO INO number to Sparc PIL level.  This table only matters for
- * INOs which will not have an associated PCI device struct, ie. onboard
- * EBUS devices and PCI controller internal error interrupts.
- */
-static unsigned char schizo_pil_table[] = {
-/*0x00*/0, 0, 0, 0,    /* PCI slot 0  Int A, B, C, D   */
-/*0x04*/0, 0, 0, 0,    /* PCI slot 1  Int A, B, C, D   */
-/*0x08*/0, 0, 0, 0,    /* PCI slot 2  Int A, B, C, D   */
-/*0x0c*/0, 0, 0, 0,    /* PCI slot 3  Int A, B, C, D   */
-/*0x10*/0, 0, 0, 0,    /* PCI slot 4  Int A, B, C, D   */
-/*0x14*/0, 0, 0, 0,    /* PCI slot 5  Int A, B, C, D   */
-/*0x18*/4,             /* SCSI                         */
-/*0x19*/4,             /* second SCSI                  */
-/*0x1a*/0,             /* UNKNOWN                      */
-/*0x1b*/0,             /* UNKNOWN                      */
-/*0x1c*/8,             /* Parallel                     */
-/*0x1d*/5,             /* Ethernet                     */
-/*0x1e*/8,             /* Firewire-1394                */
-/*0x1f*/9,             /* USB                          */
-/*0x20*/13,            /* Audio Record                 */
-/*0x21*/14,            /* Audio Playback               */
-/*0x22*/12,            /* Serial                       */
-/*0x23*/4,             /* EBUS I2C                     */
-/*0x24*/10,            /* RTC Clock                    */
-/*0x25*/11,            /* Floppy                       */
-/*0x26*/0,             /* UNKNOWN                      */
-/*0x27*/0,             /* UNKNOWN                      */
-/*0x28*/0,             /* UNKNOWN                      */
-/*0x29*/0,             /* UNKNOWN                      */
-/*0x2a*/10,            /* UPA 1                        */
-/*0x2b*/10,            /* UPA 2                        */
-/*0x2c*/0,             /* UNKNOWN                      */
-/*0x2d*/0,             /* UNKNOWN                      */
-/*0x2e*/0,             /* UNKNOWN                      */
-/*0x2f*/0,             /* UNKNOWN                      */
-/*0x30*/15,            /* Uncorrectable ECC            */
-/*0x31*/15,            /* Correctable ECC              */
-/*0x32*/15,            /* PCI Bus A Error              */
-/*0x33*/15,            /* PCI Bus B Error              */
-/*0x34*/15,            /* Safari Bus Error             */
-/*0x35*/0,             /* Reserved                     */
-/*0x36*/0,             /* Reserved                     */
-/*0x37*/0,             /* Reserved                     */
-/*0x38*/0,             /* Reserved for NewLink         */
-/*0x39*/0,             /* Reserved for NewLink         */
-/*0x3a*/0,             /* Reserved for NewLink         */
-/*0x3b*/0,             /* Reserved for NewLink         */
-/*0x3c*/0,             /* Reserved for NewLink         */
-/*0x3d*/0,             /* Reserved for NewLink         */
-/*0x3e*/0,             /* Reserved for NewLink         */
-/*0x3f*/0,             /* Reserved for NewLink         */
-};
-
-static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
-{
-       int ret;
-
-       if (pdev &&
-           pdev->vendor == PCI_VENDOR_ID_SUN &&
-           pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
-               return 9;
-
-       ret = schizo_pil_table[ino];
-       if (ret == 0 && pdev == NULL) {
-               ret = 4;
-       } else if (ret == 0) {
-               switch ((pdev->class >> 16) & 0xff) {
-               case PCI_BASE_CLASS_STORAGE:
-                       ret = 4;
-                       break;
-
-               case PCI_BASE_CLASS_NETWORK:
-                       ret = 6;
-                       break;
-
-               case PCI_BASE_CLASS_DISPLAY:
-                       ret = 9;
-                       break;
-
-               case PCI_BASE_CLASS_MULTIMEDIA:
-               case PCI_BASE_CLASS_MEMORY:
-               case PCI_BASE_CLASS_BRIDGE:
-               case PCI_BASE_CLASS_SERIAL:
-                       ret = 10;
-                       break;
-
-               default:
-                       ret = 4;
-                       break;
-               };
-       }
-
-       return ret;
-}
-
-static unsigned int __init schizo_irq_build(struct pci_pbm_info *pbm,
-                                           struct pci_dev *pdev,
-                                           unsigned int ino)
-{
-       struct ino_bucket *bucket;
-       unsigned long imap, iclr;
-       unsigned long imap_off, iclr_off;
-       int pil, ign_fixup;
-
-       ino &= PCI_IRQ_INO;
-       imap_off = schizo_imap_offset(ino);
-
-       /* Now build the IRQ bucket. */
-       pil = schizo_ino_to_pil(pdev, ino);
-
-       if (PIL_RESERVED(pil))
-               BUG();
-
-       imap = pbm->pbm_regs + imap_off;
-       imap += 4;
-
-       iclr_off = schizo_iclr_offset(ino);
-       iclr = pbm->pbm_regs + iclr_off;
-       iclr += 4;
-
-       /* On Schizo, no inofixup occurs.  This is because each
-        * INO has it's own IMAP register.  On Psycho and Sabre
-        * there is only one IMAP register for each PCI slot even
-        * though four different INOs can be generated by each
-        * PCI slot.
-        *
-        * But, for JBUS variants (essentially, Tomatillo), we have
-        * to fixup the lowest bit of the interrupt group number.
-        */
-       ign_fixup = 0;
-       if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {
-               if (pbm->portid & 1)
-                       ign_fixup = (1 << 6);
-       }
-
-       bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap));
-       bucket->flags |= IBF_PCI;
-
-       return __irq(bucket);
-}
-
 /* SCHIZO error handling support. */
 enum schizo_error_type {
        UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR
 };
 
-static spinlock_t stc_buf_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(stc_buf_lock);
 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 */
 
-static void schizo_clear_other_err_intr(int irq)
+struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino)
 {
-       struct ino_bucket *bucket = __bucket(irq);
-       unsigned long iclr = bucket->iclr;
+       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);
 
-       iclr += (SCHIZO_PBM_B_REGS_OFF - SCHIZO_PBM_A_REGS_OFF);
-       upa_writel(ICLR_IDLE, iclr);
+       return &p->pbm_A;
 }
 
 #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */
@@ -661,7 +515,7 @@ static void schizo_check_iommu_error(struct pci_controller_info *p,
 #define SCHIZO_UEAFSR_MTAG     0x000000000000e000UL /* Safari */
 #define SCHIZO_UEAFSR_ECCSYND  0x00000000000001ffUL /* Safari */
 
-static irqreturn_t schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t schizo_ue_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFSR;
@@ -728,8 +582,6 @@ 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);
-
        return IRQ_HANDLED;
 }
 
@@ -751,7 +603,7 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
 #define SCHIZO_CEAFSR_MTAG     0x000000000000e000UL
 #define SCHIZO_CEAFSR_ECCSYND  0x00000000000001ffUL
 
-static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t schizo_ce_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFSR;
@@ -819,8 +671,6 @@ 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);
-
        return IRQ_HANDLED;
 }
 
@@ -847,6 +697,7 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
 
 #define SCHIZO_PCI_CTRL                (0x2000UL)
 #define SCHIZO_PCICTRL_BUS_UNUS        (1UL << 63UL) /* Safari */
+#define SCHIZO_PCICTRL_DTO_INT (1UL << 61UL) /* Tomatillo */
 #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */
 #define SCHIZO_PCICTRL_ESLCK   (1UL << 51UL) /* Safari */
 #define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */
@@ -856,9 +707,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 */
@@ -927,7 +778,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
        return ret;
 }
 
-static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id)
 {
        struct pci_pbm_info *pbm = dev_id;
        struct pci_controller_info *p = pbm->parent;
@@ -1040,8 +891,6 @@ 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);
-
        return IRQ_HANDLED;
 }
 
@@ -1084,7 +933,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
 /* We only expect UNMAP errors here.  The rest of the Safari errors
  * are marked fatal and thus cause a system reset.
  */
-static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        u64 errlog;
@@ -1097,7 +946,6 @@ 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);
                return IRQ_HANDLED;
        }
 
@@ -1105,41 +953,20 @@ 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);
        return IRQ_HANDLED;
 }
 
 /* Nearly identical to PSYCHO equivalents... */
 #define SCHIZO_ECC_CTRL                0x10020UL
-#define  SCHIZO_ECCCTRL_EE      0x8000000000000000 /* Enable ECC Checking */
-#define  SCHIZO_ECCCTRL_UE      0x4000000000000000 /* Enable UE Interrupts */
-#define  SCHIZO_ECCCTRL_CE      0x2000000000000000 /* Enable CE INterrupts */
+#define  SCHIZO_ECCCTRL_EE      0x8000000000000000UL /* Enable ECC Checking */
+#define  SCHIZO_ECCCTRL_UE      0x4000000000000000UL /* Enable UE Interrupts */
+#define  SCHIZO_ECCCTRL_CE      0x2000000000000000UL /* Enable CE INterrupts */
 
 #define SCHIZO_SAFARI_ERRCTRL  0x10008UL
 #define  SCHIZO_SAFERRCTRL_EN   0x8000000000000000UL
 #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
@@ -1154,80 +981,50 @@ struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino)
  * PCI bus units of the same Tomatillo.  I still have not really
  * figured this out...
  */
-static void __init tomatillo_register_error_handlers(struct pci_controller_info *p)
+static void tomatillo_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm;
-       unsigned int irq;
-       struct ino_bucket *bucket;
+       struct of_device *op;
        u64 tmp, err_mask, err_no_mask;
 
-       /* Build IRQs and register handlers. */
+       /* Tomatillo IRQ property layout is:
+        * 0: PCIERR
+        * 1: UE ERR
+        * 2: CE ERR
+        * 3: SERR
+        * 4: POWER FAIL?
+        */
+
        pbm = pbm_for_ino(p, SCHIZO_UE_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO);
-       if (request_irq(irq, schizo_ue_intr,
-                       SA_SHIRQ, "TOMATILLO UE", p) < 0) {
-               prom_printf("%s: Cannot register UE interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_UE_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED,
+                           "TOMATILLO_UE", p);
 
        pbm = pbm_for_ino(p, SCHIZO_CE_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO);
-       if (request_irq(irq, schizo_ce_intr,
-                       SA_SHIRQ, "TOMATILLO CE", p) < 0) {
-               prom_printf("%s: Cannot register CE interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = upa_readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_CE_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED,
+                           "TOMATILLO CE", p);
 
        pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO);
-       irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) |
-                                          SCHIZO_PCIERR_A_INO));
-       if (request_irq(irq, schizo_pcierr_intr,
-                       SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) {
-               prom_printf("%s: Cannot register PBM A PciERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = upa_readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED,
+                           "TOMATILLO PCIERR-A", pbm);
+
 
        pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO);
-       irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) |
-                                           SCHIZO_PCIERR_B_INO));
-       if (request_irq(irq, schizo_pcierr_intr,
-                       SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) {
-               prom_printf("%s: Cannot register PBM B PciERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = upa_readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED,
+                           "TOMATILLO PCIERR-B", pbm);
 
        pbm = pbm_for_ino(p, SCHIZO_SERR_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO);
-       if (request_irq(irq, schizo_safarierr_intr,
-                       SA_SHIRQ, "TOMATILLO SERR", p) < 0) {
-               prom_printf("%s: Cannot register SafariERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = upa_readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_SERR_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED,
+                           "TOMATILLO SERR", p);
 
        /* Enable UE and CE interrupts for controller. */
        schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL,
@@ -1292,73 +1089,50 @@ static void __init tomatillo_register_error_handlers(struct pci_controller_info
                     (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
 }
 
-static void __init schizo_register_error_handlers(struct pci_controller_info *p)
+static void schizo_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm;
-       unsigned int irq;
-       struct ino_bucket *bucket;
+       struct of_device *op;
        u64 tmp, err_mask, err_no_mask;
 
-       /* Build IRQs and register handlers. */
+       /* Schizo IRQ property layout is:
+        * 0: PCIERR
+        * 1: UE ERR
+        * 2: CE ERR
+        * 3: SERR
+        * 4: POWER FAIL?
+        */
+
        pbm = pbm_for_ino(p, SCHIZO_UE_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO);
-       if (request_irq(irq, schizo_ue_intr,
-                       SA_SHIRQ, "SCHIZO UE", p) < 0) {
-               prom_printf("%s: Cannot register UE interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_UE_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED,
+                           "SCHIZO_UE", p);
 
        pbm = pbm_for_ino(p, SCHIZO_CE_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO);
-       if (request_irq(irq, schizo_ce_intr,
-                       SA_SHIRQ, "SCHIZO CE", p) < 0) {
-               prom_printf("%s: Cannot register CE interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = upa_readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_CE_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED,
+                           "SCHIZO CE", p);
 
        pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_A_INO);
-       if (request_irq(irq, schizo_pcierr_intr,
-                       SA_SHIRQ, "SCHIZO PCIERR", pbm) < 0) {
-               prom_printf("%s: Cannot register PBM A PciERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = upa_readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED,
+                           "SCHIZO PCIERR-A", pbm);
+
 
        pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_B_INO);
-       if (request_irq(irq, schizo_pcierr_intr,
-                       SA_SHIRQ, "SCHIZO PCIERR", &p->pbm_B) < 0) {
-               prom_printf("%s: Cannot register PBM B PciERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = upa_readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED,
+                           "SCHIZO PCIERR-B", pbm);
 
        pbm = pbm_for_ino(p, SCHIZO_SERR_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO);
-       if (request_irq(irq, schizo_safarierr_intr,
-                       SA_SHIRQ, "SCHIZO SERR", p) < 0) {
-               prom_printf("%s: Cannot register SafariERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       bucket = __bucket(irq);
-       tmp = upa_readl(bucket->imap);
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_SERR_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED,
+                           "SCHIZO SERR", p);
 
        /* Enable UE and CE interrupts for controller. */
        schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL,
@@ -1372,10 +1146,10 @@ static void __init schizo_register_error_handlers(struct pci_controller_info *p)
                    SCHIZO_PCICTRL_RTRY_ERR |
                    SCHIZO_PCICTRL_SBH_ERR |
                    SCHIZO_PCICTRL_SERR |
-                   SCHIZO_PCICTRL_SBH_INT |
                    SCHIZO_PCICTRL_EEN);
 
-       err_no_mask = SCHIZO_PCICTRL_DTO_ERR;
+       err_no_mask = (SCHIZO_PCICTRL_DTO_ERR |
+                      SCHIZO_PCICTRL_SBH_INT);
 
        /* Enable PCI Error interrupts and clear error
         * bits for each PBM.
@@ -1438,7 +1212,7 @@ static void __init schizo_register_error_handlers(struct pci_controller_info *p)
                     (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
 }
 
-static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+static void pbm_config_busmastering(struct pci_pbm_info *pbm)
 {
        u8 *addr;
 
@@ -1455,10 +1229,10 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
        pci_config_write8(addr, 64);
 }
 
-static void __init pbm_scan_bus(struct pci_controller_info *p,
-                               struct pci_pbm_info *pbm)
+static void pbm_scan_bus(struct pci_controller_info *p,
+                        struct pci_pbm_info *pbm)
 {
-       struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
+       struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);
 
        if (!cookie) {
                prom_printf("%s: Critical allocation failure.\n", pbm->name);
@@ -1466,7 +1240,6 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
        }
 
        /* All we care about is the PBM. */
-       memset(cookie, 0, sizeof(*cookie));
        cookie->pbm = pbm;
 
        pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno,
@@ -1483,8 +1256,8 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
        pci_setup_busmastering(pbm, pbm->pci_bus);
 }
 
-static void __init __schizo_scan_bus(struct pci_controller_info *p,
-                                    int chip_type)
+static void __schizo_scan_bus(struct pci_controller_info *p,
+                             int chip_type)
 {
        if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) {
                printk("PCI: Only one PCI bus module of controller found.\n");
@@ -1494,10 +1267,12 @@ static void __init __schizo_scan_bus(struct pci_controller_info *p,
 
        pbm_config_busmastering(&p->pbm_B);
        p->pbm_B.is_66mhz_capable =
-               prom_getbool(p->pbm_B.prom_node, "66mhz-capable");
+               (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL)
+                != NULL);
        pbm_config_busmastering(&p->pbm_A);
        p->pbm_A.is_66mhz_capable =
-               prom_getbool(p->pbm_A.prom_node, "66mhz-capable");
+               (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL)
+                != NULL);
        pbm_scan_bus(p, &p->pbm_B);
        pbm_scan_bus(p, &p->pbm_A);
 
@@ -1510,17 +1285,17 @@ static void __init __schizo_scan_bus(struct pci_controller_info *p,
                schizo_register_error_handlers(p);
 }
 
-static void __init schizo_scan_bus(struct pci_controller_info *p)
+static void schizo_scan_bus(struct pci_controller_info *p)
 {
        __schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO);
 }
 
-static void __init tomatillo_scan_bus(struct pci_controller_info *p)
+static void tomatillo_scan_bus(struct pci_controller_info *p)
 {
        __schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO);
 }
 
-static void __init schizo_base_address_update(struct pci_dev *pdev, int resource)
+static void schizo_base_address_update(struct pci_dev *pdev, int resource)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
        struct pci_pbm_info *pbm = pcp->pbm;
@@ -1554,7 +1329,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);
 
@@ -1565,9 +1340,9 @@ static void __init schizo_base_address_update(struct pci_dev *pdev, int resource
                pci_write_config_dword(pdev, where + 4, 0);
 }
 
-static void __init schizo_resource_adjust(struct pci_dev *pdev,
-                                         struct resource *res,
-                                         struct resource *root)
+static void schizo_resource_adjust(struct pci_dev *pdev,
+                                  struct resource *res,
+                                  struct resource *root)
 {
        res->start += root->start;
        res->end += root->start;
@@ -1635,8 +1410,8 @@ static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm)
               pbm->mem_space.start);
 }
 
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
-                                                  struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+                                           struct pci_pbm_info *pbm)
 {
        pbm->io_space.name = pbm->mem_space.name = pbm->name;
 
@@ -1698,14 +1473,19 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm)
 static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
 {
        struct pci_iommu *iommu = pbm->iommu;
-       unsigned long tsbbase, i, tagbase, database, order;
+       unsigned long i, tagbase, database;
+       struct property *prop;
        u32 vdma[2], dma_mask;
        u64 control;
-       int err, tsbsize;
+       int tsbsize;
+
+       prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
+       if (prop) {
+               u32 *val = prop->value;
 
-       err = prom_getproperty(pbm->prom_node, "virtual-dma",
-                              (char *)&vdma[0], sizeof(vdma));
-       if (err == 0 || err == -1) {
+               vdma[0] = val[0];
+               vdma[1] = val[1];
+       } else {
                /* No property, use default values. */
                vdma[0] = 0xc0000000;
                vdma[1] = 0x40000000;
@@ -1733,10 +1513,6 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
                        prom_halt();
        };
 
-       /* Setup initial software IOMMU state. */
-       spin_lock_init(&iommu->lock);
-       iommu->iommu_cur_ctx = 0;
-
        /* Register addresses, SCHIZO has iommu ctx flushing. */
        iommu->iommu_control  = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
        iommu->iommu_tsbbase  = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;
@@ -1765,48 +1541,9 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
        /* Leave diag mode enabled for full-flushing done
         * in pci_iommu.c
         */
+       pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
 
-       /* Using assumed page size 8K with 128K entries we need 1MB iommu page
-        * table (128K ioptes * 8 bytes per iopte).  This is
-        * page order 7 on UltraSparc.
-        */
-       order = get_order(tsbsize * 8 * 1024);
-       tsbbase = __get_free_pages(GFP_KERNEL, order);
-       if (!tsbbase) {
-               prom_printf("%s: Error, gfp(tsb) failed.\n", pbm->name);
-               prom_halt();
-       }
-
-       iommu->page_table = (iopte_t *)tsbbase;
-       iommu->page_table_map_base = vdma[0];
-       iommu->dma_addr_mask = dma_mask;
-       memset((char *)tsbbase, 0, PAGE_SIZE << order);
-
-       switch (tsbsize) {
-       case 64:
-               iommu->page_table_sz_bits = 16;
-               break;
-
-       case 128:
-               iommu->page_table_sz_bits = 17;
-               break;
-
-       default:
-               prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
-               prom_halt();
-               break;
-       };
-
-       /* We start with no consistent mappings. */
-       iommu->lowest_consistent_map =
-               1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
-
-       for (i = 0; i < PBM_NCLUSTERS; i++) {
-               iommu->alloc_info[i].flush = 0;
-               iommu->alloc_info[i].next = 0;
-       }
-
-       schizo_write(iommu->iommu_tsbbase, __pa(tsbbase));
+       schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table));
 
        control = schizo_read(iommu->iommu_control);
        control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ);
@@ -1857,38 +1594,38 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
 #define TOMATILLO_PCI_IOC_TDIAG                (0x2250UL)
 #define TOMATILLO_PCI_IOC_DDIAG                (0x2290UL)
 
-static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
+static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
 {
+       struct property *prop;
        u64 tmp;
 
-       /* Set IRQ retry to infinity. */
-       schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY,
-                    SCHIZO_IRQ_RETRY_INF);
+       schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5);
 
-       /* Enable arbiter for all PCI slots.  Also, disable PCI interval
-        * timer so that DTO (Discard TimeOuts) are not reported because
-        * some Schizo revisions report them erroneously.
-        */
        tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL);
-       if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS &&
-           pbm->chip_version == 0x5 &&
-           pbm->chip_revision == 0x1)
-               tmp |= 0x0f;
-       else
-               tmp |= 0xff;
 
-       tmp &= ~SCHIZO_PCICTRL_PTO;
+       /* Enable arbiter for all PCI slots.  */
+       tmp |= 0xff;
+
        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;
 
-       if (!prom_getbool(pbm->prom_node, "no-bus-parking"))
+       prop = of_find_property(pbm->prom_node, "no-bus-parking", NULL);
+       if (!prop)
                tmp |= SCHIZO_PCICTRL_PARK;
+       else
+               tmp &= ~SCHIZO_PCICTRL_PARK;
+
+       if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
+           pbm->chip_version <= 0x1)
+               tmp |= SCHIZO_PCICTRL_DTO_INT;
+       else
+               tmp &= ~SCHIZO_PCICTRL_DTO_INT;
 
        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);
 
@@ -1913,17 +1650,18 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
        }
 }
 
-static void __init schizo_pbm_init(struct pci_controller_info *p,
-                                  int prom_node, u32 portid,
-                                  int chip_type)
+static void schizo_pbm_init(struct pci_controller_info *p,
+                           struct device_node *dp, u32 portid,
+                           int chip_type)
 {
-       struct linux_prom64_registers pr_regs[4];
-       unsigned int busrange[2];
+       struct linux_prom64_registers *regs;
+       struct property *prop;
+       unsigned int *busrange;
        struct pci_pbm_info *pbm;
        const char *chipset_name;
-       u32 ino_bitmap[2];
+       u32 *ino_bitmap;
        int is_pbm_a;
-       int err;
+       int len;
 
        switch (chip_type) {
        case PBM_CHIP_TYPE_TOMATILLO:
@@ -1951,16 +1689,10 @@ static void __init schizo_pbm_init(struct pci_controller_info *p,
         * 3) PBM PCI config space
         * 4) Ichip regs
         */
-       err = prom_getproperty(prom_node, "reg",
-                              (char *)&pr_regs[0],
-                              sizeof(pr_regs));
-       if (err == 0 || err == -1) {
-               prom_printf("%s: Fatal error, no reg property.\n",
-                           chipset_name);
-               prom_halt();
-       }
+       prop = of_find_property(dp, "reg", NULL);
+       regs = prop->value;
 
-       is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000);
+       is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000);
 
        if (is_pbm_a)
                pbm = &p->pbm_A;
@@ -1969,89 +1701,62 @@ static void __init schizo_pbm_init(struct pci_controller_info *p,
 
        pbm->portid = portid;
        pbm->parent = p;
-       pbm->prom_node = prom_node;
+       pbm->prom_node = dp;
        pbm->pci_first_slot = 1;
 
        pbm->chip_type = chip_type;
-       pbm->chip_version =
-               prom_getintdefault(prom_node, "version#", 0);
-       pbm->chip_revision =
-               prom_getintdefault(prom_node, "module-revision#", 0);
-
-       pbm->pbm_regs = pr_regs[0].phys_addr;
-       pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL;
-
-       sprintf(pbm->name,
-               (chip_type == PBM_CHIP_TYPE_TOMATILLO ?
-                "TOMATILLO%d PBM%c" :
-                "SCHIZO%d PBM%c"),
-               p->index,
-               (pbm == &p->pbm_A ? 'A' : 'B'));
-
-       printk("%s: ver[%x:%x], portid %x, "
-              "cregs[%lx] pregs[%lx]\n",
-              pbm->name,
-              pbm->chip_version, pbm->chip_revision,
-              pbm->portid,
-              pbm->controller_regs,
-              pbm->pbm_regs);
+       pbm->chip_version = 0;
+       prop = of_find_property(dp, "version#", NULL);
+       if (prop)
+               pbm->chip_version = *(int *) prop->value;
+       pbm->chip_revision = 0;
+       prop = of_find_property(dp, "module-revision#", NULL);
+       if (prop)
+               pbm->chip_revision = *(int *) prop->value;
+
+       pbm->pbm_regs = regs[0].phys_addr;
+       pbm->controller_regs = regs[1].phys_addr - 0x10000UL;
 
-       schizo_pbm_hw_init(pbm);
+       if (chip_type == PBM_CHIP_TYPE_TOMATILLO)
+               pbm->sync_reg = regs[3].phys_addr + 0x1a18UL;
 
-       prom_getstring(prom_node, "name",
-                      pbm->prom_name,
-                      sizeof(pbm->prom_name));
+       pbm->name = dp->full_name;
 
-       err = prom_getproperty(prom_node, "ranges",
-                              (char *) pbm->pbm_ranges,
-                              sizeof(pbm->pbm_ranges));
-       if (err == 0 || err == -1) {
-               prom_printf("%s: Fatal error, no ranges property.\n",
-                           pbm->name);
-               prom_halt();
-       }
+       printk("%s: %s PCI Bus Module ver[%x:%x]\n",
+              pbm->name,
+              (chip_type == PBM_CHIP_TYPE_TOMATILLO ?
+               "TOMATILLO" : "SCHIZO"),
+              pbm->chip_version, pbm->chip_revision);
+
+       schizo_pbm_hw_init(pbm);
 
+       prop = of_find_property(dp, "ranges", &len);
+       pbm->pbm_ranges = prop->value;
        pbm->num_pbm_ranges =
-               (err / sizeof(struct linux_prom_pci_ranges));
+               (len / sizeof(struct linux_prom_pci_ranges));
 
        schizo_determine_mem_io_space(pbm);
        pbm_register_toplevel_resources(p, pbm);
 
-       err = prom_getproperty(prom_node, "interrupt-map",
-                              (char *)pbm->pbm_intmap,
-                              sizeof(pbm->pbm_intmap));
-       if (err != -1) {
-               pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap));
-               err = prom_getproperty(prom_node, "interrupt-map-mask",
-                                      (char *)&pbm->pbm_intmask,
-                                      sizeof(pbm->pbm_intmask));
-               if (err == -1) {
-                       prom_printf("%s: Fatal error, no "
-                                   "interrupt-map-mask.\n", pbm->name);
-                       prom_halt();
-               }
+       prop = of_find_property(dp, "interrupt-map", &len);
+       if (prop) {
+               pbm->pbm_intmap = prop->value;
+               pbm->num_pbm_intmap =
+                       (len / sizeof(struct linux_prom_pci_intmap));
+
+               prop = of_find_property(dp, "interrupt-map-mask", NULL);
+               pbm->pbm_intmask = prop->value;
        } else {
                pbm->num_pbm_intmap = 0;
-               memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
        }
 
-       err = prom_getproperty(prom_node, "ino-bitmap",
-                              (char *) &ino_bitmap[0],
-                              sizeof(ino_bitmap));
-       if (err == 0 || err == -1) {
-               prom_printf("%s: Fatal error, no ino-bitmap.\n", pbm->name);
-               prom_halt();
-       }
+       prop = of_find_property(dp, "ino-bitmap", NULL);
+       ino_bitmap = prop->value;
        pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) |
                           ((u64)ino_bitmap[0] <<  0UL));
 
-       err = prom_getproperty(prom_node, "bus-range",
-                              (char *)&busrange[0],
-                              sizeof(busrange));
-       if (err == 0 || err == -1) {
-               prom_printf("%s: Fatal error, no bus-range.\n", pbm->name);
-               prom_halt();
-       }
+       prop = of_find_property(dp, "bus-range", NULL);
+       busrange = prop->value;
        pbm->pci_first_busno = busrange[0];
        pbm->pci_last_busno = busrange[1];
 
@@ -2069,18 +1774,20 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
        return (x == y);
 }
 
-static void __init __schizo_init(int node, char *model_name, int chip_type)
+static void __schizo_init(struct device_node *dp, char *model_name, int chip_type)
 {
        struct pci_controller_info *p;
        struct pci_iommu *iommu;
-       unsigned long flags;
+       struct property *prop;
        int is_pbm_a;
        u32 portid;
 
-       portid = prom_getintdefault(node, "portid", 0xff);
+       portid = 0xff;
+       prop = of_find_property(dp, "portid", NULL);
+       if (prop)
+               portid = *(u32 *) prop->value;
 
-       spin_lock_irqsave(&pci_controller_lock, flags);
-       for(p = pci_controller_root; p; p = p->next) {
+       for (p = pci_controller_root; p; p = p->next) {
                struct pci_pbm_info *pbm;
 
                if (p->pbm_A.prom_node && p->pbm_B.prom_node)
@@ -2091,48 +1798,40 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
                       &p->pbm_B);
 
                if (portid_compare(pbm->portid, portid, chip_type)) {
-                       spin_unlock_irqrestore(&pci_controller_lock, flags);
-                       is_pbm_a = (p->pbm_A.prom_node == 0);
-                       schizo_pbm_init(p, node, portid, chip_type);
+                       is_pbm_a = (p->pbm_A.prom_node == NULL);
+                       schizo_pbm_init(p, dp, portid, chip_type);
                        return;
                }
        }
-       spin_unlock_irqrestore(&pci_controller_lock, flags);
 
-       p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
+       p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
        if (!p) {
                prom_printf("SCHIZO: Fatal memory allocation error.\n");
                prom_halt();
        }
-       memset(p, 0, sizeof(*p));
 
-       iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
+       iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
        if (!iommu) {
                prom_printf("SCHIZO: Fatal memory allocation error.\n");
                prom_halt();
        }
-       memset(iommu, 0, sizeof(*iommu));
        p->pbm_A.iommu = iommu;
 
-       iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
+       iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
        if (!iommu) {
                prom_printf("SCHIZO: Fatal memory allocation error.\n");
                prom_halt();
        }
-       memset(iommu, 0, sizeof(*iommu));
        p->pbm_B.iommu = iommu;
 
-       spin_lock_irqsave(&pci_controller_lock, flags);
        p->next = pci_controller_root;
        pci_controller_root = p;
-       spin_unlock_irqrestore(&pci_controller_lock, flags);
 
        p->index = pci_num_controllers++;
        p->pbms_same_domain = 0;
        p->scan_bus = (chip_type == PBM_CHIP_TYPE_TOMATILLO ?
                       tomatillo_scan_bus :
                       schizo_scan_bus);
-       p->irq_build = schizo_irq_build;
        p->base_address_update = schizo_base_address_update;
        p->resource_adjust = schizo_resource_adjust;
        p->pci_ops = &schizo_ops;
@@ -2140,20 +1839,20 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
        /* Like PSYCHO we have a 2GB aligned area for memory space. */
        pci_memspace_mask = 0x7fffffffUL;
 
-       schizo_pbm_init(p, node, portid, chip_type);
+       schizo_pbm_init(p, dp, portid, chip_type);
 }
 
-void __init schizo_init(int node, char *model_name)
+void schizo_init(struct device_node *dp, char *model_name)
 {
-       __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO);
+       __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO);
 }
 
-void __init schizo_plus_init(int node, char *model_name)
+void schizo_plus_init(struct device_node *dp, char *model_name)
 {
-       __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
+       __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
 }
 
-void __init tomatillo_init(int node, char *model_name)
+void tomatillo_init(struct device_node *dp, char *model_name)
 {
-       __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO);
+       __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO);
 }