fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / sparc64 / kernel / pci_psycho.c
index 40030bc..fda5db2 100644 (file)
@@ -17,6 +17,8 @@
 #include <asm/iommu.h>
 #include <asm/irq.h>
 #include <asm/starfire.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 
 #include "pci_impl.h"
 #include "iommu_common.h"
 
 /* Misc. PSYCHO PCI controller register offsets and definitions. */
 #define PSYCHO_CONTROL         0x0010UL
-#define  PSYCHO_CONTROL_IMPL    0xf000000000000000 /* Implementation of this PSYCHO*/
-#define  PSYCHO_CONTROL_VER     0x0f00000000000000 /* Version of this PSYCHO       */
-#define  PSYCHO_CONTROL_MID     0x00f8000000000000 /* UPA Module ID of PSYCHO      */
-#define  PSYCHO_CONTROL_IGN     0x0007c00000000000 /* Interrupt Group Number       */
-#define  PSYCHO_CONTROL_RESV     0x00003ffffffffff0 /* Reserved                     */
-#define  PSYCHO_CONTROL_APCKEN  0x0000000000000008 /* Address Parity Check Enable  */
-#define  PSYCHO_CONTROL_APERR   0x0000000000000004 /* Incoming System Addr Parerr  */
-#define  PSYCHO_CONTROL_IAP     0x0000000000000002 /* Invert UPA Parity            */
-#define  PSYCHO_CONTROL_MODE    0x0000000000000001 /* PSYCHO clock mode            */
+#define  PSYCHO_CONTROL_IMPL    0xf000000000000000UL /* Implementation of this PSYCHO*/
+#define  PSYCHO_CONTROL_VER     0x0f00000000000000UL /* Version of this PSYCHO       */
+#define  PSYCHO_CONTROL_MID     0x00f8000000000000UL /* UPA Module ID of PSYCHO      */
+#define  PSYCHO_CONTROL_IGN     0x0007c00000000000UL /* Interrupt Group Number       */
+#define  PSYCHO_CONTROL_RESV     0x00003ffffffffff0UL /* Reserved                     */
+#define  PSYCHO_CONTROL_APCKEN  0x0000000000000008UL /* Address Parity Check Enable  */
+#define  PSYCHO_CONTROL_APERR   0x0000000000000004UL /* Incoming System Addr Parerr  */
+#define  PSYCHO_CONTROL_IAP     0x0000000000000002UL /* Invert UPA Parity            */
+#define  PSYCHO_CONTROL_MODE    0x0000000000000001UL /* PSYCHO clock mode            */
 #define PSYCHO_PCIA_CTRL       0x2000UL
 #define PSYCHO_PCIB_CTRL       0x4000UL
-#define  PSYCHO_PCICTRL_RESV1   0xfffffff000000000 /* Reserved                     */
-#define  PSYCHO_PCICTRL_SBH_ERR         0x0000000800000000 /* Streaming byte hole error    */
-#define  PSYCHO_PCICTRL_SERR    0x0000000400000000 /* SERR signal asserted         */
-#define  PSYCHO_PCICTRL_SPEED   0x0000000200000000 /* PCI speed (1 is U2P clock)   */
-#define  PSYCHO_PCICTRL_RESV2   0x00000001ffc00000 /* Reserved                     */
-#define  PSYCHO_PCICTRL_ARB_PARK 0x0000000000200000 /* PCI arbitration parking      */
-#define  PSYCHO_PCICTRL_RESV3   0x00000000001ff800 /* Reserved                     */
-#define  PSYCHO_PCICTRL_SBH_INT         0x0000000000000400 /* Streaming byte hole int enab */
-#define  PSYCHO_PCICTRL_WEN     0x0000000000000200 /* Power Mgmt Wake Enable       */
-#define  PSYCHO_PCICTRL_EEN     0x0000000000000100 /* PCI Error Interrupt Enable   */
-#define  PSYCHO_PCICTRL_RESV4   0x00000000000000c0 /* Reserved                     */
-#define  PSYCHO_PCICTRL_AEN     0x000000000000003f /* PCI DVMA Arbitration Enable  */
+#define  PSYCHO_PCICTRL_RESV1   0xfffffff000000000UL /* Reserved                     */
+#define  PSYCHO_PCICTRL_SBH_ERR         0x0000000800000000UL /* Streaming byte hole error    */
+#define  PSYCHO_PCICTRL_SERR    0x0000000400000000UL /* SERR signal asserted         */
+#define  PSYCHO_PCICTRL_SPEED   0x0000000200000000UL /* PCI speed (1 is U2P clock)   */
+#define  PSYCHO_PCICTRL_RESV2   0x00000001ffc00000UL /* Reserved                     */
+#define  PSYCHO_PCICTRL_ARB_PARK 0x0000000000200000UL /* PCI arbitration parking      */
+#define  PSYCHO_PCICTRL_RESV3   0x00000000001ff800UL /* Reserved                     */
+#define  PSYCHO_PCICTRL_SBH_INT         0x0000000000000400UL /* Streaming byte hole int enab */
+#define  PSYCHO_PCICTRL_WEN     0x0000000000000200UL /* Power Mgmt Wake Enable       */
+#define  PSYCHO_PCICTRL_EEN     0x0000000000000100UL /* PCI Error Interrupt Enable   */
+#define  PSYCHO_PCICTRL_RESV4   0x00000000000000c0UL /* Reserved                     */
+#define  PSYCHO_PCICTRL_AEN     0x000000000000003fUL /* PCI DVMA Arbitration Enable  */
 
 /* U2P Programmer's Manual, page 13-55, configuration space
  * address format:
@@ -207,187 +209,6 @@ static struct pci_ops psycho_ops = {
        .write =        psycho_write_pci_cfg,
 };
 
-/* PSYCHO interrupt mapping support. */
-#define PSYCHO_IMAP_A_SLOT0    0x0c00UL
-#define PSYCHO_IMAP_B_SLOT0    0x0c20UL
-static unsigned long psycho_pcislot_imap_offset(unsigned long ino)
-{
-       unsigned int bus =  (ino & 0x10) >> 4;
-       unsigned int slot = (ino & 0x0c) >> 2;
-
-       if (bus == 0)
-               return PSYCHO_IMAP_A_SLOT0 + (slot * 8);
-       else
-               return PSYCHO_IMAP_B_SLOT0 + (slot * 8);
-}
-
-#define PSYCHO_IMAP_SCSI       0x1000UL
-#define PSYCHO_IMAP_ETH                0x1008UL
-#define PSYCHO_IMAP_BPP                0x1010UL
-#define PSYCHO_IMAP_AU_REC     0x1018UL
-#define PSYCHO_IMAP_AU_PLAY    0x1020UL
-#define PSYCHO_IMAP_PFAIL      0x1028UL
-#define PSYCHO_IMAP_KMS                0x1030UL
-#define PSYCHO_IMAP_FLPY       0x1038UL
-#define PSYCHO_IMAP_SHW                0x1040UL
-#define PSYCHO_IMAP_KBD                0x1048UL
-#define PSYCHO_IMAP_MS         0x1050UL
-#define PSYCHO_IMAP_SER                0x1058UL
-#define PSYCHO_IMAP_TIM0       0x1060UL
-#define PSYCHO_IMAP_TIM1       0x1068UL
-#define PSYCHO_IMAP_UE         0x1070UL
-#define PSYCHO_IMAP_CE         0x1078UL
-#define PSYCHO_IMAP_A_ERR      0x1080UL
-#define PSYCHO_IMAP_B_ERR      0x1088UL
-#define PSYCHO_IMAP_PMGMT      0x1090UL
-#define PSYCHO_IMAP_GFX                0x1098UL
-#define PSYCHO_IMAP_EUPA       0x10a0UL
-
-static unsigned long __onboard_imap_off[] = {
-/*0x20*/       PSYCHO_IMAP_SCSI,
-/*0x21*/       PSYCHO_IMAP_ETH,
-/*0x22*/       PSYCHO_IMAP_BPP,
-/*0x23*/       PSYCHO_IMAP_AU_REC,
-/*0x24*/       PSYCHO_IMAP_AU_PLAY,
-/*0x25*/       PSYCHO_IMAP_PFAIL,
-/*0x26*/       PSYCHO_IMAP_KMS,
-/*0x27*/       PSYCHO_IMAP_FLPY,
-/*0x28*/       PSYCHO_IMAP_SHW,
-/*0x29*/       PSYCHO_IMAP_KBD,
-/*0x2a*/       PSYCHO_IMAP_MS,
-/*0x2b*/       PSYCHO_IMAP_SER,
-/*0x2c*/       PSYCHO_IMAP_TIM0,
-/*0x2d*/       PSYCHO_IMAP_TIM1,
-/*0x2e*/       PSYCHO_IMAP_UE,
-/*0x2f*/       PSYCHO_IMAP_CE,
-/*0x30*/       PSYCHO_IMAP_A_ERR,
-/*0x31*/       PSYCHO_IMAP_B_ERR,
-/*0x32*/       PSYCHO_IMAP_PMGMT
-};
-#define PSYCHO_ONBOARD_IRQ_BASE                0x20
-#define PSYCHO_ONBOARD_IRQ_LAST                0x32
-#define psycho_onboard_imap_offset(__ino) \
-       __onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
-
-#define PSYCHO_ICLR_A_SLOT0    0x1400UL
-#define PSYCHO_ICLR_SCSI       0x1800UL
-
-#define psycho_iclr_offset(ino)                                              \
-       ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
-                       (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
-
-/* PCI PSYCHO INO number to Sparc PIL level. */
-static unsigned char psycho_pil_table[] = {
-/*0x00*/0, 0, 0, 0,    /* PCI A slot 0  Int A, B, C, D */
-/*0x04*/0, 0, 0, 0,    /* PCI A slot 1  Int A, B, C, D */
-/*0x08*/0, 0, 0, 0,    /* PCI A slot 2  Int A, B, C, D */
-/*0x0c*/0, 0, 0, 0,    /* PCI A slot 3  Int A, B, C, D */
-/*0x10*/0, 0, 0, 0,    /* PCI B slot 0  Int A, B, C, D */
-/*0x14*/0, 0, 0, 0,    /* PCI B slot 1  Int A, B, C, D */
-/*0x18*/0, 0, 0, 0,    /* PCI B slot 2  Int A, B, C, D */
-/*0x1c*/0, 0, 0, 0,    /* PCI B slot 3  Int A, B, C, D */
-/*0x20*/4,             /* SCSI                         */
-/*0x21*/5,             /* Ethernet                     */
-/*0x22*/8,             /* Parallel Port                */
-/*0x23*/13,            /* Audio Record                 */
-/*0x24*/14,            /* Audio Playback               */
-/*0x25*/15,            /* PowerFail                    */
-/*0x26*/4,             /* second SCSI                  */
-/*0x27*/11,            /* Floppy                       */
-/*0x28*/4,             /* Spare Hardware               */
-/*0x29*/9,             /* Keyboard                     */
-/*0x2a*/4,             /* Mouse                        */
-/*0x2b*/12,            /* Serial                       */
-/*0x2c*/10,            /* Timer 0                      */
-/*0x2d*/11,            /* Timer 1                      */
-/*0x2e*/15,            /* Uncorrectable ECC            */
-/*0x2f*/15,            /* Correctable ECC              */
-/*0x30*/15,            /* PCI Bus A Error              */
-/*0x31*/15,            /* PCI Bus B Error              */
-/*0x32*/15,            /* Power Management             */
-};
-
-static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
-{
-       int ret;
-
-       ret = psycho_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 psycho_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, inofixup = 0;
-
-       ino &= PCI_IRQ_INO;
-       if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
-               /* PCI slot */
-               imap_off = psycho_pcislot_imap_offset(ino);
-       } else {
-               /* Onboard device */
-               if (ino > PSYCHO_ONBOARD_IRQ_LAST) {
-                       prom_printf("psycho_irq_build: Wacky INO [%x]\n", ino);
-                       prom_halt();
-               }
-               imap_off = psycho_onboard_imap_offset(ino);
-       }
-
-       /* Now build the IRQ bucket. */
-       pil = psycho_ino_to_pil(pdev, ino);
-
-       if (PIL_RESERVED(pil))
-               BUG();
-
-       imap = pbm->controller_regs + imap_off;
-       imap += 4;
-
-       iclr_off = psycho_iclr_offset(ino);
-       iclr = pbm->controller_regs + iclr_off;
-       iclr += 4;
-
-       if ((ino & 0x20) == 0)
-               inofixup = ino & 0x03;
-
-       bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
-       bucket->flags |= IBF_PCI;
-
-       return __irq(bucket);
-}
-
 /* PSYCHO error handling support. */
 enum psycho_error_type {
        UE_ERR, CE_ERR, PCI_ERR
@@ -403,11 +224,11 @@ enum psycho_error_type {
  */
 #define PSYCHO_STRBUF_CONTROL_A 0x2800UL
 #define PSYCHO_STRBUF_CONTROL_B 0x4800UL
-#define  PSYCHO_STRBUF_CTRL_LPTR    0x00000000000000f0 /* LRU Lock Pointer */
-#define  PSYCHO_STRBUF_CTRL_LENAB   0x0000000000000008 /* LRU Lock Enable */
-#define  PSYCHO_STRBUF_CTRL_RRDIS   0x0000000000000004 /* Rerun Disable */
-#define  PSYCHO_STRBUF_CTRL_DENAB   0x0000000000000002 /* Diagnostic Mode Enable */
-#define  PSYCHO_STRBUF_CTRL_ENAB    0x0000000000000001 /* Streaming Buffer Enable */
+#define  PSYCHO_STRBUF_CTRL_LPTR    0x00000000000000f0UL /* LRU Lock Pointer */
+#define  PSYCHO_STRBUF_CTRL_LENAB   0x0000000000000008UL /* LRU Lock Enable */
+#define  PSYCHO_STRBUF_CTRL_RRDIS   0x0000000000000004UL /* Rerun Disable */
+#define  PSYCHO_STRBUF_CTRL_DENAB   0x0000000000000002UL /* Diagnostic Mode Enable */
+#define  PSYCHO_STRBUF_CTRL_ENAB    0x0000000000000001UL /* Streaming Buffer Enable */
 #define PSYCHO_STRBUF_FLUSH_A   0x2808UL
 #define PSYCHO_STRBUF_FLUSH_B   0x4808UL
 #define PSYCHO_STRBUF_FSYNC_A   0x2810UL
@@ -416,24 +237,24 @@ enum psycho_error_type {
 #define PSYCHO_STC_DATA_B      0xc000UL
 #define PSYCHO_STC_ERR_A       0xb400UL
 #define PSYCHO_STC_ERR_B       0xc400UL
-#define  PSYCHO_STCERR_WRITE    0x0000000000000002     /* Write Error */
-#define  PSYCHO_STCERR_READ     0x0000000000000001     /* Read Error */
+#define  PSYCHO_STCERR_WRITE    0x0000000000000002UL   /* Write Error */
+#define  PSYCHO_STCERR_READ     0x0000000000000001UL   /* Read Error */
 #define PSYCHO_STC_TAG_A       0xb800UL
 #define PSYCHO_STC_TAG_B       0xc800UL
-#define  PSYCHO_STCTAG_PPN      0x0fffffff00000000     /* Physical Page Number */
-#define  PSYCHO_STCTAG_VPN      0x00000000ffffe000     /* Virtual Page Number */
-#define  PSYCHO_STCTAG_VALID    0x0000000000000002     /* Valid */
-#define  PSYCHO_STCTAG_WRITE    0x0000000000000001     /* Writable */
+#define  PSYCHO_STCTAG_PPN      0x0fffffff00000000UL   /* Physical Page Number */
+#define  PSYCHO_STCTAG_VPN      0x00000000ffffe000UL   /* Virtual Page Number */
+#define  PSYCHO_STCTAG_VALID    0x0000000000000002UL   /* Valid */
+#define  PSYCHO_STCTAG_WRITE    0x0000000000000001UL   /* Writable */
 #define PSYCHO_STC_LINE_A      0xb900UL
 #define PSYCHO_STC_LINE_B      0xc900UL
-#define  PSYCHO_STCLINE_LINDX   0x0000000001e00000     /* LRU Index */
-#define  PSYCHO_STCLINE_SPTR    0x00000000001f8000     /* Dirty Data Start Pointer */
-#define  PSYCHO_STCLINE_LADDR   0x0000000000007f00     /* Line Address */
-#define  PSYCHO_STCLINE_EPTR    0x00000000000000fc     /* Dirty Data End Pointer */
-#define  PSYCHO_STCLINE_VALID   0x0000000000000002     /* Valid */
-#define  PSYCHO_STCLINE_FOFN    0x0000000000000001     /* Fetch Outstanding / Flush Necessary */
-
-static spinlock_t stc_buf_lock = SPIN_LOCK_UNLOCKED;
+#define  PSYCHO_STCLINE_LINDX   0x0000000001e00000UL   /* LRU Index */
+#define  PSYCHO_STCLINE_SPTR    0x00000000001f8000UL   /* Dirty Data Start Pointer */
+#define  PSYCHO_STCLINE_LADDR   0x0000000000007f00UL   /* Line Address */
+#define  PSYCHO_STCLINE_EPTR    0x00000000000000fcUL   /* Dirty Data End Pointer */
+#define  PSYCHO_STCLINE_VALID   0x0000000000000002UL   /* Valid */
+#define  PSYCHO_STCLINE_FOFN    0x0000000000000001UL   /* Fetch Outstanding / Flush Necessary */
+
+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];
@@ -453,9 +274,9 @@ static void __psycho_check_one_stc(struct pci_controller_info *p,
                tag_base = regbase + PSYCHO_STC_TAG_A;
                line_base = regbase + PSYCHO_STC_LINE_A;
        } else {
-               err_base = regbase + PSYCHO_STC_ERR_A;
-               tag_base = regbase + PSYCHO_STC_TAG_A;
-               line_base = regbase + PSYCHO_STC_LINE_A;
+               err_base = regbase + PSYCHO_STC_ERR_B;
+               tag_base = regbase + PSYCHO_STC_TAG_B;
+               line_base = regbase + PSYCHO_STC_LINE_B;
        }
 
        spin_lock(&stc_buf_lock);
@@ -555,24 +376,24 @@ static void __psycho_check_stc_error(struct pci_controller_info *p,
  * interrogate the IOMMU state to see if it is the cause.
  */
 #define PSYCHO_IOMMU_CONTROL   0x0200UL
-#define  PSYCHO_IOMMU_CTRL_RESV     0xfffffffff9000000 /* Reserved                      */
-#define  PSYCHO_IOMMU_CTRL_XLTESTAT 0x0000000006000000 /* Translation Error Status      */
-#define  PSYCHO_IOMMU_CTRL_XLTEERR  0x0000000001000000 /* Translation Error encountered */
-#define  PSYCHO_IOMMU_CTRL_LCKEN    0x0000000000800000 /* Enable translation locking    */
-#define  PSYCHO_IOMMU_CTRL_LCKPTR   0x0000000000780000 /* Translation lock pointer      */
-#define  PSYCHO_IOMMU_CTRL_TSBSZ    0x0000000000070000 /* TSB Size                      */
-#define  PSYCHO_IOMMU_TSBSZ_1K      0x0000000000000000 /* TSB Table 1024 8-byte entries */
-#define  PSYCHO_IOMMU_TSBSZ_2K      0x0000000000010000 /* TSB Table 2048 8-byte entries */
-#define  PSYCHO_IOMMU_TSBSZ_4K      0x0000000000020000 /* TSB Table 4096 8-byte entries */
-#define  PSYCHO_IOMMU_TSBSZ_8K      0x0000000000030000 /* TSB Table 8192 8-byte entries */
-#define  PSYCHO_IOMMU_TSBSZ_16K     0x0000000000040000 /* TSB Table 16k 8-byte entries  */
-#define  PSYCHO_IOMMU_TSBSZ_32K     0x0000000000050000 /* TSB Table 32k 8-byte entries  */
-#define  PSYCHO_IOMMU_TSBSZ_64K     0x0000000000060000 /* TSB Table 64k 8-byte entries  */
-#define  PSYCHO_IOMMU_TSBSZ_128K    0x0000000000070000 /* TSB Table 128k 8-byte entries */
-#define  PSYCHO_IOMMU_CTRL_RESV2    0x000000000000fff8 /* Reserved                      */
-#define  PSYCHO_IOMMU_CTRL_TBWSZ    0x0000000000000004 /* Assumed page size, 0=8k 1=64k */
-#define  PSYCHO_IOMMU_CTRL_DENAB    0x0000000000000002 /* Diagnostic mode enable        */
-#define  PSYCHO_IOMMU_CTRL_ENAB     0x0000000000000001 /* IOMMU Enable                  */
+#define  PSYCHO_IOMMU_CTRL_RESV     0xfffffffff9000000UL /* Reserved                      */
+#define  PSYCHO_IOMMU_CTRL_XLTESTAT 0x0000000006000000UL /* Translation Error Status      */
+#define  PSYCHO_IOMMU_CTRL_XLTEERR  0x0000000001000000UL /* Translation Error encountered */
+#define  PSYCHO_IOMMU_CTRL_LCKEN    0x0000000000800000UL /* Enable translation locking    */
+#define  PSYCHO_IOMMU_CTRL_LCKPTR   0x0000000000780000UL /* Translation lock pointer      */
+#define  PSYCHO_IOMMU_CTRL_TSBSZ    0x0000000000070000UL /* TSB Size                      */
+#define  PSYCHO_IOMMU_TSBSZ_1K      0x0000000000000000UL /* TSB Table 1024 8-byte entries */
+#define  PSYCHO_IOMMU_TSBSZ_2K      0x0000000000010000UL /* TSB Table 2048 8-byte entries */
+#define  PSYCHO_IOMMU_TSBSZ_4K      0x0000000000020000UL /* TSB Table 4096 8-byte entries */
+#define  PSYCHO_IOMMU_TSBSZ_8K      0x0000000000030000UL /* TSB Table 8192 8-byte entries */
+#define  PSYCHO_IOMMU_TSBSZ_16K     0x0000000000040000UL /* TSB Table 16k 8-byte entries  */
+#define  PSYCHO_IOMMU_TSBSZ_32K     0x0000000000050000UL /* TSB Table 32k 8-byte entries  */
+#define  PSYCHO_IOMMU_TSBSZ_64K     0x0000000000060000UL /* TSB Table 64k 8-byte entries  */
+#define  PSYCHO_IOMMU_TSBSZ_128K    0x0000000000070000UL /* TSB Table 128k 8-byte entries */
+#define  PSYCHO_IOMMU_CTRL_RESV2    0x000000000000fff8UL /* Reserved                      */
+#define  PSYCHO_IOMMU_CTRL_TBWSZ    0x0000000000000004UL /* Assumed page size, 0=8k 1=64k */
+#define  PSYCHO_IOMMU_CTRL_DENAB    0x0000000000000002UL /* Diagnostic mode enable        */
+#define  PSYCHO_IOMMU_CTRL_ENAB     0x0000000000000001UL /* IOMMU Enable                  */
 #define PSYCHO_IOMMU_TSBBASE   0x0208UL
 #define PSYCHO_IOMMU_FLUSH     0x0210UL
 #define PSYCHO_IOMMU_TAG       0xa580UL
@@ -698,21 +519,21 @@ static void psycho_check_iommu_error(struct pci_controller_info *p,
  * relating to UPA interface transactions.
  */
 #define PSYCHO_UE_AFSR 0x0030UL
-#define  PSYCHO_UEAFSR_PPIO    0x8000000000000000 /* Primary PIO is cause         */
-#define  PSYCHO_UEAFSR_PDRD    0x4000000000000000 /* Primary DVMA read is cause   */
-#define  PSYCHO_UEAFSR_PDWR    0x2000000000000000 /* Primary DVMA write is cause  */
-#define  PSYCHO_UEAFSR_SPIO    0x1000000000000000 /* Secondary PIO is cause       */
-#define  PSYCHO_UEAFSR_SDRD    0x0800000000000000 /* Secondary DVMA read is cause */
-#define  PSYCHO_UEAFSR_SDWR    0x0400000000000000 /* Secondary DVMA write is cause*/
-#define  PSYCHO_UEAFSR_RESV1   0x03ff000000000000 /* Reserved                     */
-#define  PSYCHO_UEAFSR_BMSK    0x0000ffff00000000 /* Bytemask of failed transfer  */
-#define  PSYCHO_UEAFSR_DOFF    0x00000000e0000000 /* Doubleword Offset            */
-#define  PSYCHO_UEAFSR_MID     0x000000001f000000 /* UPA MID causing the fault    */
-#define  PSYCHO_UEAFSR_BLK     0x0000000000800000 /* Trans was block operation    */
-#define  PSYCHO_UEAFSR_RESV2   0x00000000007fffff /* Reserved                     */
+#define  PSYCHO_UEAFSR_PPIO    0x8000000000000000UL /* Primary PIO is cause         */
+#define  PSYCHO_UEAFSR_PDRD    0x4000000000000000UL /* Primary DVMA read is cause   */
+#define  PSYCHO_UEAFSR_PDWR    0x2000000000000000UL /* Primary DVMA write is cause  */
+#define  PSYCHO_UEAFSR_SPIO    0x1000000000000000UL /* Secondary PIO is cause       */
+#define  PSYCHO_UEAFSR_SDRD    0x0800000000000000UL /* Secondary DVMA read is cause */
+#define  PSYCHO_UEAFSR_SDWR    0x0400000000000000UL /* Secondary DVMA write is cause*/
+#define  PSYCHO_UEAFSR_RESV1   0x03ff000000000000UL /* Reserved                     */
+#define  PSYCHO_UEAFSR_BMSK    0x0000ffff00000000UL /* Bytemask of failed transfer  */
+#define  PSYCHO_UEAFSR_DOFF    0x00000000e0000000UL /* Doubleword Offset            */
+#define  PSYCHO_UEAFSR_MID     0x000000001f000000UL /* UPA MID causing the fault    */
+#define  PSYCHO_UEAFSR_BLK     0x0000000000800000UL /* Trans was block operation    */
+#define  PSYCHO_UEAFSR_RESV2   0x00000000007fffffUL /* Reserved                     */
 #define PSYCHO_UE_AFAR 0x0038UL
 
-static irqreturn_t psycho_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t psycho_ue_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFSR;
@@ -774,22 +595,22 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
 
 /* Correctable Errors. */
 #define PSYCHO_CE_AFSR 0x0040UL
-#define  PSYCHO_CEAFSR_PPIO    0x8000000000000000 /* Primary PIO is cause         */
-#define  PSYCHO_CEAFSR_PDRD    0x4000000000000000 /* Primary DVMA read is cause   */
-#define  PSYCHO_CEAFSR_PDWR    0x2000000000000000 /* Primary DVMA write is cause  */
-#define  PSYCHO_CEAFSR_SPIO    0x1000000000000000 /* Secondary PIO is cause       */
-#define  PSYCHO_CEAFSR_SDRD    0x0800000000000000 /* Secondary DVMA read is cause */
-#define  PSYCHO_CEAFSR_SDWR    0x0400000000000000 /* Secondary DVMA write is cause*/
-#define  PSYCHO_CEAFSR_RESV1   0x0300000000000000 /* Reserved                     */
-#define  PSYCHO_CEAFSR_ESYND   0x00ff000000000000 /* Syndrome Bits                */
-#define  PSYCHO_CEAFSR_BMSK    0x0000ffff00000000 /* Bytemask of failed transfer  */
-#define  PSYCHO_CEAFSR_DOFF    0x00000000e0000000 /* Double Offset                */
-#define  PSYCHO_CEAFSR_MID     0x000000001f000000 /* UPA MID causing the fault    */
-#define  PSYCHO_CEAFSR_BLK     0x0000000000800000 /* Trans was block operation    */
-#define  PSYCHO_CEAFSR_RESV2   0x00000000007fffff /* Reserved                     */
+#define  PSYCHO_CEAFSR_PPIO    0x8000000000000000UL /* Primary PIO is cause         */
+#define  PSYCHO_CEAFSR_PDRD    0x4000000000000000UL /* Primary DVMA read is cause   */
+#define  PSYCHO_CEAFSR_PDWR    0x2000000000000000UL /* Primary DVMA write is cause  */
+#define  PSYCHO_CEAFSR_SPIO    0x1000000000000000UL /* Secondary PIO is cause       */
+#define  PSYCHO_CEAFSR_SDRD    0x0800000000000000UL /* Secondary DVMA read is cause */
+#define  PSYCHO_CEAFSR_SDWR    0x0400000000000000UL /* Secondary DVMA write is cause*/
+#define  PSYCHO_CEAFSR_RESV1   0x0300000000000000UL /* Reserved                     */
+#define  PSYCHO_CEAFSR_ESYND   0x00ff000000000000UL /* Syndrome Bits                */
+#define  PSYCHO_CEAFSR_BMSK    0x0000ffff00000000UL /* Bytemask of failed transfer  */
+#define  PSYCHO_CEAFSR_DOFF    0x00000000e0000000UL /* Double Offset                */
+#define  PSYCHO_CEAFSR_MID     0x000000001f000000UL /* UPA MID causing the fault    */
+#define  PSYCHO_CEAFSR_BLK     0x0000000000800000UL /* Trans was block operation    */
+#define  PSYCHO_CEAFSR_RESV2   0x00000000007fffffUL /* Reserved                     */
 #define PSYCHO_CE_AFAR 0x0040UL
 
-static irqreturn_t psycho_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t psycho_ce_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFSR;
@@ -857,20 +678,20 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
  */
 #define PSYCHO_PCI_AFSR_A      0x2010UL
 #define PSYCHO_PCI_AFSR_B      0x4010UL
-#define  PSYCHO_PCIAFSR_PMA    0x8000000000000000 /* Primary Master Abort Error   */
-#define  PSYCHO_PCIAFSR_PTA    0x4000000000000000 /* Primary Target Abort Error   */
-#define  PSYCHO_PCIAFSR_PRTRY  0x2000000000000000 /* Primary Excessive Retries    */
-#define  PSYCHO_PCIAFSR_PPERR  0x1000000000000000 /* Primary Parity Error         */
-#define  PSYCHO_PCIAFSR_SMA    0x0800000000000000 /* Secondary Master Abort Error */
-#define  PSYCHO_PCIAFSR_STA    0x0400000000000000 /* Secondary Target Abort Error */
-#define  PSYCHO_PCIAFSR_SRTRY  0x0200000000000000 /* Secondary Excessive Retries  */
-#define  PSYCHO_PCIAFSR_SPERR  0x0100000000000000 /* Secondary Parity Error       */
-#define  PSYCHO_PCIAFSR_RESV1  0x00ff000000000000 /* Reserved                     */
-#define  PSYCHO_PCIAFSR_BMSK   0x0000ffff00000000 /* Bytemask of failed transfer  */
-#define  PSYCHO_PCIAFSR_BLK    0x0000000080000000 /* Trans was block operation    */
-#define  PSYCHO_PCIAFSR_RESV2  0x0000000040000000 /* Reserved                     */
-#define  PSYCHO_PCIAFSR_MID    0x000000003e000000 /* MID causing the error        */
-#define  PSYCHO_PCIAFSR_RESV3  0x0000000001ffffff /* Reserved                     */
+#define  PSYCHO_PCIAFSR_PMA    0x8000000000000000UL /* Primary Master Abort Error   */
+#define  PSYCHO_PCIAFSR_PTA    0x4000000000000000UL /* Primary Target Abort Error   */
+#define  PSYCHO_PCIAFSR_PRTRY  0x2000000000000000UL /* Primary Excessive Retries    */
+#define  PSYCHO_PCIAFSR_PPERR  0x1000000000000000UL /* Primary Parity Error         */
+#define  PSYCHO_PCIAFSR_SMA    0x0800000000000000UL /* Secondary Master Abort Error */
+#define  PSYCHO_PCIAFSR_STA    0x0400000000000000UL /* Secondary Target Abort Error */
+#define  PSYCHO_PCIAFSR_SRTRY  0x0200000000000000UL /* Secondary Excessive Retries  */
+#define  PSYCHO_PCIAFSR_SPERR  0x0100000000000000UL /* Secondary Parity Error       */
+#define  PSYCHO_PCIAFSR_RESV1  0x00ff000000000000UL /* Reserved                     */
+#define  PSYCHO_PCIAFSR_BMSK   0x0000ffff00000000UL /* Bytemask of failed transfer  */
+#define  PSYCHO_PCIAFSR_BLK    0x0000000080000000UL /* Trans was block operation    */
+#define  PSYCHO_PCIAFSR_RESV2  0x0000000040000000UL /* Reserved                     */
+#define  PSYCHO_PCIAFSR_MID    0x000000003e000000UL /* MID causing the error        */
+#define  PSYCHO_PCIAFSR_RESV3  0x0000000001ffffffUL /* Reserved                     */
 #define PSYCHO_PCI_AFAR_A      0x2018UL
 #define PSYCHO_PCI_AFAR_B      0x4018UL
 
@@ -914,7 +735,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
        return ret;
 }
 
-static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
 {
        struct pci_pbm_info *pbm = dev_id;
        struct pci_controller_info *p = pbm->parent;
@@ -1017,54 +838,37 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
 
 /* XXX What about PowerFail/PowerManagement??? -DaveM */
 #define PSYCHO_ECC_CTRL                0x0020
-#define  PSYCHO_ECCCTRL_EE      0x8000000000000000 /* Enable ECC Checking */
-#define  PSYCHO_ECCCTRL_UE      0x4000000000000000 /* Enable UE Interrupts */
-#define  PSYCHO_ECCCTRL_CE      0x2000000000000000 /* Enable CE INterrupts */
-#define PSYCHO_UE_INO          0x2e
-#define PSYCHO_CE_INO          0x2f
-#define PSYCHO_PCIERR_A_INO    0x30
-#define PSYCHO_PCIERR_B_INO    0x31
-static void __init psycho_register_error_handlers(struct pci_controller_info *p)
+#define  PSYCHO_ECCCTRL_EE      0x8000000000000000UL /* Enable ECC Checking */
+#define  PSYCHO_ECCCTRL_UE      0x4000000000000000UL /* Enable UE Interrupts */
+#define  PSYCHO_ECCCTRL_CE      0x2000000000000000UL /* Enable CE INterrupts */
+static void psycho_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
+       struct of_device *op = of_find_device_by_node(pbm->prom_node);
        unsigned long base = p->pbm_A.controller_regs;
-       unsigned int irq, portid = pbm->portid;
        u64 tmp;
 
-       /* Build IRQs and register handlers. */
-       irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_UE_INO);
-       if (request_irq(irq, psycho_ue_intr,
-                       SA_SHIRQ, "PSYCHO UE", p) < 0) {
-               prom_printf("PSYCHO%d: Cannot register UE interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       if (!op)
+               return;
 
-       irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_CE_INO);
-       if (request_irq(irq, psycho_ce_intr,
-                       SA_SHIRQ, "PSYCHO CE", p) < 0) {
-               prom_printf("PSYCHO%d: Cannot register CE interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       /* Psycho interrupt property order is:
+        * 0: PCIERR PBM B INO
+        * 1: UE ERR
+        * 2: CE ERR
+        * 3: POWER FAIL
+        * 4: SPARE HARDWARE
+        * 5: PCIERR PBM A INO
+        */
 
-       pbm = &p->pbm_A;
-       irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO);
-       if (request_irq(irq, psycho_pcierr_intr,
-                       SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_A) < 0) {
-               prom_printf("PSYCHO%d(PBMA): Cannot register PciERR interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       if (op->num_irqs < 6)
+               return;
 
-       pbm = &p->pbm_B;
-       irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO);
-       if (request_irq(irq, psycho_pcierr_intr,
-                       SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_B) < 0) {
-               prom_printf("PSYCHO%d(PBMB): Cannot register PciERR interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED, "PSYCHO UE", p);
+       request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED, "PSYCHO CE", p);
+       request_irq(op->irqs[5], psycho_pcierr_intr, IRQF_SHARED,
+                   "PSYCHO PCIERR-A", &p->pbm_A);
+       request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED,
+                   "PSYCHO PCIERR-B", &p->pbm_B);
 
        /* Enable UE and CE interrupts for controller. */
        psycho_write(base + PSYCHO_ECC_CTRL,
@@ -1076,30 +880,30 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
         * bits for each PBM.
         */
        tmp = psycho_read(base + PSYCHO_PCIA_CTRL);
-       tmp |= (PSYCHO_PCICTRL_SBH_ERR |
-               PSYCHO_PCICTRL_SERR |
-               PSYCHO_PCICTRL_SBH_INT |
+       tmp |= (PSYCHO_PCICTRL_SERR |
+               PSYCHO_PCICTRL_SBH_ERR |
                PSYCHO_PCICTRL_EEN);
+       tmp &= ~(PSYCHO_PCICTRL_SBH_INT);
        psycho_write(base + PSYCHO_PCIA_CTRL, tmp);
                     
        tmp = psycho_read(base + PSYCHO_PCIB_CTRL);
-       tmp |= (PSYCHO_PCICTRL_SBH_ERR |
-               PSYCHO_PCICTRL_SERR |
-               PSYCHO_PCICTRL_SBH_INT |
+       tmp |= (PSYCHO_PCICTRL_SERR |
+               PSYCHO_PCICTRL_SBH_ERR |
                PSYCHO_PCICTRL_EEN);
+       tmp &= ~(PSYCHO_PCICTRL_SBH_INT);
        psycho_write(base + PSYCHO_PCIB_CTRL, tmp);
 }
 
 /* PSYCHO boot time probing and initialization. */
-static void __init psycho_resource_adjust(struct pci_dev *pdev,
-                                         struct resource *res,
-                                         struct resource *root)
+static void psycho_resource_adjust(struct pci_dev *pdev,
+                                  struct resource *res,
+                                  struct resource *root)
 {
        res->start += root->start;
        res->end += root->start;
 }
 
-static void __init psycho_base_address_update(struct pci_dev *pdev, int resource)
+static void psycho_base_address_update(struct pci_dev *pdev, int resource)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
        struct pci_pbm_info *pbm = pcp->pbm;
@@ -1133,7 +937,7 @@ static void __init psycho_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);
 
@@ -1144,7 +948,7 @@ static void __init psycho_base_address_update(struct pci_dev *pdev, int resource
                pci_write_config_dword(pdev, where + 4, 0);
 }
 
-static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+static void pbm_config_busmastering(struct pci_pbm_info *pbm)
 {
        u8 *addr;
 
@@ -1161,10 +965,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("PSYCHO: Critical allocation failure.\n");
@@ -1172,7 +976,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,
@@ -1189,7 +992,7 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
        pci_setup_busmastering(pbm, pbm->pci_bus);
 }
 
-static void __init psycho_scan_bus(struct pci_controller_info *p)
+static void psycho_scan_bus(struct pci_controller_info *p)
 {
        pbm_config_busmastering(&p->pbm_B);
        p->pbm_B.is_66mhz_capable = 0;
@@ -1204,16 +1007,12 @@ static void __init psycho_scan_bus(struct pci_controller_info *p)
        psycho_register_error_handlers(p);
 }
 
-static void __init psycho_iommu_init(struct pci_controller_info *p)
+static void psycho_iommu_init(struct pci_controller_info *p)
 {
        struct pci_iommu *iommu = p->pbm_A.iommu;
-       unsigned long tsbbase, i;
+       unsigned long i;
        u64 control;
 
-       /* Setup initial software IOMMU state. */
-       spin_lock_init(&iommu->lock);
-       iommu->iommu_cur_ctx = 0;
-
        /* Register addresses. */
        iommu->iommu_control  = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL;
        iommu->iommu_tsbbase  = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE;
@@ -1240,32 +1039,10 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
        /* Leave diag mode enabled for full-flushing done
         * in pci_iommu.c
         */
+       pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff);
 
-       /* 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.
-        */
-       tsbbase = __get_free_pages(GFP_KERNEL, get_order(IO_TSB_SIZE));
-       if (!tsbbase) {
-               prom_printf("PSYCHO_IOMMU: Error, gfp(tsb) failed.\n");
-               prom_halt();
-       }
-       iommu->page_table = (iopte_t *)tsbbase;
-       iommu->page_table_sz_bits = 17;
-       iommu->page_table_map_base = 0xc0000000;
-       iommu->dma_addr_mask = 0xffffffff;
-       memset((char *)tsbbase, 0, IO_TSB_SIZE);
-
-       /* 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;
-       }
-
-       psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase));
+       psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE,
+                    __pa(iommu->page_table));
 
        control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL);
        control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
@@ -1273,30 +1050,27 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
        psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control);
 
        /* If necessary, hook us up for starfire IRQ translations. */
-       if(this_is_starfire)
-               p->starfire_cookie = starfire_hookup(p->pbm_A.portid);
-       else
-               p->starfire_cookie = NULL;
+       if (this_is_starfire)
+               starfire_hookup(p->pbm_A.portid);
 }
 
 #define PSYCHO_IRQ_RETRY       0x1a00UL
 #define PSYCHO_PCIA_DIAG       0x2020UL
 #define PSYCHO_PCIB_DIAG       0x4020UL
-#define  PSYCHO_PCIDIAG_RESV    0xffffffffffffff80 /* Reserved                     */
-#define  PSYCHO_PCIDIAG_DRETRY  0x0000000000000040 /* Disable retry limit          */
-#define  PSYCHO_PCIDIAG_DISYNC  0x0000000000000020 /* Disable DMA wr / irq sync    */
-#define  PSYCHO_PCIDIAG_DDWSYNC         0x0000000000000010 /* Disable DMA wr / PIO rd sync */
-#define  PSYCHO_PCIDIAG_IDDPAR  0x0000000000000008 /* Invert DMA data parity       */
-#define  PSYCHO_PCIDIAG_IPDPAR  0x0000000000000004 /* Invert PIO data parity       */
-#define  PSYCHO_PCIDIAG_IPAPAR  0x0000000000000002 /* Invert PIO address parity    */
-#define  PSYCHO_PCIDIAG_LPBACK  0x0000000000000001 /* Enable loopback mode         */
+#define  PSYCHO_PCIDIAG_RESV    0xffffffffffffff80UL /* Reserved                     */
+#define  PSYCHO_PCIDIAG_DRETRY  0x0000000000000040UL /* Disable retry limit          */
+#define  PSYCHO_PCIDIAG_DISYNC  0x0000000000000020UL /* Disable DMA wr / irq sync    */
+#define  PSYCHO_PCIDIAG_DDWSYNC         0x0000000000000010UL /* Disable DMA wr / PIO rd sync */
+#define  PSYCHO_PCIDIAG_IDDPAR  0x0000000000000008UL /* Invert DMA data parity       */
+#define  PSYCHO_PCIDIAG_IPDPAR  0x0000000000000004UL /* Invert PIO data parity       */
+#define  PSYCHO_PCIDIAG_IPAPAR  0x0000000000000002UL /* Invert PIO address parity    */
+#define  PSYCHO_PCIDIAG_LPBACK  0x0000000000000001UL /* Enable loopback mode         */
 
 static void psycho_controller_hwinit(struct pci_controller_info *p)
 {
        u64 tmp;
 
-       /* PROM sets the IRQ retry value too low, increase it. */
-       psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 0xff);
+       psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5);
 
        /* Enable arbiter for all PCI slots. */
        tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL);
@@ -1320,14 +1094,11 @@ static void psycho_controller_hwinit(struct pci_controller_info *p)
        psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp);
 }
 
-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)
 {
        char *name = pbm->name;
 
-       sprintf(name, "PSYCHO%d PBM%c",
-               p->index,
-               (pbm == &p->pbm_A ? 'A' : 'B'));
        pbm->io_space.name = pbm->mem_space.name = name;
 
        request_resource(&ioport_resource, &pbm->io_space);
@@ -1396,11 +1167,12 @@ static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
 #define PSYCHO_MEMSPACE_SIZE   0x07fffffffUL
 
 static void psycho_pbm_init(struct pci_controller_info *p,
-                           int prom_node, int is_pbm_a)
+                           struct device_node *dp, int is_pbm_a)
 {
-       unsigned int busrange[2];
+       unsigned int *busrange;
+       struct property *prop;
        struct pci_pbm_info *pbm;
-       int err;
+       int len;
 
        if (is_pbm_a) {
                pbm = &p->pbm_A;
@@ -1415,57 +1187,53 @@ static void psycho_pbm_init(struct pci_controller_info *p,
        }
 
        pbm->chip_type = PBM_CHIP_TYPE_PSYCHO;
-       pbm->chip_version =
-               prom_getintdefault(prom_node, "version#", 0);
-       pbm->chip_revision =
-               prom_getintdefault(prom_node, "module-revision#", 0);
+       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->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE;
        pbm->io_space.flags = IORESOURCE_IO;
        pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE;
        pbm->mem_space.flags = IORESOURCE_MEM;
-       pbm_register_toplevel_resources(p, pbm);
 
        pbm->parent = p;
-       pbm->prom_node = prom_node;
-       prom_getstring(prom_node, "name",
-                      pbm->prom_name,
-                      sizeof(pbm->prom_name));
-
-       err = prom_getproperty(prom_node, "ranges",
-                              (char *)pbm->pbm_ranges,
-                              sizeof(pbm->pbm_ranges));
-       if (err != -1)
+       pbm->prom_node = dp;
+       pbm->name = dp->full_name;
+
+       pbm_register_toplevel_resources(p, pbm);
+
+       printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
+              pbm->name,
+              pbm->chip_version, pbm->chip_revision);
+
+       prop = of_find_property(dp, "ranges", &len);
+       if (prop) {
+               pbm->pbm_ranges = prop->value;
                pbm->num_pbm_ranges =
-                       (err / sizeof(struct linux_prom_pci_ranges));
-       else
+                       (len / sizeof(struct linux_prom_pci_ranges));
+       } else {
                pbm->num_pbm_ranges = 0;
+       }
 
-       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("PSYCHO-PBM: Fatal error, no "
-                                   "interrupt-map-mask.\n");
-                       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, "bus-range",
-                              (char *)&busrange[0],
-                              sizeof(busrange));
-       if (err == 0 || err == -1) {
-               prom_printf("PSYCHO-PBM: Fatal error, no bus-range.\n");
-               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];
 
@@ -1474,74 +1242,60 @@ static void psycho_pbm_init(struct pci_controller_info *p,
 
 #define PSYCHO_CONFIGSPACE     0x001000000UL
 
-void __init psycho_init(int node, char *model_name)
+void psycho_init(struct device_node *dp, char *model_name)
 {
-       struct linux_prom64_registers pr_regs[3];
+       struct linux_prom64_registers *pr_regs;
        struct pci_controller_info *p;
        struct pci_iommu *iommu;
-       unsigned long flags;
+       struct property *prop;
        u32 upa_portid;
-       int is_pbm_a, err;
+       int is_pbm_a;
 
-       upa_portid = prom_getintdefault(node, "upa-portid", 0xff);
+       upa_portid = 0xff;
+       prop = of_find_property(dp, "upa-portid", NULL);
+       if (prop)
+               upa_portid = *(u32 *) prop->value;
 
-       spin_lock_irqsave(&pci_controller_lock, flags);
        for(p = pci_controller_root; p; p = p->next) {
                if (p->pbm_A.portid == upa_portid) {
-                       spin_unlock_irqrestore(&pci_controller_lock, flags);
-                       is_pbm_a = (p->pbm_A.prom_node == 0);
-                       psycho_pbm_init(p, node, is_pbm_a);
+                       is_pbm_a = (p->pbm_A.prom_node == NULL);
+                       psycho_pbm_init(p, dp, is_pbm_a);
                        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("PSYCHO: 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("PSYCHO: Fatal memory allocation error.\n");
                prom_halt();
        }
-       memset(iommu, 0, sizeof(*iommu));
        p->pbm_A.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->pbm_A.portid = upa_portid;
        p->pbm_B.portid = upa_portid;
        p->index = pci_num_controllers++;
        p->pbms_same_domain = 0;
        p->scan_bus = psycho_scan_bus;
-       p->irq_build = psycho_irq_build;
        p->base_address_update = psycho_base_address_update;
        p->resource_adjust = psycho_resource_adjust;
        p->pci_ops = &psycho_ops;
 
-       err = prom_getproperty(node, "reg",
-                              (char *)&pr_regs[0],
-                              sizeof(pr_regs));
-       if (err == 0 || err == -1) {
-               prom_printf("PSYCHO: Fatal error, no reg property.\n");
-               prom_halt();
-       }
+       prop = of_find_property(dp, "reg", NULL);
+       pr_regs = prop->value;
 
        p->pbm_A.controller_regs = pr_regs[2].phys_addr;
        p->pbm_B.controller_regs = pr_regs[2].phys_addr;
-       printk("PCI: Found PSYCHO, control regs at %016lx\n",
-              p->pbm_A.controller_regs);
 
        p->pbm_A.config_space = p->pbm_B.config_space =
                (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE);
-       printk("PSYCHO: Shared PCI config space at %016lx\n",
-              p->pbm_A.config_space);
 
        /*
         * Psycho's PCI MEM space is mapped to a 2GB aligned area, so
@@ -1554,5 +1308,5 @@ void __init psycho_init(int node, char *model_name)
        psycho_iommu_init(p);
 
        is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000);
-       psycho_pbm_init(p, node, is_pbm_a);
+       psycho_pbm_init(p, dp, is_pbm_a);
 }