aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-22 19:18:54 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:26 -0400
commitde8d28b16f5614aeb12bb69c8f9a38578b8d3ada (patch)
tree152f0930dc099606342e9cc6d9a3892cd9f3f192
parent765b5f32730cfd2608291e679060b0391570c8b3 (diff)
[SPARC64]: Convert sparc64 PCI layer to in-kernel device tree.
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>
-rw-r--r--arch/sparc64/kernel/ebus.c6
-rw-r--r--arch/sparc64/kernel/isa.c4
-rw-r--r--arch/sparc64/kernel/pci_common.c196
-rw-r--r--arch/sparc64/kernel/pci_impl.h3
-rw-r--r--arch/sparc64/kernel/pci_psycho.c2
-rw-r--r--arch/sparc64/kernel/pci_sabre.c4
-rw-r--r--arch/sparc64/kernel/pci_schizo.c2
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c3
-rw-r--r--arch/sparc64/kernel/prom.c25
-rw-r--r--drivers/net/sungem.c19
-rw-r--r--drivers/net/sunhme.c18
-rw-r--r--drivers/net/tg3.c10
-rw-r--r--drivers/net/tulip/tulip_core.c12
-rw-r--r--drivers/sbus/char/openprom.c4
-rw-r--r--drivers/video/aty/atyfb_base.c2
-rw-r--r--include/asm-sparc64/pbm.h3
-rw-r--r--include/asm-sparc64/prom.h3
17 files changed, 182 insertions, 134 deletions
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index c69504aa638f..3125a5b49775 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -553,7 +553,7 @@ void __init ebus_init(void)
553 } 553 }
554 554
555 cookie = pdev->sysdata; 555 cookie = pdev->sysdata;
556 ebusnd = cookie->prom_node; 556 ebusnd = cookie->prom_node->node;
557 557
558 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); 558 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
559 ebus->next = NULL; 559 ebus->next = NULL;
@@ -578,7 +578,7 @@ void __init ebus_init(void)
578 } 578 }
579 ebus->is_rio = is_rio; 579 ebus->is_rio = is_rio;
580 cookie = pdev->sysdata; 580 cookie = pdev->sysdata;
581 ebusnd = cookie->prom_node; 581 ebusnd = cookie->prom_node->node;
582 continue; 582 continue;
583 } 583 }
584 printk("ebus%d:", num_ebus); 584 printk("ebus%d:", num_ebus);
@@ -622,7 +622,7 @@ void __init ebus_init(void)
622 break; 622 break;
623 623
624 cookie = pdev->sysdata; 624 cookie = pdev->sysdata;
625 ebusnd = cookie->prom_node; 625 ebusnd = cookie->prom_node->node;
626 626
627 ebus->next = ebus_alloc(sizeof(struct linux_ebus)); 627 ebus->next = ebus_alloc(sizeof(struct linux_ebus));
628 ebus = ebus->next; 628 ebus = ebus->next;
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index 30862abee611..ae02c3820eab 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -291,8 +291,8 @@ void __init isa_init(void)
291 isa_br->parent = pbm; 291 isa_br->parent = pbm;
292 isa_br->self = pdev; 292 isa_br->self = pdev;
293 isa_br->index = index++; 293 isa_br->index = index++;
294 isa_br->prom_node = pdev_cookie->prom_node; 294 isa_br->prom_node = pdev_cookie->prom_node->node;
295 strncpy(isa_br->prom_name, pdev_cookie->prom_name, 295 strncpy(isa_br->prom_name, pdev_cookie->prom_node->name,
296 sizeof(isa_br->prom_name)); 296 sizeof(isa_br->prom_name));
297 297
298 prop_len = prom_getproperty(isa_br->prom_node, 298 prop_len = prom_getproperty(isa_br->prom_node,
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index 2319d732b13e..b06a2955bf5f 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -9,6 +9,9 @@
9#include <linux/init.h> 9#include <linux/init.h>
10 10
11#include <asm/pbm.h> 11#include <asm/pbm.h>
12#include <asm/prom.h>
13
14#include "pci_impl.h"
12 15
13/* Pass "pci=irq_verbose" on the kernel command line to enable this. */ 16/* Pass "pci=irq_verbose" on the kernel command line to enable this. */
14int pci_irq_verbose; 17int pci_irq_verbose;
@@ -31,16 +34,14 @@ void __init pci_fixup_host_bridge_self(struct pci_bus *pbus)
31 prom_halt(); 34 prom_halt();
32} 35}
33 36
34/* Find the OBP PROM device tree node for a PCI device. 37/* Find the OBP PROM device tree node for a PCI device. */
35 * Return zero if not found. 38static struct device_node * __init
36 */ 39find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev,
37static int __init find_device_prom_node(struct pci_pbm_info *pbm, 40 struct device_node *bus_node,
38 struct pci_dev *pdev, 41 struct linux_prom_pci_registers **pregs,
39 int bus_prom_node, 42 int *nregs)
40 struct linux_prom_pci_registers *pregs,
41 int *nregs)
42{ 43{
43 int node; 44 struct device_node *dp;
44 45
45 *nregs = 0; 46 *nregs = 0;
46 47
@@ -57,24 +58,30 @@ static int __init find_device_prom_node(struct pci_pbm_info *pbm,
57 pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO || 58 pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO ||
58 pdev->device == PCI_DEVICE_ID_SUN_SABRE || 59 pdev->device == PCI_DEVICE_ID_SUN_SABRE ||
59 pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) 60 pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD))
60 return bus_prom_node; 61 return bus_node;
61 62
62 node = prom_getchild(bus_prom_node); 63 dp = bus_node->child;
63 while (node != 0) { 64 while (dp) {
64 int err = prom_getproperty(node, "reg", 65 struct linux_prom_pci_registers *regs;
65 (char *)pregs, 66 struct property *prop;
66 sizeof(*pregs) * PROMREG_MAX); 67 int len;
67 if (err == 0 || err == -1) 68
69 prop = of_find_property(dp, "reg", &len);
70 if (!prop)
68 goto do_next_sibling; 71 goto do_next_sibling;
69 if (((pregs[0].phys_hi >> 8) & 0xff) == pdev->devfn) { 72
70 *nregs = err / sizeof(*pregs); 73 regs = prop->value;
71 return node; 74 if (((regs[0].phys_hi >> 8) & 0xff) == pdev->devfn) {
75 *pregs = regs;
76 *nregs = len / sizeof(struct linux_prom_pci_registers);
77 return dp;
72 } 78 }
73 79
74 do_next_sibling: 80 do_next_sibling:
75 node = prom_getsibling(node); 81 dp = dp->sibling;
76 } 82 }
77 return 0; 83
84 return NULL;
78} 85}
79 86
80/* Older versions of OBP on PCI systems encode 64-bit MEM 87/* 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,
131 */ 138 */
132static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, 139static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
133 struct pci_dev *pdev, 140 struct pci_dev *pdev,
134 int bus_prom_node) 141 struct device_node *bus_node)
135{ 142{
136 struct linux_prom_pci_registers pregs[PROMREG_MAX]; 143 struct linux_prom_pci_registers *pregs = NULL;
137 struct pcidev_cookie *pcp; 144 struct pcidev_cookie *pcp;
138 int device_prom_node, nregs, err; 145 struct device_node *dp;
146 struct property *prop;
147 int nregs, len;
139 148
140 device_prom_node = find_device_prom_node(pbm, pdev, bus_prom_node, 149 dp = find_device_prom_node(pbm, pdev, bus_node,
141 pregs, &nregs); 150 &pregs, &nregs);
142 if (device_prom_node == 0) { 151 if (!dp) {
143 /* If it is not in the OBP device tree then 152 /* If it is not in the OBP device tree then
144 * there must be a damn good reason for it. 153 * there must be a damn good reason for it.
145 * 154 *
@@ -153,45 +162,43 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
153 return; 162 return;
154 } 163 }
155 164
156 pcp = kmalloc(sizeof(*pcp), GFP_ATOMIC); 165 pcp = kzalloc(sizeof(*pcp), GFP_ATOMIC);
157 if (pcp == NULL) { 166 if (pcp == NULL) {
158 prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n"); 167 prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n");
159 prom_halt(); 168 prom_halt();
160 } 169 }
161 pcp->pbm = pbm; 170 pcp->pbm = pbm;
162 pcp->prom_node = device_prom_node; 171 pcp->prom_node = dp;
163 memcpy(pcp->prom_regs, pregs, sizeof(pcp->prom_regs)); 172 memcpy(pcp->prom_regs, pregs,
173 nregs * sizeof(struct linux_prom_pci_registers));
164 pcp->num_prom_regs = nregs; 174 pcp->num_prom_regs = nregs;
165 err = prom_getproperty(device_prom_node, "name", 175
166 pcp->prom_name, sizeof(pcp->prom_name)); 176 /* We can't have the pcidev_cookie assignments be just
167 if (err > 0) 177 * direct pointers into the property value, since they
168 pcp->prom_name[err] = 0; 178 * are potentially modified by the probing process.
169 else 179 */
170 pcp->prom_name[0] = 0; 180 prop = of_find_property(dp, "assigned-addresses", &len);
171 181 if (!prop) {
172 err = prom_getproperty(device_prom_node,
173 "assigned-addresses",
174 (char *)pcp->prom_assignments,
175 sizeof(pcp->prom_assignments));
176 if (err == 0 || err == -1)
177 pcp->num_prom_assignments = 0; 182 pcp->num_prom_assignments = 0;
178 else 183 } else {
184 memcpy(pcp->prom_assignments, prop->value, len);
179 pcp->num_prom_assignments = 185 pcp->num_prom_assignments =
180 (err / sizeof(pcp->prom_assignments[0])); 186 (len / sizeof(pcp->prom_assignments[0]));
187 }
181 188
182 if (strcmp(pcp->prom_name, "ebus") == 0) { 189 if (strcmp(dp->name, "ebus") == 0) {
183 struct linux_prom_ebus_ranges erng[PROM_PCIRNG_MAX]; 190 struct linux_prom_ebus_ranges *erng;
184 int iter; 191 int iter;
185 192
186 /* EBUS is special... */ 193 /* EBUS is special... */
187 err = prom_getproperty(device_prom_node, "ranges", 194 prop = of_find_property(dp, "ranges", &len);
188 (char *)&erng[0], sizeof(erng)); 195 if (!prop) {
189 if (err == 0 || err == -1) {
190 prom_printf("EBUS: Fatal error, no range property\n"); 196 prom_printf("EBUS: Fatal error, no range property\n");
191 prom_halt(); 197 prom_halt();
192 } 198 }
193 err = (err / sizeof(erng[0])); 199 erng = prop->value;
194 for(iter = 0; iter < err; iter++) { 200 len = (len / sizeof(erng[0]));
201 for (iter = 0; iter < len; iter++) {
195 struct linux_prom_ebus_ranges *ep = &erng[iter]; 202 struct linux_prom_ebus_ranges *ep = &erng[iter];
196 struct linux_prom_pci_registers *ap; 203 struct linux_prom_pci_registers *ap;
197 204
@@ -203,7 +210,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
203 ap->size_hi = 0; 210 ap->size_hi = 0;
204 ap->size_lo = ep->size; 211 ap->size_lo = ep->size;
205 } 212 }
206 pcp->num_prom_assignments = err; 213 pcp->num_prom_assignments = len;
207 } 214 }
208 215
209 fixup_obp_assignments(pdev, pcp); 216 fixup_obp_assignments(pdev, pcp);
@@ -213,7 +220,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
213 220
214void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus, 221void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
215 struct pci_pbm_info *pbm, 222 struct pci_pbm_info *pbm,
216 int prom_node) 223 struct device_node *dp)
217{ 224{
218 struct pci_dev *pdev, *pdev_next; 225 struct pci_dev *pdev, *pdev_next;
219 struct pci_bus *this_pbus, *pbus_next; 226 struct pci_bus *this_pbus, *pbus_next;
@@ -221,7 +228,7 @@ void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
221 /* This must be _safe because the cookie fillin 228 /* This must be _safe because the cookie fillin
222 routine can delete devices from the tree. */ 229 routine can delete devices from the tree. */
223 list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list) 230 list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list)
224 pdev_cookie_fillin(pbm, pdev, prom_node); 231 pdev_cookie_fillin(pbm, pdev, dp);
225 232
226 list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) { 233 list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) {
227 struct pcidev_cookie *pcp = this_pbus->self->sysdata; 234 struct pcidev_cookie *pcp = this_pbus->self->sysdata;
@@ -244,7 +251,6 @@ static void __init bad_assignment(struct pci_dev *pdev,
244 if (res) 251 if (res)
245 prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n", 252 prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n",
246 res->start, res->end, res->flags); 253 res->start, res->end, res->flags);
247 prom_printf("Please email this information to davem@redhat.com\n");
248 if (do_prom_halt) 254 if (do_prom_halt)
249 prom_halt(); 255 prom_halt();
250} 256}
@@ -276,8 +282,7 @@ __init get_root_resource(struct linux_prom_pci_registers *ap,
276 return &pbm->mem_space; 282 return &pbm->mem_space;
277 283
278 default: 284 default:
279 printk("PCI: What is resource space %x? " 285 printk("PCI: What is resource space %x?\n", space);
280 "Tell davem@redhat.com about it!\n", space);
281 return NULL; 286 return NULL;
282 }; 287 };
283} 288}
@@ -572,50 +577,51 @@ static inline unsigned int pci_apply_intmap(struct pci_pbm_info *pbm,
572 struct pci_dev *pbus, 577 struct pci_dev *pbus,
573 struct pci_dev *pdev, 578 struct pci_dev *pdev,
574 unsigned int interrupt, 579 unsigned int interrupt,
575 unsigned int *cnode) 580 struct device_node **cnode)
576{ 581{
577 struct linux_prom_pci_intmap imap[PROM_PCIIMAP_MAX]; 582 struct linux_prom_pci_intmap *imap;
578 struct linux_prom_pci_intmask imask; 583 struct linux_prom_pci_intmask *imask;
579 struct pcidev_cookie *pbus_pcp = pbus->sysdata; 584 struct pcidev_cookie *pbus_pcp = pbus->sysdata;
580 struct pcidev_cookie *pdev_pcp = pdev->sysdata; 585 struct pcidev_cookie *pdev_pcp = pdev->sysdata;
581 struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs; 586 struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs;
587 struct property *prop;
582 int plen, num_imap, i; 588 int plen, num_imap, i;
583 unsigned int hi, mid, lo, irq, orig_interrupt; 589 unsigned int hi, mid, lo, irq, orig_interrupt;
584 590
585 *cnode = pbus_pcp->prom_node; 591 *cnode = pbus_pcp->prom_node;
586 592
587 plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map", 593 prop = of_find_property(pbus_pcp->prom_node, "interrupt-map", &plen);
588 (char *) &imap[0], sizeof(imap)); 594 if (!prop ||
589 if (plen <= 0 ||
590 (plen % sizeof(struct linux_prom_pci_intmap)) != 0) { 595 (plen % sizeof(struct linux_prom_pci_intmap)) != 0) {
591 printk("%s: Device %s interrupt-map has bad len %d\n", 596 printk("%s: Device %s interrupt-map has bad len %d\n",
592 pbm->name, pci_name(pbus), plen); 597 pbm->name, pci_name(pbus), plen);
593 goto no_intmap; 598 goto no_intmap;
594 } 599 }
600 imap = prop->value;
595 num_imap = plen / sizeof(struct linux_prom_pci_intmap); 601 num_imap = plen / sizeof(struct linux_prom_pci_intmap);
596 602
597 plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map-mask", 603 prop = of_find_property(pbus_pcp->prom_node, "interrupt-map-mask", &plen);
598 (char *) &imask, sizeof(imask)); 604 if (!prop ||
599 if (plen <= 0 ||
600 (plen % sizeof(struct linux_prom_pci_intmask)) != 0) { 605 (plen % sizeof(struct linux_prom_pci_intmask)) != 0) {
601 printk("%s: Device %s interrupt-map-mask has bad len %d\n", 606 printk("%s: Device %s interrupt-map-mask has bad len %d\n",
602 pbm->name, pci_name(pbus), plen); 607 pbm->name, pci_name(pbus), plen);
603 goto no_intmap; 608 goto no_intmap;
604 } 609 }
610 imask = prop->value;
605 611
606 orig_interrupt = interrupt; 612 orig_interrupt = interrupt;
607 613
608 hi = pregs->phys_hi & imask.phys_hi; 614 hi = pregs->phys_hi & imask->phys_hi;
609 mid = pregs->phys_mid & imask.phys_mid; 615 mid = pregs->phys_mid & imask->phys_mid;
610 lo = pregs->phys_lo & imask.phys_lo; 616 lo = pregs->phys_lo & imask->phys_lo;
611 irq = interrupt & imask.interrupt; 617 irq = interrupt & imask->interrupt;
612 618
613 for (i = 0; i < num_imap; i++) { 619 for (i = 0; i < num_imap; i++) {
614 if (imap[i].phys_hi == hi && 620 if (imap[i].phys_hi == hi &&
615 imap[i].phys_mid == mid && 621 imap[i].phys_mid == mid &&
616 imap[i].phys_lo == lo && 622 imap[i].phys_lo == lo &&
617 imap[i].interrupt == irq) { 623 imap[i].interrupt == irq) {
618 *cnode = imap[i].cnode; 624 *cnode = of_find_node_by_phandle(imap[i].cnode);
619 interrupt = imap[i].cinterrupt; 625 interrupt = imap[i].cinterrupt;
620 } 626 }
621 } 627 }
@@ -638,21 +644,22 @@ no_intmap:
638 * all interrupt translations are complete, else we should use that node's 644 * all interrupt translations are complete, else we should use that node's
639 * "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt. 645 * "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt.
640 */ 646 */
641static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm, 647static struct device_node * __init
642 struct pci_dev *pdev, 648pci_intmap_match_to_root(struct pci_pbm_info *pbm,
643 unsigned int *interrupt) 649 struct pci_dev *pdev,
650 unsigned int *interrupt)
644{ 651{
645 struct pci_dev *toplevel_pdev = pdev; 652 struct pci_dev *toplevel_pdev = pdev;
646 struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata; 653 struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata;
647 unsigned int cnode = toplevel_pcp->prom_node; 654 struct device_node *cnode = toplevel_pcp->prom_node;
648 655
649 while (pdev->bus->number != pbm->pci_first_busno) { 656 while (pdev->bus->number != pbm->pci_first_busno) {
650 struct pci_dev *pbus = pdev->bus->self; 657 struct pci_dev *pbus = pdev->bus->self;
651 struct pcidev_cookie *pcp = pbus->sysdata; 658 struct pcidev_cookie *pcp = pbus->sysdata;
652 int plen; 659 struct property *prop;
653 660
654 plen = prom_getproplen(pcp->prom_node, "interrupt-map"); 661 prop = of_find_property(pcp->prom_node, "interrupt-map", NULL);
655 if (plen <= 0) { 662 if (!prop) {
656 *interrupt = pci_slot_swivel(pbm, toplevel_pdev, 663 *interrupt = pci_slot_swivel(pbm, toplevel_pdev,
657 pdev, *interrupt); 664 pdev, *interrupt);
658 cnode = pcp->prom_node; 665 cnode = pcp->prom_node;
@@ -669,7 +676,7 @@ static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm,
669 } 676 }
670 pdev = pbus; 677 pdev = pbus;
671 678
672 if (cnode == pbm->prom_node->node) 679 if (cnode == pbm->prom_node)
673 break; 680 break;
674 } 681 }
675 682
@@ -680,21 +687,24 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
680{ 687{
681 struct pcidev_cookie *dev_pcp = pdev->sysdata; 688 struct pcidev_cookie *dev_pcp = pdev->sysdata;
682 struct pci_pbm_info *pbm = dev_pcp->pbm; 689 struct pci_pbm_info *pbm = dev_pcp->pbm;
683 struct linux_prom_pci_registers reg[PROMREG_MAX]; 690 struct linux_prom_pci_registers *reg;
691 struct device_node *cnode;
692 struct property *prop;
684 unsigned int hi, mid, lo, irq; 693 unsigned int hi, mid, lo, irq;
685 int i, cnode, plen; 694 int i, plen;
686 695
687 cnode = pci_intmap_match_to_root(pbm, pdev, interrupt); 696 cnode = pci_intmap_match_to_root(pbm, pdev, interrupt);
688 if (cnode == pbm->prom_node->node) 697 if (cnode == pbm->prom_node)
689 goto success; 698 goto success;
690 699
691 plen = prom_getproperty(cnode, "reg", (char *) reg, sizeof(reg)); 700 prop = of_find_property(cnode, "reg", &plen);
692 if (plen <= 0 || 701 if (!prop ||
693 (plen % sizeof(struct linux_prom_pci_registers)) != 0) { 702 (plen % sizeof(struct linux_prom_pci_registers)) != 0) {
694 printk("%s: OBP node %x reg property has bad len %d\n", 703 printk("%s: OBP node %s reg property has bad len %d\n",
695 pbm->name, cnode, plen); 704 pbm->name, cnode->full_name, plen);
696 goto fail; 705 goto fail;
697 } 706 }
707 reg = prop->value;
698 708
699 hi = reg[0].phys_hi & pbm->pbm_intmask->phys_hi; 709 hi = reg[0].phys_hi & pbm->pbm_intmask->phys_hi;
700 mid = reg[0].phys_mid & pbm->pbm_intmask->phys_mid; 710 mid = reg[0].phys_mid & pbm->pbm_intmask->phys_mid;
@@ -734,8 +744,8 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
734 struct pci_controller_info *p = pbm->parent; 744 struct pci_controller_info *p = pbm->parent;
735 unsigned int portid = pbm->portid; 745 unsigned int portid = pbm->portid;
736 unsigned int prom_irq; 746 unsigned int prom_irq;
737 int prom_node = pcp->prom_node; 747 struct device_node *dp = pcp->prom_node;
738 int err; 748 struct property *prop;
739 749
740 /* If this is an empty EBUS device, sometimes OBP fails to 750 /* If this is an empty EBUS device, sometimes OBP fails to
741 * give it a valid fully specified interrupts property. 751 * give it a valid fully specified interrupts property.
@@ -746,17 +756,17 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
746 */ 756 */
747 if (pdev->vendor == PCI_VENDOR_ID_SUN && 757 if (pdev->vendor == PCI_VENDOR_ID_SUN &&
748 pdev->device == PCI_DEVICE_ID_SUN_EBUS && 758 pdev->device == PCI_DEVICE_ID_SUN_EBUS &&
749 !prom_getchild(prom_node)) { 759 !dp->child) {
750 pdev->irq = 0; 760 pdev->irq = 0;
751 return; 761 return;
752 } 762 }
753 763
754 err = prom_getproperty(prom_node, "interrupts", 764 prop = of_find_property(dp, "interrupts", NULL);
755 (char *)&prom_irq, sizeof(prom_irq)); 765 if (!prop) {
756 if (err == 0 || err == -1) {
757 pdev->irq = 0; 766 pdev->irq = 0;
758 return; 767 return;
759 } 768 }
769 prom_irq = *(unsigned int *) prop->value;
760 770
761 if (tlb_type != hypervisor) { 771 if (tlb_type != hypervisor) {
762 /* Fully specified already? */ 772 /* Fully specified already? */
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h
index 6c3205962544..971e2bea30b4 100644
--- a/arch/sparc64/kernel/pci_impl.h
+++ b/arch/sparc64/kernel/pci_impl.h
@@ -10,6 +10,7 @@
10#include <linux/types.h> 10#include <linux/types.h>
11#include <linux/spinlock.h> 11#include <linux/spinlock.h>
12#include <asm/io.h> 12#include <asm/io.h>
13#include <asm/prom.h>
13 14
14extern struct pci_controller_info *pci_controller_root; 15extern struct pci_controller_info *pci_controller_root;
15 16
@@ -19,7 +20,7 @@ extern int pci_num_controllers;
19extern void pci_fixup_host_bridge_self(struct pci_bus *pbus); 20extern void pci_fixup_host_bridge_self(struct pci_bus *pbus);
20extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus, 21extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus,
21 struct pci_pbm_info *pbm, 22 struct pci_pbm_info *pbm,
22 int prom_node); 23 struct device_node *prom_node);
23extern void pci_record_assignments(struct pci_pbm_info *pbm, 24extern void pci_record_assignments(struct pci_pbm_info *pbm,
24 struct pci_bus *pbus); 25 struct pci_bus *pbus);
25extern void pci_assign_unassigned(struct pci_pbm_info *pbm, 26extern void pci_assign_unassigned(struct pci_pbm_info *pbm,
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 40c2b6819983..5b2261ebda6f 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1104,7 +1104,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
1104 pci_fixup_host_bridge_self(pbm->pci_bus); 1104 pci_fixup_host_bridge_self(pbm->pci_bus);
1105 pbm->pci_bus->self->sysdata = cookie; 1105 pbm->pci_bus->self->sysdata = cookie;
1106 1106
1107 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node); 1107 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
1108 pci_record_assignments(pbm, pbm->pci_bus); 1108 pci_record_assignments(pbm, pbm->pci_bus);
1109 pci_assign_unassigned(pbm, pbm->pci_bus); 1109 pci_assign_unassigned(pbm, pbm->pci_bus);
1110 pci_fixup_irq(pbm, pbm->pci_bus); 1110 pci_fixup_irq(pbm, pbm->pci_bus);
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 4ce7b4620c09..26f194ce4400 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -1161,7 +1161,7 @@ static void sabre_scan_bus(struct pci_controller_info *p)
1161 1161
1162 pbus->sysdata = pbm; 1162 pbus->sysdata = pbm;
1163 pbm->pci_bus = pbus; 1163 pbm->pci_bus = pbus;
1164 pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node->node); 1164 pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node);
1165 pci_record_assignments(pbm, pbus); 1165 pci_record_assignments(pbm, pbus);
1166 pci_assign_unassigned(pbm, pbus); 1166 pci_assign_unassigned(pbm, pbus);
1167 pci_fixup_irq(pbm, pbus); 1167 pci_fixup_irq(pbm, pbus);
@@ -1174,7 +1174,7 @@ static void sabre_scan_bus(struct pci_controller_info *p)
1174 pbm = &p->pbm_A; 1174 pbm = &p->pbm_A;
1175 sabre_bus->sysdata = pbm; 1175 sabre_bus->sysdata = pbm;
1176 pbm->pci_bus = sabre_bus; 1176 pbm->pci_bus = sabre_bus;
1177 pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node->node); 1177 pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node);
1178 pci_record_assignments(pbm, sabre_bus); 1178 pci_record_assignments(pbm, sabre_bus);
1179 pci_assign_unassigned(pbm, sabre_bus); 1179 pci_assign_unassigned(pbm, sabre_bus);
1180 pci_fixup_irq(pbm, sabre_bus); 1180 pci_fixup_irq(pbm, sabre_bus);
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index d26820086843..f16449ccd7bc 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -1438,7 +1438,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
1438 pci_fixup_host_bridge_self(pbm->pci_bus); 1438 pci_fixup_host_bridge_self(pbm->pci_bus);
1439 pbm->pci_bus->self->sysdata = cookie; 1439 pbm->pci_bus->self->sysdata = cookie;
1440 1440
1441 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node); 1441 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
1442 pci_record_assignments(pbm, pbm->pci_bus); 1442 pci_record_assignments(pbm, pbm->pci_bus);
1443 pci_assign_unassigned(pbm, pbm->pci_bus); 1443 pci_assign_unassigned(pbm, pbm->pci_bus);
1444 pci_fixup_irq(pbm, pbm->pci_bus); 1444 pci_fixup_irq(pbm, pbm->pci_bus);
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index b275c7df0186..b69e2270a721 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -814,8 +814,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
814 pci_fixup_host_bridge_self(pbm->pci_bus); 814 pci_fixup_host_bridge_self(pbm->pci_bus);
815 pbm->pci_bus->self->sysdata = cookie; 815 pbm->pci_bus->self->sysdata = cookie;
816#endif 816#endif
817 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, 817 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
818 pbm->prom_node->node);
819 pci_record_assignments(pbm, pbm->pci_bus); 818 pci_record_assignments(pbm, pbm->pci_bus);
820 pci_assign_unassigned(pbm, pbm->pci_bus); 819 pci_assign_unassigned(pbm, pbm->pci_bus);
821 pci_fixup_irq(pbm, pbm->pci_bus); 820 pci_fixup_irq(pbm, pbm->pci_bus);
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 0a32b1064dfb..fb112c3c0485 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -20,6 +20,7 @@
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/bootmem.h> 22#include <linux/bootmem.h>
23#include <linux/module.h>
23 24
24#include <asm/prom.h> 25#include <asm/prom.h>
25#include <asm/oplib.h> 26#include <asm/oplib.h>
@@ -63,6 +64,17 @@ struct device_node *of_find_node_by_path(const char *path)
63 return np; 64 return np;
64} 65}
65 66
67struct device_node *of_find_node_by_phandle(phandle handle)
68{
69 struct device_node *np;
70
71 for (np = allnodes; np != 0; np = np->allnext)
72 if (np->node == handle)
73 break;
74
75 return np;
76}
77
66struct device_node *of_find_node_by_name(struct device_node *from, 78struct device_node *of_find_node_by_name(struct device_node *from,
67 const char *name) 79 const char *name)
68{ 80{
@@ -103,6 +115,18 @@ struct property *of_find_property(struct device_node *np, const char *name,
103 } 115 }
104 return pp; 116 return pp;
105} 117}
118EXPORT_SYMBOL(of_find_property);
119
120/*
121 * Find a property with a given name for a given node
122 * and return the value.
123 */
124void *of_get_property(struct device_node *np, const char *name, int *lenp)
125{
126 struct property *pp = of_find_property(np,name,lenp);
127 return pp ? pp->value : NULL;
128}
129EXPORT_SYMBOL(of_get_property);
106 130
107int of_getintprop_default(struct device_node *np, const char *name, int def) 131int of_getintprop_default(struct device_node *np, const char *name, int def)
108{ 132{
@@ -115,6 +139,7 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
115 139
116 return *(int *) prop->value; 140 return *(int *) prop->value;
117} 141}
142EXPORT_SYMBOL(of_getintprop_default);
118 143
119static unsigned int prom_early_allocated; 144static unsigned int prom_early_allocated;
120 145
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 38cd30cb7c75..5248670d29f7 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2880,17 +2880,20 @@ static int __devinit gem_get_device_address(struct gem *gp)
2880#if defined(__sparc__) 2880#if defined(__sparc__)
2881 struct pci_dev *pdev = gp->pdev; 2881 struct pci_dev *pdev = gp->pdev;
2882 struct pcidev_cookie *pcp = pdev->sysdata; 2882 struct pcidev_cookie *pcp = pdev->sysdata;
2883 int node = -1; 2883 int use_idprom = 1;
2884 2884
2885 if (pcp != NULL) { 2885 if (pcp != NULL) {
2886 node = pcp->prom_node; 2886 unsigned char *addr;
2887 if (prom_getproplen(node, "local-mac-address") == 6) 2887 int len;
2888 prom_getproperty(node, "local-mac-address", 2888
2889 dev->dev_addr, 6); 2889 addr = of_get_property(pcp->prom_node, "local-mac-address",
2890 else 2890 &len);
2891 node = -1; 2891 if (addr && len == 6) {
2892 use_idprom = 0;
2893 memcpy(dev->dev_addr, addr, 6);
2894 }
2892 } 2895 }
2893 if (node == -1) 2896 if (use_idprom)
2894 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 2897 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
2895#elif defined(CONFIG_PPC_PMAC) 2898#elif defined(CONFIG_PPC_PMAC)
2896 unsigned char *addr; 2899 unsigned char *addr;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index bd5d2668a362..b0d452733c9b 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -3013,7 +3013,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3013 struct quattro *qp = NULL; 3013 struct quattro *qp = NULL;
3014#ifdef __sparc__ 3014#ifdef __sparc__
3015 struct pcidev_cookie *pcp; 3015 struct pcidev_cookie *pcp;
3016 int node;
3017#endif 3016#endif
3018 struct happy_meal *hp; 3017 struct happy_meal *hp;
3019 struct net_device *dev; 3018 struct net_device *dev;
@@ -3026,13 +3025,12 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3026 /* Now make sure pci_dev cookie is there. */ 3025 /* Now make sure pci_dev cookie is there. */
3027#ifdef __sparc__ 3026#ifdef __sparc__
3028 pcp = pdev->sysdata; 3027 pcp = pdev->sysdata;
3029 if (pcp == NULL || pcp->prom_node == -1) { 3028 if (pcp == NULL) {
3030 printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); 3029 printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n");
3031 return -ENODEV; 3030 return -ENODEV;
3032 } 3031 }
3033 node = pcp->prom_node;
3034 3032
3035 prom_getstring(node, "name", prom_name, sizeof(prom_name)); 3033 strcpy(prom_name, pcp->prom_node->name);
3036#else 3034#else
3037 if (is_quattro_p(pdev)) 3035 if (is_quattro_p(pdev))
3038 strcpy(prom_name, "SUNW,qfe"); 3036 strcpy(prom_name, "SUNW,qfe");
@@ -3104,10 +3102,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3104 macaddr[5]++; 3102 macaddr[5]++;
3105 } else { 3103 } else {
3106#ifdef __sparc__ 3104#ifdef __sparc__
3105 unsigned char *addr;
3106 int len;
3107
3107 if (qfe_slot != -1 && 3108 if (qfe_slot != -1 &&
3108 prom_getproplen(node, "local-mac-address") == 6) { 3109 (addr = of_get_property(pcp->prom_node,
3109 prom_getproperty(node, "local-mac-address", 3110 "local-mac-address", &len)) != NULL
3110 dev->dev_addr, 6); 3111 && len == 6) {
3112 memcpy(dev->dev_addr, addr, 6);
3111 } else { 3113 } else {
3112 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 3114 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
3113 } 3115 }
@@ -3124,7 +3126,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3124 hp->tcvregs = (hpreg_base + 0x7000UL); 3126 hp->tcvregs = (hpreg_base + 0x7000UL);
3125 3127
3126#ifdef __sparc__ 3128#ifdef __sparc__
3127 hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); 3129 hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff);
3128 if (hp->hm_revision == 0xff) { 3130 if (hp->hm_revision == 0xff) {
3129 unsigned char prev; 3131 unsigned char prev;
3130 3132
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e3e380f90f86..35f931638750 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10549,11 +10549,13 @@ static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp)
10549 struct pcidev_cookie *pcp = pdev->sysdata; 10549 struct pcidev_cookie *pcp = pdev->sysdata;
10550 10550
10551 if (pcp != NULL) { 10551 if (pcp != NULL) {
10552 int node = pcp->prom_node; 10552 unsigned char *addr;
10553 int len;
10553 10554
10554 if (prom_getproplen(node, "local-mac-address") == 6) { 10555 addr = of_get_property(pcp->prom_node, "local-mac-address",
10555 prom_getproperty(node, "local-mac-address", 10556 &len);
10556 dev->dev_addr, 6); 10557 if (addr && len == 6) {
10558 memcpy(dev->dev_addr, addr, 6);
10557 memcpy(dev->perm_addr, dev->dev_addr, 6); 10559 memcpy(dev->perm_addr, dev->dev_addr, 6);
10558 return 0; 10560 return 0;
10559 } 10561 }
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index cabdf894e21e..e0de66739a42 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1550,10 +1550,14 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
1550 dev->dev_addr[i] = last_phys_addr[i]; 1550 dev->dev_addr[i] = last_phys_addr[i];
1551 dev->dev_addr[i] = last_phys_addr[i] + 1; 1551 dev->dev_addr[i] = last_phys_addr[i] + 1;
1552#if defined(__sparc__) 1552#if defined(__sparc__)
1553 if ((pcp != NULL) && prom_getproplen(pcp->prom_node, 1553 if (pcp) {
1554 "local-mac-address") == 6) { 1554 unsigned char *addr;
1555 prom_getproperty(pcp->prom_node, "local-mac-address", 1555 int len;
1556 dev->dev_addr, 6); 1556
1557 addr = of_get_property(pcp->prom_node,
1558 "local-mac-address", &len);
1559 if (addr && len == 6)
1560 memcpy(dev->dev_addr, addr, 6);
1557 } 1561 }
1558#endif 1562#endif
1559#if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */ 1563#if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 239e108b8ed1..cf5b476b5496 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -243,8 +243,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
243 ((int *) opp->oprom_array)[1]); 243 ((int *) opp->oprom_array)[1]);
244 244
245 pcp = pdev->sysdata; 245 pcp = pdev->sysdata;
246 if (pcp != NULL && pcp->prom_node != -1 && pcp->prom_node) { 246 if (pcp != NULL) {
247 node = pcp->prom_node; 247 node = pcp->prom_node->node;
248 data->current_node = node; 248 data->current_node = node;
249 *((int *)opp->oprom_array) = node; 249 *((int *)opp->oprom_array) = node;
250 opp->oprom_size = sizeof(int); 250 opp->oprom_size = sizeof(int);
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index eb6aa42be60e..c054bb28b1c4 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2966,7 +2966,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2966 } 2966 }
2967 2967
2968 pcp = pdev->sysdata; 2968 pcp = pdev->sysdata;
2969 if (node == pcp->prom_node) { 2969 if (node == pcp->prom_node->node) {
2970 struct fb_var_screeninfo *var = &default_var; 2970 struct fb_var_screeninfo *var = &default_var;
2971 unsigned int N, P, Q, M, T, R; 2971 unsigned int N, P, Q, M, T, R;
2972 u32 v_total, h_total; 2972 u32 v_total, h_total;
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
index 142cc4028bb8..cebe80b1da6c 100644
--- a/include/asm-sparc64/pbm.h
+++ b/include/asm-sparc64/pbm.h
@@ -227,8 +227,7 @@ struct pci_controller_info {
227 */ 227 */
228struct pcidev_cookie { 228struct pcidev_cookie {
229 struct pci_pbm_info *pbm; 229 struct pci_pbm_info *pbm;
230 char prom_name[64]; 230 struct device_node *prom_node;
231 int prom_node;
232 struct linux_prom_pci_registers prom_regs[PROMREG_MAX]; 231 struct linux_prom_pci_registers prom_regs[PROMREG_MAX];
233 int num_prom_regs; 232 int num_prom_regs;
234 struct linux_prom_pci_registers prom_assignments[PROMREG_MAX]; 233 struct linux_prom_pci_registers prom_assignments[PROMREG_MAX];
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h
index d0187b3a0ec3..062ae6e1212e 100644
--- a/include/asm-sparc64/prom.h
+++ b/include/asm-sparc64/prom.h
@@ -76,12 +76,15 @@ extern struct device_node *of_find_node_by_type(struct device_node *from,
76 for (dn = of_find_node_by_type(NULL, type); dn; \ 76 for (dn = of_find_node_by_type(NULL, type); dn; \
77 dn = of_find_node_by_type(dn, type)) 77 dn = of_find_node_by_type(dn, type))
78extern struct device_node *of_find_node_by_path(const char *path); 78extern struct device_node *of_find_node_by_path(const char *path);
79extern struct device_node *of_find_node_by_phandle(phandle handle);
79extern struct device_node *of_get_parent(const struct device_node *node); 80extern struct device_node *of_get_parent(const struct device_node *node);
80extern struct device_node *of_get_next_child(const struct device_node *node, 81extern struct device_node *of_get_next_child(const struct device_node *node,
81 struct device_node *prev); 82 struct device_node *prev);
82extern struct property *of_find_property(struct device_node *np, 83extern struct property *of_find_property(struct device_node *np,
83 const char *name, 84 const char *name,
84 int *lenp); 85 int *lenp);
86extern void *of_get_property(struct device_node *node, const char *name,
87 int *lenp);
85extern int of_getintprop_default(struct device_node *np, 88extern int of_getintprop_default(struct device_node *np,
86 const char *name, 89 const char *name,
87 int def); 90 int def);