Merge ../linus
[pandora-kernel.git] / arch / sparc64 / kernel / pci_psycho.c
index c03ed5f..5b2261e 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/iommu.h>
 #include <asm/irq.h>
 #include <asm/starfire.h>
+#include <asm/prom.h>
 
 #include "pci_impl.h"
 #include "iommu_common.h"
@@ -276,82 +277,13 @@ static unsigned long __onboard_imap_off[] = {
        ((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 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 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;
+       int inofixup = 0;
 
        ino &= PCI_IRQ_INO;
        if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
@@ -367,11 +299,6 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
        }
 
        /* 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;
 
@@ -382,10 +309,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
        if ((ino & 0x20) == 0)
                inofixup = ino & 0x03;
 
-       bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
-       bucket->flags |= IBF_PCI;
-
-       return __irq(bucket);
+       return build_irq(inofixup, iclr, imap);
 }
 
 /* PSYCHO error handling support. */
@@ -1164,7 +1088,7 @@ static void pbm_config_busmastering(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 +1096,6 @@ static void 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,
@@ -1369,11 +1292,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;
@@ -1388,10 +1312,14 @@ 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;
@@ -1400,45 +1328,36 @@ static void psycho_pbm_init(struct pci_controller_info *p,
        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;
+
+       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];
 
@@ -1447,36 +1366,38 @@ static void psycho_pbm_init(struct pci_controller_info *p,
 
 #define PSYCHO_CONFIGSPACE     0x001000000UL
 
-void 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;
+       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;
 
        for(p = pci_controller_root; p; p = p->next) {
                if (p->pbm_A.portid == upa_portid) {
-                       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;
                }
        }
 
-       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;
 
        p->next = pci_controller_root;
@@ -1492,23 +1413,14 @@ void psycho_init(int node, char *model_name)
        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
@@ -1521,5 +1433,5 @@ void 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);
 }