]> err.no Git - linux-2.6/commitdiff
[SPARC64]: Convert sparc64 PCI layer to in-kernel device tree.
authorDavid S. Miller <davem@sunset.davemloft.net>
Thu, 22 Jun 2006 23:18:54 +0000 (16:18 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Sat, 24 Jun 2006 06:15:26 +0000 (23:15 -0700)
One thing this change pointed out was that we really should
pull the "get 'local-mac-address' property" logic into a helper
function all the network drivers can call.

Signed-off-by: David S. Miller <davem@davemloft.net>
17 files changed:
arch/sparc64/kernel/ebus.c
arch/sparc64/kernel/isa.c
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_impl.h
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/prom.c
drivers/net/sungem.c
drivers/net/sunhme.c
drivers/net/tg3.c
drivers/net/tulip/tulip_core.c
drivers/sbus/char/openprom.c
drivers/video/aty/atyfb_base.c
include/asm-sparc64/pbm.h
include/asm-sparc64/prom.h

index c69504aa638f59418a3bf08040cabb57fc85767f..3125a5b4977529814361758f891aaf6509a63f79 100644 (file)
@@ -553,7 +553,7 @@ void __init ebus_init(void)
        }
 
        cookie = pdev->sysdata;
-       ebusnd = cookie->prom_node;
+       ebusnd = cookie->prom_node->node;
 
        ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
        ebus->next = NULL;
@@ -578,7 +578,7 @@ void __init ebus_init(void)
                        }
                        ebus->is_rio = is_rio;
                        cookie = pdev->sysdata;
-                       ebusnd = cookie->prom_node;
+                       ebusnd = cookie->prom_node->node;
                        continue;
                }
                printk("ebus%d:", num_ebus);
@@ -622,7 +622,7 @@ void __init ebus_init(void)
                        break;
 
                cookie = pdev->sysdata;
-               ebusnd = cookie->prom_node;
+               ebusnd = cookie->prom_node->node;
 
                ebus->next = ebus_alloc(sizeof(struct linux_ebus));
                ebus = ebus->next;
index 30862abee611d745fd3182722c2c23e73bda488f..ae02c3820eabf0fc2f59e919a02fdb9fb3f045a7 100644 (file)
@@ -291,8 +291,8 @@ void __init isa_init(void)
                isa_br->parent = pbm;
                isa_br->self = pdev;
                isa_br->index = index++;
-               isa_br->prom_node = pdev_cookie->prom_node;
-               strncpy(isa_br->prom_name, pdev_cookie->prom_name,
+               isa_br->prom_node = pdev_cookie->prom_node->node;
+               strncpy(isa_br->prom_name, pdev_cookie->prom_node->name,
                        sizeof(isa_br->prom_name));
 
                prop_len = prom_getproperty(isa_br->prom_node,
index 2319d732b13e4360e296f1577a682f4c724437ae..b06a2955bf5f720b30a1af3db2206de8f9f4d215 100644 (file)
@@ -9,6 +9,9 @@
 #include <linux/init.h>
 
 #include <asm/pbm.h>
+#include <asm/prom.h>
+
+#include "pci_impl.h"
 
 /* Pass "pci=irq_verbose" on the kernel command line to enable this.  */
 int pci_irq_verbose;
@@ -31,16 +34,14 @@ void __init pci_fixup_host_bridge_self(struct pci_bus *pbus)
        prom_halt();
 }
 
-/* Find the OBP PROM device tree node for a PCI device.
- * Return zero if not found.
- */
-static int __init find_device_prom_node(struct pci_pbm_info *pbm,
-                                       struct pci_dev *pdev,
-                                       int bus_prom_node,
-                                       struct linux_prom_pci_registers *pregs,
-                                       int *nregs)
+/* Find the OBP PROM device tree node for a PCI device.  */
+static struct device_node * __init
+find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev,
+                     struct device_node *bus_node,
+                     struct linux_prom_pci_registers **pregs,
+                     int *nregs)
 {
-       int node;
+       struct device_node *dp;
 
        *nregs = 0;
 
@@ -57,24 +58,30 @@ static int __init find_device_prom_node(struct pci_pbm_info *pbm,
             pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO ||
             pdev->device == PCI_DEVICE_ID_SUN_SABRE ||
             pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD))
-               return bus_prom_node;
-
-       node = prom_getchild(bus_prom_node);
-       while (node != 0) {
-               int err = prom_getproperty(node, "reg",
-                                          (char *)pregs,
-                                          sizeof(*pregs) * PROMREG_MAX);
-               if (err == 0 || err == -1)
+               return bus_node;
+
+       dp = bus_node->child;
+       while (dp) {
+               struct linux_prom_pci_registers *regs;
+               struct property *prop;
+               int len;
+
+               prop = of_find_property(dp, "reg", &len);
+               if (!prop)
                        goto do_next_sibling;
-               if (((pregs[0].phys_hi >> 8) & 0xff) == pdev->devfn) {
-                       *nregs = err / sizeof(*pregs);
-                       return node;
+
+               regs = prop->value;
+               if (((regs[0].phys_hi >> 8) & 0xff) == pdev->devfn) {
+                       *pregs = regs;
+                       *nregs = len / sizeof(struct linux_prom_pci_registers);
+                       return dp;
                }
 
        do_next_sibling:
-               node = prom_getsibling(node);
+               dp = dp->sibling;
        }
-       return 0;
+
+       return NULL;
 }
 
 /* Older versions of OBP on PCI systems encode 64-bit MEM
@@ -131,15 +138,17 @@ static void __init fixup_obp_assignments(struct pci_dev *pdev,
  */
 static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
                                      struct pci_dev *pdev,
-                                     int bus_prom_node)
+                                     struct device_node *bus_node)
 {
-       struct linux_prom_pci_registers pregs[PROMREG_MAX];
+       struct linux_prom_pci_registers *pregs = NULL;
        struct pcidev_cookie *pcp;
-       int device_prom_node, nregs, err;
+       struct device_node *dp;
+       struct property *prop;
+       int nregs, len;
 
-       device_prom_node = find_device_prom_node(pbm, pdev, bus_prom_node,
-                                                pregs, &nregs);
-       if (device_prom_node == 0) {
+       dp = find_device_prom_node(pbm, pdev, bus_node,
+                                  &pregs, &nregs);
+       if (!dp) {
                /* If it is not in the OBP device tree then
                 * there must be a damn good reason for it.
                 *
@@ -153,45 +162,43 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
                return;
        }
 
-       pcp = kmalloc(sizeof(*pcp), GFP_ATOMIC);
+       pcp = kzalloc(sizeof(*pcp), GFP_ATOMIC);
        if (pcp == NULL) {
                prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n");
                prom_halt();
        }
        pcp->pbm = pbm;
-       pcp->prom_node = device_prom_node;
-       memcpy(pcp->prom_regs, pregs, sizeof(pcp->prom_regs));
+       pcp->prom_node = dp;
+       memcpy(pcp->prom_regs, pregs,
+              nregs * sizeof(struct linux_prom_pci_registers));
        pcp->num_prom_regs = nregs;
-       err = prom_getproperty(device_prom_node, "name",
-                              pcp->prom_name, sizeof(pcp->prom_name));
-       if (err > 0)
-               pcp->prom_name[err] = 0;
-       else
-               pcp->prom_name[0] = 0;
-
-       err = prom_getproperty(device_prom_node,
-                              "assigned-addresses",
-                              (char *)pcp->prom_assignments,
-                              sizeof(pcp->prom_assignments));
-       if (err == 0 || err == -1)
+
+       /* We can't have the pcidev_cookie assignments be just
+        * direct pointers into the property value, since they
+        * are potentially modified by the probing process.
+        */
+       prop = of_find_property(dp, "assigned-addresses", &len);
+       if (!prop) {
                pcp->num_prom_assignments = 0;
-       else
+       } else {
+               memcpy(pcp->prom_assignments, prop->value, len);
                pcp->num_prom_assignments =
-                       (err / sizeof(pcp->prom_assignments[0]));
+                       (len / sizeof(pcp->prom_assignments[0]));
+       }
 
-       if (strcmp(pcp->prom_name, "ebus") == 0) {
-               struct linux_prom_ebus_ranges erng[PROM_PCIRNG_MAX];
+       if (strcmp(dp->name, "ebus") == 0) {
+               struct linux_prom_ebus_ranges *erng;
                int iter;
 
                /* EBUS is special... */
-               err = prom_getproperty(device_prom_node, "ranges",
-                                      (char *)&erng[0], sizeof(erng));
-               if (err == 0 || err == -1) {
+               prop = of_find_property(dp, "ranges", &len);
+               if (!prop) {
                        prom_printf("EBUS: Fatal error, no range property\n");
                        prom_halt();
                }
-               err = (err / sizeof(erng[0]));
-               for(iter = 0; iter < err; iter++) {
+               erng = prop->value;
+               len = (len / sizeof(erng[0]));
+               for (iter = 0; iter < len; iter++) {
                        struct linux_prom_ebus_ranges *ep = &erng[iter];
                        struct linux_prom_pci_registers *ap;
 
@@ -203,7 +210,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
                        ap->size_hi = 0;
                        ap->size_lo = ep->size;
                }
-               pcp->num_prom_assignments = err;
+               pcp->num_prom_assignments = len;
        }
 
        fixup_obp_assignments(pdev, pcp);
@@ -213,7 +220,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
 
 void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
                                    struct pci_pbm_info *pbm,
-                                   int prom_node)
+                                   struct device_node *dp)
 {
        struct pci_dev *pdev, *pdev_next;
        struct pci_bus *this_pbus, *pbus_next;
@@ -221,7 +228,7 @@ void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
        /* This must be _safe because the cookie fillin
           routine can delete devices from the tree.  */
        list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list)
-               pdev_cookie_fillin(pbm, pdev, prom_node);
+               pdev_cookie_fillin(pbm, pdev, dp);
 
        list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) {
                struct pcidev_cookie *pcp = this_pbus->self->sysdata;
@@ -244,7 +251,6 @@ static void __init bad_assignment(struct pci_dev *pdev,
        if (res)
                prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n",
                            res->start, res->end, res->flags);
-       prom_printf("Please email this information to davem@redhat.com\n");
        if (do_prom_halt)
                prom_halt();
 }
@@ -276,8 +282,7 @@ __init get_root_resource(struct linux_prom_pci_registers *ap,
                return &pbm->mem_space;
 
        default:
-               printk("PCI: What is resource space %x? "
-                      "Tell davem@redhat.com about it!\n", space);
+               printk("PCI: What is resource space %x?\n", space);
                return NULL;
        };
 }
@@ -572,50 +577,51 @@ static inline unsigned int pci_apply_intmap(struct pci_pbm_info *pbm,
                                            struct pci_dev *pbus,
                                            struct pci_dev *pdev,
                                            unsigned int interrupt,
-                                           unsigned int *cnode)
+                                           struct device_node **cnode)
 {
-       struct linux_prom_pci_intmap imap[PROM_PCIIMAP_MAX];
-       struct linux_prom_pci_intmask imask;
+       struct linux_prom_pci_intmap *imap;
+       struct linux_prom_pci_intmask *imask;
        struct pcidev_cookie *pbus_pcp = pbus->sysdata;
        struct pcidev_cookie *pdev_pcp = pdev->sysdata;
        struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs;
+       struct property *prop;
        int plen, num_imap, i;
        unsigned int hi, mid, lo, irq, orig_interrupt;
 
        *cnode = pbus_pcp->prom_node;
 
-       plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map",
-                               (char *) &imap[0], sizeof(imap));
-       if (plen <= 0 ||
+       prop = of_find_property(pbus_pcp->prom_node, "interrupt-map", &plen);
+       if (!prop ||
            (plen % sizeof(struct linux_prom_pci_intmap)) != 0) {
                printk("%s: Device %s interrupt-map has bad len %d\n",
                       pbm->name, pci_name(pbus), plen);
                goto no_intmap;
        }
+       imap = prop->value;
        num_imap = plen / sizeof(struct linux_prom_pci_intmap);
 
-       plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map-mask",
-                               (char *) &imask, sizeof(imask));
-       if (plen <= 0 ||
+       prop = of_find_property(pbus_pcp->prom_node, "interrupt-map-mask", &plen);
+       if (!prop ||
            (plen % sizeof(struct linux_prom_pci_intmask)) != 0) {
                printk("%s: Device %s interrupt-map-mask has bad len %d\n",
                       pbm->name, pci_name(pbus), plen);
                goto no_intmap;
        }
+       imask = prop->value;
 
        orig_interrupt = interrupt;
 
-       hi   = pregs->phys_hi & imask.phys_hi;
-       mid  = pregs->phys_mid & imask.phys_mid;
-       lo   = pregs->phys_lo & imask.phys_lo;
-       irq  = interrupt & imask.interrupt;
+       hi   = pregs->phys_hi & imask->phys_hi;
+       mid  = pregs->phys_mid & imask->phys_mid;
+       lo   = pregs->phys_lo & imask->phys_lo;
+       irq  = interrupt & imask->interrupt;
 
        for (i = 0; i < num_imap; i++) {
                if (imap[i].phys_hi  == hi   &&
                    imap[i].phys_mid == mid  &&
                    imap[i].phys_lo  == lo   &&
                    imap[i].interrupt == irq) {
-                       *cnode = imap[i].cnode;
+                       *cnode = of_find_node_by_phandle(imap[i].cnode);
                        interrupt = imap[i].cinterrupt;
                }
        }
@@ -638,21 +644,22 @@ no_intmap:
  * all interrupt translations are complete, else we should use that node's
  * "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt.
  */
-static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm,
-                                                   struct pci_dev *pdev,
-                                                   unsigned int *interrupt)
+static struct device_node * __init
+pci_intmap_match_to_root(struct pci_pbm_info *pbm,
+                        struct pci_dev *pdev,
+                        unsigned int *interrupt)
 {
        struct pci_dev *toplevel_pdev = pdev;
        struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata;
-       unsigned int cnode = toplevel_pcp->prom_node;
+       struct device_node *cnode = toplevel_pcp->prom_node;
 
        while (pdev->bus->number != pbm->pci_first_busno) {
                struct pci_dev *pbus = pdev->bus->self;
                struct pcidev_cookie *pcp = pbus->sysdata;
-               int plen;
+               struct property *prop;
 
-               plen = prom_getproplen(pcp->prom_node, "interrupt-map");
-               if (plen <= 0) {
+               prop = of_find_property(pcp->prom_node, "interrupt-map", NULL);
+               if (!prop) {
                        *interrupt = pci_slot_swivel(pbm, toplevel_pdev,
                                                     pdev, *interrupt);
                        cnode = pcp->prom_node;
@@ -669,7 +676,7 @@ static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm,
                }
                pdev = pbus;
 
-               if (cnode == pbm->prom_node->node)
+               if (cnode == pbm->prom_node)
                        break;
        }
 
@@ -680,21 +687,24 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
 {
        struct pcidev_cookie *dev_pcp = pdev->sysdata;
        struct pci_pbm_info *pbm = dev_pcp->pbm;
-       struct linux_prom_pci_registers reg[PROMREG_MAX];
+       struct linux_prom_pci_registers *reg;
+       struct device_node *cnode;
+       struct property *prop;
        unsigned int hi, mid, lo, irq;
-       int i, cnode, plen;
+       int i, plen;
 
        cnode = pci_intmap_match_to_root(pbm, pdev, interrupt);
-       if (cnode == pbm->prom_node->node)
+       if (cnode == pbm->prom_node)
                goto success;
 
-       plen = prom_getproperty(cnode, "reg", (char *) reg, sizeof(reg));
-       if (plen <= 0 ||
+       prop = of_find_property(cnode, "reg", &plen);
+       if (!prop ||
            (plen % sizeof(struct linux_prom_pci_registers)) != 0) {
-               printk("%s: OBP node %x reg property has bad len %d\n",
-                      pbm->name, cnode, plen);
+               printk("%s: OBP node %s reg property has bad len %d\n",
+                      pbm->name, cnode->full_name, plen);
                goto fail;
        }
+       reg = prop->value;
 
        hi   = reg[0].phys_hi & pbm->pbm_intmask->phys_hi;
        mid  = reg[0].phys_mid & pbm->pbm_intmask->phys_mid;
@@ -734,8 +744,8 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
        struct pci_controller_info *p = pbm->parent;
        unsigned int portid = pbm->portid;
        unsigned int prom_irq;
-       int prom_node = pcp->prom_node;
-       int err;
+       struct device_node *dp = pcp->prom_node;
+       struct property *prop;
 
        /* If this is an empty EBUS device, sometimes OBP fails to
         * give it a valid fully specified interrupts property.
@@ -746,17 +756,17 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
         */
        if (pdev->vendor == PCI_VENDOR_ID_SUN &&
            pdev->device == PCI_DEVICE_ID_SUN_EBUS &&
-           !prom_getchild(prom_node)) {
+           !dp->child) {
                pdev->irq = 0;
                return;
        }
 
-       err = prom_getproperty(prom_node, "interrupts",
-                              (char *)&prom_irq, sizeof(prom_irq));
-       if (err == 0 || err == -1) {
+       prop = of_find_property(dp, "interrupts", NULL);
+       if (!prop) {
                pdev->irq = 0;
                return;
        }
+       prom_irq = *(unsigned int *) prop->value;
 
        if (tlb_type != hypervisor) {
                /* Fully specified already? */
index 6c32059625440333e0991cb96ddbaa7ce76e594a..971e2bea30b41b4e0006b15037e96ecf6c08012f 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <asm/io.h>
+#include <asm/prom.h>
 
 extern struct pci_controller_info *pci_controller_root;
 
@@ -19,7 +20,7 @@ extern int pci_num_controllers;
 extern void pci_fixup_host_bridge_self(struct pci_bus *pbus);
 extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus,
                                    struct pci_pbm_info *pbm,
-                                   int prom_node);
+                                   struct device_node *prom_node);
 extern void pci_record_assignments(struct pci_pbm_info *pbm,
                                   struct pci_bus *pbus);
 extern void pci_assign_unassigned(struct pci_pbm_info *pbm,
index 40c2b68199835b3f320cd0096721a1c4b084abb2..5b2261ebda6f98bd787ee3e143b55a2861677056 100644 (file)
@@ -1104,7 +1104,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
        pci_fixup_host_bridge_self(pbm->pci_bus);
        pbm->pci_bus->self->sysdata = cookie;
 
-       pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node);
+       pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
        pci_record_assignments(pbm, pbm->pci_bus);
        pci_assign_unassigned(pbm, pbm->pci_bus);
        pci_fixup_irq(pbm, pbm->pci_bus);
index 4ce7b4620c09438f1dfef96e438673565930398e..26f194ce4400082774ae5bcb5a96e6be062ef1e8 100644 (file)
@@ -1161,7 +1161,7 @@ static void sabre_scan_bus(struct pci_controller_info *p)
 
                pbus->sysdata = pbm;
                pbm->pci_bus = pbus;
-               pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node->node);
+               pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node);
                pci_record_assignments(pbm, pbus);
                pci_assign_unassigned(pbm, pbus);
                pci_fixup_irq(pbm, pbus);
@@ -1174,7 +1174,7 @@ static void sabre_scan_bus(struct pci_controller_info *p)
                pbm = &p->pbm_A;
                sabre_bus->sysdata = pbm;
                pbm->pci_bus = sabre_bus;
-               pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node->node);
+               pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node);
                pci_record_assignments(pbm, sabre_bus);
                pci_assign_unassigned(pbm, sabre_bus);
                pci_fixup_irq(pbm, sabre_bus);
index d26820086843eefdb0e01a3034516b90c59218ee..f16449ccd7bc389d172509976e7171a3ca3c2125 100644 (file)
@@ -1438,7 +1438,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
        pci_fixup_host_bridge_self(pbm->pci_bus);
        pbm->pci_bus->self->sysdata = cookie;
 
-       pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node);
+       pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
        pci_record_assignments(pbm, pbm->pci_bus);
        pci_assign_unassigned(pbm, pbm->pci_bus);
        pci_fixup_irq(pbm, pbm->pci_bus);
index b275c7df01867d0f67622a2febce28105de1c256..b69e2270a721103099184cbe3b456a48702b99c2 100644 (file)
@@ -814,8 +814,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
        pci_fixup_host_bridge_self(pbm->pci_bus);
        pbm->pci_bus->self->sysdata = cookie;
 #endif
-       pci_fill_in_pbm_cookies(pbm->pci_bus, pbm,
-                               pbm->prom_node->node);
+       pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
        pci_record_assignments(pbm, pbm->pci_bus);
        pci_assign_unassigned(pbm, pbm->pci_bus);
        pci_fixup_irq(pbm, pbm->pci_bus);
index 0a32b1064dfbf51b92edf070e35d983228909175..fb112c3c0485b46cd5c272b3197788edf1f01376 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/module.h>
 
 #include <asm/prom.h>
 #include <asm/oplib.h>
@@ -63,6 +64,17 @@ struct device_node *of_find_node_by_path(const char *path)
        return np;
 }
 
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+       struct device_node *np;
+
+       for (np = allnodes; np != 0; np = np->allnext)
+               if (np->node == handle)
+                       break;
+
+       return np;
+}
+
 struct device_node *of_find_node_by_name(struct device_node *from,
        const char *name)
 {
@@ -103,6 +115,18 @@ struct property *of_find_property(struct device_node *np, const char *name,
        }
        return pp;
 }
+EXPORT_SYMBOL(of_find_property);
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+void *of_get_property(struct device_node *np, const char *name, int *lenp)
+{
+       struct property *pp = of_find_property(np,name,lenp);
+       return pp ? pp->value : NULL;
+}
+EXPORT_SYMBOL(of_get_property);
 
 int of_getintprop_default(struct device_node *np, const char *name, int def)
 {
@@ -115,6 +139,7 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
 
        return *(int *) prop->value;
 }
+EXPORT_SYMBOL(of_getintprop_default);
 
 static unsigned int prom_early_allocated;
 
index 38cd30cb7c750e0ef7c248d160f1400b3593e22b..5248670d29f70e33c2af87939985b3c3c72cd4c4 100644 (file)
@@ -2880,17 +2880,20 @@ static int __devinit gem_get_device_address(struct gem *gp)
 #if defined(__sparc__)
        struct pci_dev *pdev = gp->pdev;
        struct pcidev_cookie *pcp = pdev->sysdata;
-       int node = -1;
+       int use_idprom = 1;
 
        if (pcp != NULL) {
-               node = pcp->prom_node;
-               if (prom_getproplen(node, "local-mac-address") == 6)
-                       prom_getproperty(node, "local-mac-address",
-                                        dev->dev_addr, 6);
-               else
-                       node = -1;
+               unsigned char *addr;
+               int len;
+
+               addr = of_get_property(pcp->prom_node, "local-mac-address",
+                                      &len);
+               if (addr && len == 6) {
+                       use_idprom = 0;
+                       memcpy(dev->dev_addr, addr, 6);
+               }
        }
-       if (node == -1)
+       if (use_idprom)
                memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
 #elif defined(CONFIG_PPC_PMAC)
        unsigned char *addr;
index bd5d2668a36227626b6cefbf0b20eac9b1c8d3a4..b0d452733c9bfb8d2736002c3a19a00a913f0d54 100644 (file)
@@ -3013,7 +3013,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
        struct quattro *qp = NULL;
 #ifdef __sparc__
        struct pcidev_cookie *pcp;
-       int node;
 #endif
        struct happy_meal *hp;
        struct net_device *dev;
@@ -3026,13 +3025,12 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
        /* Now make sure pci_dev cookie is there. */
 #ifdef __sparc__
        pcp = pdev->sysdata;
-       if (pcp == NULL || pcp->prom_node == -1) {
+       if (pcp == NULL) {
                printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n");
                return -ENODEV;
        }
-       node = pcp->prom_node;
        
-       prom_getstring(node, "name", prom_name, sizeof(prom_name));
+       strcpy(prom_name, pcp->prom_node->name);
 #else
        if (is_quattro_p(pdev))
                strcpy(prom_name, "SUNW,qfe");
@@ -3104,10 +3102,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
                macaddr[5]++;
        } else {
 #ifdef __sparc__
+               unsigned char *addr;
+               int len;
+
                if (qfe_slot != -1 &&
-                   prom_getproplen(node, "local-mac-address") == 6) {
-                       prom_getproperty(node, "local-mac-address",
-                                        dev->dev_addr, 6);
+                   (addr = of_get_property(pcp->prom_node,
+                                           "local-mac-address", &len)) != NULL
+                   && len == 6) {
+                       memcpy(dev->dev_addr, addr, 6);
                } else {
                        memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
                }
@@ -3124,7 +3126,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
        hp->tcvregs    = (hpreg_base + 0x7000UL);
 
 #ifdef __sparc__
-       hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff);
+       hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff);
        if (hp->hm_revision == 0xff) {
                unsigned char prev;
 
index e3e380f90f86dec173b0966936d64951aa80ba40..35f931638750cd333d376e0928ad5fd844e39866 100644 (file)
@@ -10549,11 +10549,13 @@ static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp)
        struct pcidev_cookie *pcp = pdev->sysdata;
 
        if (pcp != NULL) {
-               int node = pcp->prom_node;
+               unsigned char *addr;
+               int len;
 
-               if (prom_getproplen(node, "local-mac-address") == 6) {
-                       prom_getproperty(node, "local-mac-address",
-                                        dev->dev_addr, 6);
+               addr = of_get_property(pcp->prom_node, "local-mac-address",
+                                       &len);
+               if (addr && len == 6) {
+                       memcpy(dev->dev_addr, addr, 6);
                        memcpy(dev->perm_addr, dev->dev_addr, 6);
                        return 0;
                }
index cabdf894e21e3c7e3ea39c1705b41237ca15dfa9..e0de66739a422744616ae3205e89db5504f2036c 100644 (file)
@@ -1550,10 +1550,14 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                        dev->dev_addr[i] = last_phys_addr[i];
                dev->dev_addr[i] = last_phys_addr[i] + 1;
 #if defined(__sparc__)
-               if ((pcp != NULL) && prom_getproplen(pcp->prom_node,
-                       "local-mac-address") == 6) {
-                       prom_getproperty(pcp->prom_node, "local-mac-address",
-                           dev->dev_addr, 6);
+               if (pcp) {
+                       unsigned char *addr;
+                       int len;
+                 
+                       addr = of_get_property(pcp->prom_node,
+                                              "local-mac-address", &len);
+                       if (addr && len == 6)
+                               memcpy(dev->dev_addr, addr, 6);
                }
 #endif
 #if defined(__i386__) || defined(__x86_64__)   /* Patch up x86 BIOS bug. */
index 239e108b8ed1e16cb45d51fa89591418a5410bac..cf5b476b549676df72f24ab4366279edb5930b1c 100644 (file)
@@ -243,8 +243,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
                                              ((int *) opp->oprom_array)[1]);
 
                        pcp = pdev->sysdata;
-                       if (pcp != NULL && pcp->prom_node != -1 && pcp->prom_node) {
-                               node = pcp->prom_node;
+                       if (pcp != NULL) {
+                               node = pcp->prom_node->node;
                                data->current_node = node;
                                *((int *)opp->oprom_array) = node;
                                opp->oprom_size = sizeof(int);
index eb6aa42be60eb8cf6413c9106e4c270f4ec4f4f2..c054bb28b1c4a1a74cba6c47bd388394514718eb 100644 (file)
@@ -2966,7 +2966,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
        }
 
        pcp = pdev->sysdata;
-       if (node == pcp->prom_node) {
+       if (node == pcp->prom_node->node) {
                struct fb_var_screeninfo *var = &default_var;
                unsigned int N, P, Q, M, T, R;
                u32 v_total, h_total;
index 142cc4028bb86ed7a513ae4a300fe87ccf2c2914..cebe80b1da6c70f9aa626ea13add9fd7a2e00ac1 100644 (file)
@@ -227,8 +227,7 @@ struct pci_controller_info {
  */
 struct pcidev_cookie {
        struct pci_pbm_info             *pbm;
-       char                            prom_name[64];
-       int                             prom_node;
+       struct device_node              *prom_node;
        struct linux_prom_pci_registers prom_regs[PROMREG_MAX];
        int num_prom_regs;
        struct linux_prom_pci_registers prom_assignments[PROMREG_MAX];
index d0187b3a0ec39607c058836c2effc2e505340e5b..062ae6e1212e6b507f0189d94153772c6c7fbf25 100644 (file)
@@ -76,12 +76,15 @@ extern struct device_node *of_find_node_by_type(struct device_node *from,
        for (dn = of_find_node_by_type(NULL, type); dn; \
             dn = of_find_node_by_type(dn, type))
 extern struct device_node *of_find_node_by_path(const char *path);
+extern struct device_node *of_find_node_by_phandle(phandle handle);
 extern struct device_node *of_get_parent(const struct device_node *node);
 extern struct device_node *of_get_next_child(const struct device_node *node,
                                             struct device_node *prev);
 extern struct property *of_find_property(struct device_node *np,
                                         const char *name,
                                         int *lenp);
+extern void *of_get_property(struct device_node *node, const char *name,
+                            int *lenp);
 extern int of_getintprop_default(struct device_node *np,
                                 const char *name,
                                 int def);