linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / sparc64 / kernel / pci_sabre.c
index f04c6d2..da8e136 100644 (file)
@@ -19,7 +19,6 @@
 #include <asm/irq.h>
 #include <asm/smp.h>
 #include <asm/oplib.h>
-#include <asm/prom.h>
 
 #include "pci_impl.h"
 #include "iommu_common.h"
@@ -485,6 +484,191 @@ static struct pci_ops sabre_ops = {
        .write =        sabre_write_pci_cfg,
 };
 
+static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
+{
+       unsigned int bus =  (ino & 0x10) >> 4;
+       unsigned int slot = (ino & 0x0c) >> 2;
+
+       if (bus == 0)
+               return SABRE_IMAP_A_SLOT0 + (slot * 8);
+       else
+               return SABRE_IMAP_B_SLOT0 + (slot * 8);
+}
+
+static unsigned long __onboard_imap_off[] = {
+/*0x20*/       SABRE_IMAP_SCSI,
+/*0x21*/       SABRE_IMAP_ETH,
+/*0x22*/       SABRE_IMAP_BPP,
+/*0x23*/       SABRE_IMAP_AU_REC,
+/*0x24*/       SABRE_IMAP_AU_PLAY,
+/*0x25*/       SABRE_IMAP_PFAIL,
+/*0x26*/       SABRE_IMAP_KMS,
+/*0x27*/       SABRE_IMAP_FLPY,
+/*0x28*/       SABRE_IMAP_SHW,
+/*0x29*/       SABRE_IMAP_KBD,
+/*0x2a*/       SABRE_IMAP_MS,
+/*0x2b*/       SABRE_IMAP_SER,
+/*0x2c*/       0 /* reserved */,
+/*0x2d*/       0 /* reserved */,
+/*0x2e*/       SABRE_IMAP_UE,
+/*0x2f*/       SABRE_IMAP_CE,
+/*0x30*/       SABRE_IMAP_PCIERR,
+};
+#define SABRE_ONBOARD_IRQ_BASE         0x20
+#define SABRE_ONBOARD_IRQ_LAST         0x30
+#define sabre_onboard_imap_offset(__ino) \
+       __onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE]
+
+#define sabre_iclr_offset(ino)                                       \
+       ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
+                       (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
+
+/* PCI SABRE INO number to Sparc PIL level. */
+static unsigned char sabre_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 sabre_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 = sabre_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;
+}
+
+/* When a device lives behind a bridge deeper in the PCI bus topology
+ * than APB, a special sequence must run to make sure all pending DMA
+ * transfers at the time of IRQ delivery are visible in the coherency
+ * domain by the cpu.  This sequence is to perform a read on the far
+ * side of the non-APB bridge, then perform a read of Sabre's DMA
+ * write-sync register.
+ */
+static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2)
+{
+       struct pci_dev *pdev = _arg1;
+       unsigned long sync_reg = (unsigned long) _arg2;
+       u16 _unused;
+
+       pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused);
+       sabre_read(sync_reg);
+}
+
+static unsigned int sabre_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 < SABRE_ONBOARD_IRQ_BASE) {
+               /* PCI slot */
+               imap_off = sabre_pcislot_imap_offset(ino);
+       } else {
+               /* onboard device */
+               if (ino > SABRE_ONBOARD_IRQ_LAST) {
+                       prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino);
+                       prom_halt();
+               }
+               imap_off = sabre_onboard_imap_offset(ino);
+       }
+
+       /* Now build the IRQ bucket. */
+       pil = sabre_ino_to_pil(pdev, ino);
+
+       if (PIL_RESERVED(pil))
+               BUG();
+
+       imap = pbm->controller_regs + imap_off;
+       imap += 4;
+
+       iclr_off = sabre_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;
+
+       if (pdev) {
+               struct pcidev_cookie *pcp = pdev->sysdata;
+
+               if (pdev->bus->number != pcp->pbm->pci_first_busno) {
+                       struct pci_controller_info *p = pcp->pbm->parent;
+                       struct irq_desc *d = bucket->irq_info;
+
+                       d->pre_handler = sabre_wsync_handler;
+                       d->pre_handler_arg1 = pdev;
+                       d->pre_handler_arg2 = (void *)
+                               p->pbm_A.controller_regs + SABRE_WRSYNC;
+               }
+       }
+       return __irq(bucket);
+}
+
 /* SABRE error handling support. */
 static void sabre_check_iommu_error(struct pci_controller_info *p,
                                    unsigned long afsr,
@@ -821,30 +1005,17 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
        return IRQ_HANDLED;
 }
 
+/* XXX What about PowerFail/PowerManagement??? -DaveM */
+#define SABRE_UE_INO           0x2e
+#define SABRE_CE_INO           0x2f
+#define SABRE_PCIERR_INO       0x30
 static void sabre_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
-       struct device_node *dp = pbm->prom_node;
-       struct of_device *op;
        unsigned long base = pbm->controller_regs;
+       unsigned long irq, portid = pbm->portid;
        u64 tmp;
 
-       if (pbm->chip_type == PBM_CHIP_TYPE_SABRE)
-               dp = dp->parent;
-
-       op = of_find_device_by_node(dp);
-       if (!op)
-               return;
-
-       /* Sabre/Hummingbird IRQ property layout is:
-        * 0: PCI ERR
-        * 1: UE ERR
-        * 2: CE ERR
-        * 3: POWER FAIL
-        */
-       if (op->num_irqs < 4)
-               return;
-
        /* We clear the error bits in the appropriate AFSR before
         * registering the handler so that we don't get spurious
         * interrupts.
@@ -853,16 +1024,32 @@ static void sabre_register_error_handlers(struct pci_controller_info *p)
                    (SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
                     SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
                     SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE));
-
-       request_irq(op->irqs[1], sabre_ue_intr, IRQF_SHARED, "SABRE UE", p);
+       irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_UE_INO);
+       if (request_irq(irq, sabre_ue_intr,
+                       SA_SHIRQ, "SABRE UE", p) < 0) {
+               prom_printf("SABRE%d: Cannot register UE interrupt.\n",
+                           p->index);
+               prom_halt();
+       }
 
        sabre_write(base + SABRE_CE_AFSR,
                    (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
                     SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR));
+       irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_CE_INO);
+       if (request_irq(irq, sabre_ce_intr,
+                       SA_SHIRQ, "SABRE CE", p) < 0) {
+               prom_printf("SABRE%d: Cannot register CE interrupt.\n",
+                           p->index);
+               prom_halt();
+       }
 
-       request_irq(op->irqs[2], sabre_ce_intr, IRQF_SHARED, "SABRE CE", p);
-       request_irq(op->irqs[0], sabre_pcierr_intr, IRQF_SHARED,
-                   "SABRE PCIERR", p);
+       irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_PCIERR_INO);
+       if (request_irq(irq, sabre_pcierr_intr,
+                       SA_SHIRQ, "SABRE PCIERR", p) < 0) {
+               prom_printf("SABRE%d: Cannot register PciERR interrupt.\n",
+                           p->index);
+               prom_halt();
+       }
 
        tmp = sabre_read(base + SABRE_PCICTRL);
        tmp |= SABRE_PCICTRL_ERREN;
@@ -980,7 +1167,7 @@ static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
 
 static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
 {
-       struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);
+       struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
 
        if (!cookie) {
                prom_printf("SABRE: Critical allocation failure.\n");
@@ -988,6 +1175,7 @@ static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
        }
 
        /* All we care about is the PBM. */
+       memset(cookie, 0, sizeof(*cookie));
        cookie->pbm = pbm;
 
        return cookie;
@@ -1196,36 +1384,34 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p,
                                            &pbm->mem_space);
 }
 
-static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end)
+static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
 {
        struct pci_pbm_info *pbm;
-       struct device_node *node;
-       struct property *prop;
-       u32 *busrange;
-       int len, simbas_found;
+       char namebuf[128];
+       u32 busrange[2];
+       int node, simbas_found;
 
        simbas_found = 0;
-       node = dp->child;
-       while (node != NULL) {
-               if (strcmp(node->name, "pci"))
-                       goto next_pci;
+       node = prom_getchild(sabre_node);
+       while ((node = prom_searchsiblings(node, "pci")) != 0) {
+               int err;
 
-               prop = of_find_property(node, "model", NULL);
-               if (!prop || strncmp(prop->value, "SUNW,simba", prop->length))
+               err = prom_getproperty(node, "model", namebuf, sizeof(namebuf));
+               if ((err <= 0) || strncmp(namebuf, "SUNW,simba", err))
                        goto next_pci;
 
-               simbas_found++;
+               err = prom_getproperty(node, "bus-range",
+                                      (char *)&busrange[0], sizeof(busrange));
+               if (err == 0 || err == -1) {
+                       prom_printf("APB: Error, cannot get PCI bus-range.\n");
+                       prom_halt();
+               }
 
-               prop = of_find_property(node, "bus-range", NULL);
-               busrange = prop->value;
+               simbas_found++;
                if (busrange[0] == 1)
                        pbm = &p->pbm_B;
                else
                        pbm = &p->pbm_A;
-
-               pbm->name = node->full_name;
-               printk("%s: SABRE PCI Bus Module\n", pbm->name);
-
                pbm->chip_type = PBM_CHIP_TYPE_SABRE;
                pbm->parent = p;
                pbm->prom_node = node;
@@ -1233,70 +1419,83 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
                pbm->pci_first_busno = busrange[0];
                pbm->pci_last_busno = busrange[1];
 
-               prop = of_find_property(node, "ranges", &len);
-               if (prop) {
-                       pbm->pbm_ranges = prop->value;
+               prom_getstring(node, "name", pbm->prom_name, sizeof(pbm->prom_name));
+               err = prom_getproperty(node, "ranges",
+                                      (char *)pbm->pbm_ranges,
+                                      sizeof(pbm->pbm_ranges));
+               if (err != -1)
                        pbm->num_pbm_ranges =
-                               (len / sizeof(struct linux_prom_pci_ranges));
-               } else {
+                               (err / sizeof(struct linux_prom_pci_ranges));
+               else
                        pbm->num_pbm_ranges = 0;
-               }
-
-               prop = of_find_property(node, "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(node, "interrupt-map-mask",
-                                               NULL);
-                       pbm->pbm_intmask = prop->value;
+               err = prom_getproperty(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(node, "interrupt-map-mask",
+                                              (char *)&pbm->pbm_intmask,
+                                              sizeof(pbm->pbm_intmask));
+                       if (err == -1) {
+                               prom_printf("APB: Fatal error, no interrupt-map-mask.\n");
+                               prom_halt();
+                       }
                } else {
                        pbm->num_pbm_intmap = 0;
+                       memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
                }
 
                pbm_register_toplevel_resources(p, pbm);
 
        next_pci:
-               node = node->sibling;
+               node = prom_getsibling(node);
+               if (!node)
+                       break;
        }
        if (simbas_found == 0) {
-               struct resource *rp;
+               int err;
 
                /* No APBs underneath, probably this is a hummingbird
                 * system.
                 */
                pbm = &p->pbm_A;
                pbm->parent = p;
-               pbm->prom_node = dp;
+               pbm->prom_node = sabre_node;
                pbm->pci_first_busno = p->pci_first_busno;
                pbm->pci_last_busno = p->pci_last_busno;
 
-               prop = of_find_property(dp, "ranges", &len);
-               if (prop) {
-                       pbm->pbm_ranges = prop->value;
+               prom_getstring(sabre_node, "name", pbm->prom_name, sizeof(pbm->prom_name));
+               err = prom_getproperty(sabre_node, "ranges",
+                                      (char *) pbm->pbm_ranges,
+                                      sizeof(pbm->pbm_ranges));
+               if (err != -1)
                        pbm->num_pbm_ranges =
-                               (len / sizeof(struct linux_prom_pci_ranges));
-               } else {
+                               (err / sizeof(struct linux_prom_pci_ranges));
+               else
                        pbm->num_pbm_ranges = 0;
-               }
-
-               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;
+               err = prom_getproperty(sabre_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(sabre_node, "interrupt-map-mask",
+                                              (char *)&pbm->pbm_intmask,
+                                              sizeof(pbm->pbm_intmask));
+                       if (err == -1) {
+                               prom_printf("Hummingbird: Fatal error, no interrupt-map-mask.\n");
+                               prom_halt();
+                       }
                } else {
                        pbm->num_pbm_intmap = 0;
+                       memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
                }
 
-               pbm->name = dp->full_name;
-               printk("%s: SABRE PCI Bus Module\n", pbm->name);
 
+               sprintf(pbm->name, "SABRE%d PBM%c", p->index,
+                       (pbm == &p->pbm_A ? 'A' : 'B'));
                pbm->io_space.name = pbm->mem_space.name = pbm->name;
 
                /* Hack up top-level resources. */
@@ -1304,10 +1503,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
                pbm->io_space.end   = pbm->io_space.start + (1UL << 24) - 1UL;
                pbm->io_space.flags = IORESOURCE_IO;
 
-               pbm->mem_space.start =
-                       (p->pbm_A.controller_regs + SABRE_MEMSPACE);
-               pbm->mem_space.end =
-                       (pbm->mem_space.start + ((1UL << 32UL) - 1UL));
+               pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE;
+               pbm->mem_space.end   = pbm->mem_space.start + (unsigned long)dma_begin - 1UL;
                pbm->mem_space.flags = IORESOURCE_MEM;
 
                if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
@@ -1319,31 +1516,19 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
                        prom_halt();
                }
 
-               rp = kmalloc(sizeof(*rp), GFP_KERNEL);
-               if (!rp) {
-                       prom_printf("Cannot allocate IOMMU resource.\n");
-                       prom_halt();
-               }
-               rp->name = "IOMMU";
-               rp->start = pbm->mem_space.start + (unsigned long) dma_start;
-               rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL;
-               rp->flags = IORESOURCE_BUSY;
-               request_resource(&pbm->mem_space, rp);
-
                pci_register_legacy_regions(&pbm->io_space,
                                            &pbm->mem_space);
        }
 }
 
-void sabre_init(struct device_node *dp, char *model_name)
+void sabre_init(int pnode, char *model_name)
 {
-       struct linux_prom64_registers *pr_regs;
+       struct linux_prom64_registers pr_regs[2];
        struct pci_controller_info *p;
        struct pci_iommu *iommu;
-       struct property *prop;
-       int tsbsize;
-       u32 *busrange;
-       u32 *vdma;
+       int tsbsize, err;
+       u32 busrange[2];
+       u32 vdma[2];
        u32 upa_portid, dma_mask;
        u64 clear_irq;
 
@@ -1351,42 +1536,42 @@ void sabre_init(struct device_node *dp, char *model_name)
        if (!strcmp(model_name, "pci108e,a001"))
                hummingbird_p = 1;
        else if (!strcmp(model_name, "SUNW,sabre")) {
-               prop = of_find_property(dp, "compatible", NULL);
-               if (prop) {
-                       const char *compat = prop->value;
+               char compat[64];
 
-                       if (!strcmp(compat, "pci108e,a001"))
-                               hummingbird_p = 1;
-               }
-               if (!hummingbird_p) {
-                       struct device_node *dp;
+               if (prom_getproperty(pnode, "compatible",
+                                    compat, sizeof(compat)) > 0 &&
+                   !strcmp(compat, "pci108e,a001")) {
+                       hummingbird_p = 1;
+               } else {
+                       int cpu_node;
 
                        /* Of course, Sun has to encode things a thousand
                         * different ways, inconsistently.
                         */
-                       cpu_find_by_instance(0, &dp, NULL);
-                       if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe"))
+                       cpu_find_by_instance(0, &cpu_node, NULL);
+                       if (prom_getproperty(cpu_node, "name",
+                                            compat, sizeof(compat)) > 0 &&
+                           !strcmp(compat, "SUNW,UltraSPARC-IIe"))
                                hummingbird_p = 1;
                }
        }
 
-       p = kzalloc(sizeof(*p), GFP_ATOMIC);
+       p = kmalloc(sizeof(*p), GFP_ATOMIC);
        if (!p) {
                prom_printf("SABRE: Error, kmalloc(pci_controller_info) failed.\n");
                prom_halt();
        }
+       memset(p, 0, sizeof(*p));
 
-       iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC);
+       iommu = kmalloc(sizeof(*iommu), GFP_ATOMIC);
        if (!iommu) {
                prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n");
                prom_halt();
        }
+       memset(iommu, 0, sizeof(*iommu));
        p->pbm_A.iommu = p->pbm_B.iommu = iommu;
 
-       upa_portid = 0xff;
-       prop = of_find_property(dp, "upa-portid", NULL);
-       if (prop)
-               upa_portid = *(u32 *) prop->value;
+       upa_portid = prom_getintdefault(pnode, "upa-portid", 0xff);
 
        p->next = pci_controller_root;
        pci_controller_root = p;
@@ -1396,6 +1581,7 @@ void sabre_init(struct device_node *dp, char *model_name)
        p->index = pci_num_controllers++;
        p->pbms_same_domain = 1;
        p->scan_bus = sabre_scan_bus;
+       p->irq_build = sabre_irq_build;
        p->base_address_update = sabre_base_address_update;
        p->resource_adjust = sabre_resource_adjust;
        p->pci_ops = &sabre_ops;
@@ -1403,9 +1589,13 @@ void sabre_init(struct device_node *dp, char *model_name)
        /*
         * Map in SABRE register set and report the presence of this SABRE.
         */
-       
-       prop = of_find_property(dp, "reg", NULL);
-       pr_regs = prop->value;
+       err = prom_getproperty(pnode, "reg",
+                              (char *)&pr_regs[0], sizeof(pr_regs));
+       if(err == 0 || err == -1) {
+               prom_printf("SABRE: Error, cannot get U2P registers "
+                           "from PROM.\n");
+               prom_halt();
+       }
 
        /*
         * First REG in property is base of entire SABRE register space.
@@ -1413,6 +1603,9 @@ void sabre_init(struct device_node *dp, char *model_name)
        p->pbm_A.controller_regs = pr_regs[0].phys_addr;
        p->pbm_B.controller_regs = pr_regs[0].phys_addr;
 
+       printk("PCI: Found SABRE, main regs at %016lx\n",
+              p->pbm_A.controller_regs);
+
        /* Clear interrupts */
 
        /* PCI first */
@@ -1431,9 +1624,16 @@ void sabre_init(struct device_node *dp, char *model_name)
        /* Now map in PCI config space for entire SABRE. */
        p->pbm_A.config_space = p->pbm_B.config_space =
                (p->pbm_A.controller_regs + SABRE_CONFIGSPACE);
-
-       prop = of_find_property(dp, "virtual-dma", NULL);
-       vdma = prop->value;
+       printk("SABRE: Shared PCI config space at %016lx\n",
+              p->pbm_A.config_space);
+
+       err = prom_getproperty(pnode, "virtual-dma",
+                              (char *)&vdma[0], sizeof(vdma));
+       if(err == 0 || err == -1) {
+               prom_printf("SABRE: Error, cannot get virtual-dma property "
+                           "from PROM.\n");
+               prom_halt();
+       }
 
        dma_mask = vdma[0];
        switch(vdma[1]) {
@@ -1457,13 +1657,21 @@ void sabre_init(struct device_node *dp, char *model_name)
 
        sabre_iommu_init(p, tsbsize, vdma[0], dma_mask);
 
-       prop = of_find_property(dp, "bus-range", NULL);
-       busrange = prop->value;
+       printk("SABRE: DVMA at %08x [%08x]\n", vdma[0], vdma[1]);
+
+       err = prom_getproperty(pnode, "bus-range",
+                                      (char *)&busrange[0], sizeof(busrange));
+       if(err == 0 || err == -1) {
+               prom_printf("SABRE: Error, cannot get PCI bus-range "
+                           " from PROM.\n");
+               prom_halt();
+       }
+
        p->pci_first_busno = busrange[0];
        p->pci_last_busno = busrange[1];
 
        /*
         * Look for APB underneath.
         */
-       sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]);
+       sabre_pbm_init(p, pnode, vdma[0]);
 }