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