diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-10 11:57:03 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-10 11:57:03 -0500 |
commit | 0bd2cbcdfaff9cb22267d66fc843fa4f73f0c281 (patch) | |
tree | 7d9732bcf5f2f646cb0c2c529c48b454b15d4ae2 /drivers/of | |
parent | 57cc7215b70856dc6bae8e55b00ecd7b1d7429b1 (diff) | |
parent | a081748735c5feb96b1365e78a5ff0fb6ca7e3a4 (diff) |
Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
* 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6: (29 commits)
of/flattree: forward declare struct device_node in of_fdt.h
ipmi: explicitly include of_address.h and of_irq.h
sparc: explicitly cast negative phandle checks to s32
powerpc/405: Fix missing #{address,size}-cells in i2c node
powerpc/5200: dts: refactor dts files
powerpc/5200: dts: Change combatible strings on localbus
powerpc/5200: dts: remove unused properties
powerpc/5200: dts: rename nodes to prepare for refactoring dts files
of/flattree: Update dtc to current mainline.
of/device: Don't register disabled devices
powerpc/dts: fix syntax bugs in bluestone.dts
of: Fixes for OF probing on little endian systems
of: make drivers depend on CONFIG_OF instead of CONFIG_PPC_OF
of/flattree: Add of_flat_dt_match() helper function
of_serial: explicitly include of_irq.h
of/flattree: Refactor unflatten_device_tree and add fdt_unflatten_tree
of/flattree: Reorder unflatten_dt_node
of/flattree: Refactor unflatten_dt_node
of/flattree: Add non-boottime device tree functions
of/flattree: Add Kconfig for EARLY_FLATTREE
...
Fix up trivial conflict in arch/sparc/prom/tree_32.c as per Grant.
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/Kconfig | 8 | ||||
-rw-r--r-- | drivers/of/Makefile | 1 | ||||
-rw-r--r-- | drivers/of/address.c | 54 | ||||
-rw-r--r-- | drivers/of/fdt.c | 430 | ||||
-rw-r--r-- | drivers/of/of_mdio.c | 26 | ||||
-rw-r--r-- | drivers/of/of_net.c | 48 | ||||
-rw-r--r-- | drivers/of/platform.c | 22 |
7 files changed, 388 insertions, 201 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index aa675ebd8eb3..3c6e100a3ad0 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
@@ -19,6 +19,10 @@ config OF_FLATTREE | |||
19 | bool | 19 | bool |
20 | select DTC | 20 | select DTC |
21 | 21 | ||
22 | config OF_EARLY_FLATTREE | ||
23 | bool | ||
24 | select OF_FLATTREE | ||
25 | |||
22 | config OF_PROMTREE | 26 | config OF_PROMTREE |
23 | bool | 27 | bool |
24 | 28 | ||
@@ -49,6 +53,10 @@ config OF_I2C | |||
49 | help | 53 | help |
50 | OpenFirmware I2C accessors | 54 | OpenFirmware I2C accessors |
51 | 55 | ||
56 | config OF_NET | ||
57 | depends on NETDEVICES | ||
58 | def_bool y | ||
59 | |||
52 | config OF_SPI | 60 | config OF_SPI |
53 | def_tristate SPI | 61 | def_tristate SPI |
54 | depends on SPI && !SPARC | 62 | depends on SPI && !SPARC |
diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 7888155bea08..3ab21a0a4907 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile | |||
@@ -6,5 +6,6 @@ obj-$(CONFIG_OF_IRQ) += irq.o | |||
6 | obj-$(CONFIG_OF_DEVICE) += device.o platform.o | 6 | obj-$(CONFIG_OF_DEVICE) += device.o platform.o |
7 | obj-$(CONFIG_OF_GPIO) += gpio.o | 7 | obj-$(CONFIG_OF_GPIO) += gpio.o |
8 | obj-$(CONFIG_OF_I2C) += of_i2c.o | 8 | obj-$(CONFIG_OF_I2C) += of_i2c.o |
9 | obj-$(CONFIG_OF_NET) += of_net.o | ||
9 | obj-$(CONFIG_OF_SPI) += of_spi.o | 10 | obj-$(CONFIG_OF_SPI) += of_spi.o |
10 | obj-$(CONFIG_OF_MDIO) += of_mdio.o | 11 | obj-$(CONFIG_OF_MDIO) += of_mdio.o |
diff --git a/drivers/of/address.c b/drivers/of/address.c index 3a1c7e70b192..b4559c58c095 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -12,13 +12,13 @@ | |||
12 | (ns) > 0) | 12 | (ns) > 0) |
13 | 13 | ||
14 | static struct of_bus *of_match_bus(struct device_node *np); | 14 | static struct of_bus *of_match_bus(struct device_node *np); |
15 | static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, | 15 | static int __of_address_to_resource(struct device_node *dev, |
16 | u64 size, unsigned int flags, | 16 | const __be32 *addrp, u64 size, unsigned int flags, |
17 | struct resource *r); | 17 | struct resource *r); |
18 | 18 | ||
19 | /* Debug utility */ | 19 | /* Debug utility */ |
20 | #ifdef DEBUG | 20 | #ifdef DEBUG |
21 | static void of_dump_addr(const char *s, const u32 *addr, int na) | 21 | static void of_dump_addr(const char *s, const __be32 *addr, int na) |
22 | { | 22 | { |
23 | printk(KERN_DEBUG "%s", s); | 23 | printk(KERN_DEBUG "%s", s); |
24 | while (na--) | 24 | while (na--) |
@@ -26,7 +26,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na) | |||
26 | printk("\n"); | 26 | printk("\n"); |
27 | } | 27 | } |
28 | #else | 28 | #else |
29 | static void of_dump_addr(const char *s, const u32 *addr, int na) { } | 29 | static void of_dump_addr(const char *s, const __be32 *addr, int na) { } |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | /* Callbacks for bus specific translators */ | 32 | /* Callbacks for bus specific translators */ |
@@ -36,10 +36,10 @@ struct of_bus { | |||
36 | int (*match)(struct device_node *parent); | 36 | int (*match)(struct device_node *parent); |
37 | void (*count_cells)(struct device_node *child, | 37 | void (*count_cells)(struct device_node *child, |
38 | int *addrc, int *sizec); | 38 | int *addrc, int *sizec); |
39 | u64 (*map)(u32 *addr, const u32 *range, | 39 | u64 (*map)(u32 *addr, const __be32 *range, |
40 | int na, int ns, int pna); | 40 | int na, int ns, int pna); |
41 | int (*translate)(u32 *addr, u64 offset, int na); | 41 | int (*translate)(u32 *addr, u64 offset, int na); |
42 | unsigned int (*get_flags)(const u32 *addr); | 42 | unsigned int (*get_flags)(const __be32 *addr); |
43 | }; | 43 | }; |
44 | 44 | ||
45 | /* | 45 | /* |
@@ -55,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev, | |||
55 | *sizec = of_n_size_cells(dev); | 55 | *sizec = of_n_size_cells(dev); |
56 | } | 56 | } |
57 | 57 | ||
58 | static u64 of_bus_default_map(u32 *addr, const u32 *range, | 58 | static u64 of_bus_default_map(u32 *addr, const __be32 *range, |
59 | int na, int ns, int pna) | 59 | int na, int ns, int pna) |
60 | { | 60 | { |
61 | u64 cp, s, da; | 61 | u64 cp, s, da; |
@@ -85,7 +85,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na) | |||
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
87 | 87 | ||
88 | static unsigned int of_bus_default_get_flags(const u32 *addr) | 88 | static unsigned int of_bus_default_get_flags(const __be32 *addr) |
89 | { | 89 | { |
90 | return IORESOURCE_MEM; | 90 | return IORESOURCE_MEM; |
91 | } | 91 | } |
@@ -110,10 +110,10 @@ static void of_bus_pci_count_cells(struct device_node *np, | |||
110 | *sizec = 2; | 110 | *sizec = 2; |
111 | } | 111 | } |
112 | 112 | ||
113 | static unsigned int of_bus_pci_get_flags(const u32 *addr) | 113 | static unsigned int of_bus_pci_get_flags(const __be32 *addr) |
114 | { | 114 | { |
115 | unsigned int flags = 0; | 115 | unsigned int flags = 0; |
116 | u32 w = addr[0]; | 116 | u32 w = be32_to_cpup(addr); |
117 | 117 | ||
118 | switch((w >> 24) & 0x03) { | 118 | switch((w >> 24) & 0x03) { |
119 | case 0x01: | 119 | case 0x01: |
@@ -129,7 +129,8 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr) | |||
129 | return flags; | 129 | return flags; |
130 | } | 130 | } |
131 | 131 | ||
132 | static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) | 132 | static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns, |
133 | int pna) | ||
133 | { | 134 | { |
134 | u64 cp, s, da; | 135 | u64 cp, s, da; |
135 | unsigned int af, rf; | 136 | unsigned int af, rf; |
@@ -160,7 +161,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | |||
160 | return of_bus_default_translate(addr + 1, offset, na - 1); | 161 | return of_bus_default_translate(addr + 1, offset, na - 1); |
161 | } | 162 | } |
162 | 163 | ||
163 | const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | 164 | const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, |
164 | unsigned int *flags) | 165 | unsigned int *flags) |
165 | { | 166 | { |
166 | const __be32 *prop; | 167 | const __be32 *prop; |
@@ -207,7 +208,7 @@ EXPORT_SYMBOL(of_get_pci_address); | |||
207 | int of_pci_address_to_resource(struct device_node *dev, int bar, | 208 | int of_pci_address_to_resource(struct device_node *dev, int bar, |
208 | struct resource *r) | 209 | struct resource *r) |
209 | { | 210 | { |
210 | const u32 *addrp; | 211 | const __be32 *addrp; |
211 | u64 size; | 212 | u64 size; |
212 | unsigned int flags; | 213 | unsigned int flags; |
213 | 214 | ||
@@ -237,12 +238,13 @@ static void of_bus_isa_count_cells(struct device_node *child, | |||
237 | *sizec = 1; | 238 | *sizec = 1; |
238 | } | 239 | } |
239 | 240 | ||
240 | static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) | 241 | static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns, |
242 | int pna) | ||
241 | { | 243 | { |
242 | u64 cp, s, da; | 244 | u64 cp, s, da; |
243 | 245 | ||
244 | /* Check address type match */ | 246 | /* Check address type match */ |
245 | if ((addr[0] ^ range[0]) & 0x00000001) | 247 | if ((addr[0] ^ range[0]) & cpu_to_be32(1)) |
246 | return OF_BAD_ADDR; | 248 | return OF_BAD_ADDR; |
247 | 249 | ||
248 | /* Read address values, skipping high cell */ | 250 | /* Read address values, skipping high cell */ |
@@ -264,10 +266,10 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | |||
264 | return of_bus_default_translate(addr + 1, offset, na - 1); | 266 | return of_bus_default_translate(addr + 1, offset, na - 1); |
265 | } | 267 | } |
266 | 268 | ||
267 | static unsigned int of_bus_isa_get_flags(const u32 *addr) | 269 | static unsigned int of_bus_isa_get_flags(const __be32 *addr) |
268 | { | 270 | { |
269 | unsigned int flags = 0; | 271 | unsigned int flags = 0; |
270 | u32 w = addr[0]; | 272 | u32 w = be32_to_cpup(addr); |
271 | 273 | ||
272 | if (w & 1) | 274 | if (w & 1) |
273 | flags |= IORESOURCE_IO; | 275 | flags |= IORESOURCE_IO; |
@@ -330,7 +332,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, | |||
330 | struct of_bus *pbus, u32 *addr, | 332 | struct of_bus *pbus, u32 *addr, |
331 | int na, int ns, int pna, const char *rprop) | 333 | int na, int ns, int pna, const char *rprop) |
332 | { | 334 | { |
333 | const u32 *ranges; | 335 | const __be32 *ranges; |
334 | unsigned int rlen; | 336 | unsigned int rlen; |
335 | int rone; | 337 | int rone; |
336 | u64 offset = OF_BAD_ADDR; | 338 | u64 offset = OF_BAD_ADDR; |
@@ -398,7 +400,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, | |||
398 | * that can be mapped to a cpu physical address). This is not really specified | 400 | * that can be mapped to a cpu physical address). This is not really specified |
399 | * that way, but this is traditionally the way IBM at least do things | 401 | * that way, but this is traditionally the way IBM at least do things |
400 | */ | 402 | */ |
401 | u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, | 403 | u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, |
402 | const char *rprop) | 404 | const char *rprop) |
403 | { | 405 | { |
404 | struct device_node *parent = NULL; | 406 | struct device_node *parent = NULL; |
@@ -475,22 +477,22 @@ u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, | |||
475 | return result; | 477 | return result; |
476 | } | 478 | } |
477 | 479 | ||
478 | u64 of_translate_address(struct device_node *dev, const u32 *in_addr) | 480 | u64 of_translate_address(struct device_node *dev, const __be32 *in_addr) |
479 | { | 481 | { |
480 | return __of_translate_address(dev, in_addr, "ranges"); | 482 | return __of_translate_address(dev, in_addr, "ranges"); |
481 | } | 483 | } |
482 | EXPORT_SYMBOL(of_translate_address); | 484 | EXPORT_SYMBOL(of_translate_address); |
483 | 485 | ||
484 | u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) | 486 | u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) |
485 | { | 487 | { |
486 | return __of_translate_address(dev, in_addr, "dma-ranges"); | 488 | return __of_translate_address(dev, in_addr, "dma-ranges"); |
487 | } | 489 | } |
488 | EXPORT_SYMBOL(of_translate_dma_address); | 490 | EXPORT_SYMBOL(of_translate_dma_address); |
489 | 491 | ||
490 | const u32 *of_get_address(struct device_node *dev, int index, u64 *size, | 492 | const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, |
491 | unsigned int *flags) | 493 | unsigned int *flags) |
492 | { | 494 | { |
493 | const u32 *prop; | 495 | const __be32 *prop; |
494 | unsigned int psize; | 496 | unsigned int psize; |
495 | struct device_node *parent; | 497 | struct device_node *parent; |
496 | struct of_bus *bus; | 498 | struct of_bus *bus; |
@@ -525,8 +527,8 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size, | |||
525 | } | 527 | } |
526 | EXPORT_SYMBOL(of_get_address); | 528 | EXPORT_SYMBOL(of_get_address); |
527 | 529 | ||
528 | static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, | 530 | static int __of_address_to_resource(struct device_node *dev, |
529 | u64 size, unsigned int flags, | 531 | const __be32 *addrp, u64 size, unsigned int flags, |
530 | struct resource *r) | 532 | struct resource *r) |
531 | { | 533 | { |
532 | u64 taddr; | 534 | u64 taddr; |
@@ -564,7 +566,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, | |||
564 | int of_address_to_resource(struct device_node *dev, int index, | 566 | int of_address_to_resource(struct device_node *dev, int index, |
565 | struct resource *r) | 567 | struct resource *r) |
566 | { | 568 | { |
567 | const u32 *addrp; | 569 | const __be32 *addrp; |
568 | u64 size; | 570 | u64 size; |
569 | unsigned int flags; | 571 | unsigned int flags; |
570 | 572 | ||
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index c1360e02f921..c787c3d95c60 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -11,10 +11,12 @@ | |||
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/initrd.h> | 13 | #include <linux/initrd.h> |
14 | #include <linux/module.h> | ||
14 | #include <linux/of.h> | 15 | #include <linux/of.h> |
15 | #include <linux/of_fdt.h> | 16 | #include <linux/of_fdt.h> |
16 | #include <linux/string.h> | 17 | #include <linux/string.h> |
17 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/slab.h> | ||
18 | 20 | ||
19 | #ifdef CONFIG_PPC | 21 | #ifdef CONFIG_PPC |
20 | #include <asm/machdep.h> | 22 | #include <asm/machdep.h> |
@@ -22,104 +24,19 @@ | |||
22 | 24 | ||
23 | #include <asm/page.h> | 25 | #include <asm/page.h> |
24 | 26 | ||
25 | int __initdata dt_root_addr_cells; | 27 | char *of_fdt_get_string(struct boot_param_header *blob, u32 offset) |
26 | int __initdata dt_root_size_cells; | ||
27 | |||
28 | struct boot_param_header *initial_boot_params; | ||
29 | |||
30 | char *find_flat_dt_string(u32 offset) | ||
31 | { | 28 | { |
32 | return ((char *)initial_boot_params) + | 29 | return ((char *)blob) + |
33 | be32_to_cpu(initial_boot_params->off_dt_strings) + offset; | 30 | be32_to_cpu(blob->off_dt_strings) + offset; |
34 | } | ||
35 | |||
36 | /** | ||
37 | * of_scan_flat_dt - scan flattened tree blob and call callback on each. | ||
38 | * @it: callback function | ||
39 | * @data: context data pointer | ||
40 | * | ||
41 | * This function is used to scan the flattened device-tree, it is | ||
42 | * used to extract the memory information at boot before we can | ||
43 | * unflatten the tree | ||
44 | */ | ||
45 | int __init of_scan_flat_dt(int (*it)(unsigned long node, | ||
46 | const char *uname, int depth, | ||
47 | void *data), | ||
48 | void *data) | ||
49 | { | ||
50 | unsigned long p = ((unsigned long)initial_boot_params) + | ||
51 | be32_to_cpu(initial_boot_params->off_dt_struct); | ||
52 | int rc = 0; | ||
53 | int depth = -1; | ||
54 | |||
55 | do { | ||
56 | u32 tag = be32_to_cpup((__be32 *)p); | ||
57 | char *pathp; | ||
58 | |||
59 | p += 4; | ||
60 | if (tag == OF_DT_END_NODE) { | ||
61 | depth--; | ||
62 | continue; | ||
63 | } | ||
64 | if (tag == OF_DT_NOP) | ||
65 | continue; | ||
66 | if (tag == OF_DT_END) | ||
67 | break; | ||
68 | if (tag == OF_DT_PROP) { | ||
69 | u32 sz = be32_to_cpup((__be32 *)p); | ||
70 | p += 8; | ||
71 | if (be32_to_cpu(initial_boot_params->version) < 0x10) | ||
72 | p = ALIGN(p, sz >= 8 ? 8 : 4); | ||
73 | p += sz; | ||
74 | p = ALIGN(p, 4); | ||
75 | continue; | ||
76 | } | ||
77 | if (tag != OF_DT_BEGIN_NODE) { | ||
78 | pr_err("Invalid tag %x in flat device tree!\n", tag); | ||
79 | return -EINVAL; | ||
80 | } | ||
81 | depth++; | ||
82 | pathp = (char *)p; | ||
83 | p = ALIGN(p + strlen(pathp) + 1, 4); | ||
84 | if ((*pathp) == '/') { | ||
85 | char *lp, *np; | ||
86 | for (lp = NULL, np = pathp; *np; np++) | ||
87 | if ((*np) == '/') | ||
88 | lp = np+1; | ||
89 | if (lp != NULL) | ||
90 | pathp = lp; | ||
91 | } | ||
92 | rc = it(p, pathp, depth, data); | ||
93 | if (rc != 0) | ||
94 | break; | ||
95 | } while (1); | ||
96 | |||
97 | return rc; | ||
98 | } | 31 | } |
99 | 32 | ||
100 | /** | 33 | /** |
101 | * of_get_flat_dt_root - find the root node in the flat blob | 34 | * of_fdt_get_property - Given a node in the given flat blob, return |
35 | * the property ptr | ||
102 | */ | 36 | */ |
103 | unsigned long __init of_get_flat_dt_root(void) | 37 | void *of_fdt_get_property(struct boot_param_header *blob, |
104 | { | 38 | unsigned long node, const char *name, |
105 | unsigned long p = ((unsigned long)initial_boot_params) + | 39 | unsigned long *size) |
106 | be32_to_cpu(initial_boot_params->off_dt_struct); | ||
107 | |||
108 | while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) | ||
109 | p += 4; | ||
110 | BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); | ||
111 | p += 4; | ||
112 | return ALIGN(p + strlen((char *)p) + 1, 4); | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr | ||
117 | * | ||
118 | * This function can be used within scan_flattened_dt callback to get | ||
119 | * access to properties | ||
120 | */ | ||
121 | void *__init of_get_flat_dt_prop(unsigned long node, const char *name, | ||
122 | unsigned long *size) | ||
123 | { | 40 | { |
124 | unsigned long p = node; | 41 | unsigned long p = node; |
125 | 42 | ||
@@ -137,10 +54,10 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name, | |||
137 | sz = be32_to_cpup((__be32 *)p); | 54 | sz = be32_to_cpup((__be32 *)p); |
138 | noff = be32_to_cpup((__be32 *)(p + 4)); | 55 | noff = be32_to_cpup((__be32 *)(p + 4)); |
139 | p += 8; | 56 | p += 8; |
140 | if (be32_to_cpu(initial_boot_params->version) < 0x10) | 57 | if (be32_to_cpu(blob->version) < 0x10) |
141 | p = ALIGN(p, sz >= 8 ? 8 : 4); | 58 | p = ALIGN(p, sz >= 8 ? 8 : 4); |
142 | 59 | ||
143 | nstr = find_flat_dt_string(noff); | 60 | nstr = of_fdt_get_string(blob, noff); |
144 | if (nstr == NULL) { | 61 | if (nstr == NULL) { |
145 | pr_warning("Can't find property index name !\n"); | 62 | pr_warning("Can't find property index name !\n"); |
146 | return NULL; | 63 | return NULL; |
@@ -156,21 +73,28 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name, | |||
156 | } | 73 | } |
157 | 74 | ||
158 | /** | 75 | /** |
159 | * of_flat_dt_is_compatible - Return true if given node has compat in compatible list | 76 | * of_fdt_is_compatible - Return true if given node from the given blob has |
77 | * compat in its compatible list | ||
78 | * @blob: A device tree blob | ||
160 | * @node: node to test | 79 | * @node: node to test |
161 | * @compat: compatible string to compare with compatible list. | 80 | * @compat: compatible string to compare with compatible list. |
81 | * | ||
82 | * On match, returns a non-zero value with smaller values returned for more | ||
83 | * specific compatible values. | ||
162 | */ | 84 | */ |
163 | int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) | 85 | int of_fdt_is_compatible(struct boot_param_header *blob, |
86 | unsigned long node, const char *compat) | ||
164 | { | 87 | { |
165 | const char *cp; | 88 | const char *cp; |
166 | unsigned long cplen, l; | 89 | unsigned long cplen, l, score = 0; |
167 | 90 | ||
168 | cp = of_get_flat_dt_prop(node, "compatible", &cplen); | 91 | cp = of_fdt_get_property(blob, node, "compatible", &cplen); |
169 | if (cp == NULL) | 92 | if (cp == NULL) |
170 | return 0; | 93 | return 0; |
171 | while (cplen > 0) { | 94 | while (cplen > 0) { |
95 | score++; | ||
172 | if (of_compat_cmp(cp, compat, strlen(compat)) == 0) | 96 | if (of_compat_cmp(cp, compat, strlen(compat)) == 0) |
173 | return 1; | 97 | return score; |
174 | l = strlen(cp) + 1; | 98 | l = strlen(cp) + 1; |
175 | cp += l; | 99 | cp += l; |
176 | cplen -= l; | 100 | cplen -= l; |
@@ -179,7 +103,28 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) | |||
179 | return 0; | 103 | return 0; |
180 | } | 104 | } |
181 | 105 | ||
182 | static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, | 106 | /** |
107 | * of_fdt_match - Return true if node matches a list of compatible values | ||
108 | */ | ||
109 | int of_fdt_match(struct boot_param_header *blob, unsigned long node, | ||
110 | const char **compat) | ||
111 | { | ||
112 | unsigned int tmp, score = 0; | ||
113 | |||
114 | if (!compat) | ||
115 | return 0; | ||
116 | |||
117 | while (*compat) { | ||
118 | tmp = of_fdt_is_compatible(blob, node, *compat); | ||
119 | if (tmp && (score == 0 || (tmp < score))) | ||
120 | score = tmp; | ||
121 | compat++; | ||
122 | } | ||
123 | |||
124 | return score; | ||
125 | } | ||
126 | |||
127 | static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, | ||
183 | unsigned long align) | 128 | unsigned long align) |
184 | { | 129 | { |
185 | void *res; | 130 | void *res; |
@@ -193,16 +138,18 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, | |||
193 | 138 | ||
194 | /** | 139 | /** |
195 | * unflatten_dt_node - Alloc and populate a device_node from the flat tree | 140 | * unflatten_dt_node - Alloc and populate a device_node from the flat tree |
141 | * @blob: The parent device tree blob | ||
196 | * @p: pointer to node in flat tree | 142 | * @p: pointer to node in flat tree |
197 | * @dad: Parent struct device_node | 143 | * @dad: Parent struct device_node |
198 | * @allnextpp: pointer to ->allnext from last allocated device_node | 144 | * @allnextpp: pointer to ->allnext from last allocated device_node |
199 | * @fpsize: Size of the node path up at the current depth. | 145 | * @fpsize: Size of the node path up at the current depth. |
200 | */ | 146 | */ |
201 | unsigned long __init unflatten_dt_node(unsigned long mem, | 147 | unsigned long unflatten_dt_node(struct boot_param_header *blob, |
202 | unsigned long *p, | 148 | unsigned long mem, |
203 | struct device_node *dad, | 149 | unsigned long *p, |
204 | struct device_node ***allnextpp, | 150 | struct device_node *dad, |
205 | unsigned long fpsize) | 151 | struct device_node ***allnextpp, |
152 | unsigned long fpsize) | ||
206 | { | 153 | { |
207 | struct device_node *np; | 154 | struct device_node *np; |
208 | struct property *pp, **prev_pp = NULL; | 155 | struct property *pp, **prev_pp = NULL; |
@@ -298,10 +245,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem, | |||
298 | sz = be32_to_cpup((__be32 *)(*p)); | 245 | sz = be32_to_cpup((__be32 *)(*p)); |
299 | noff = be32_to_cpup((__be32 *)((*p) + 4)); | 246 | noff = be32_to_cpup((__be32 *)((*p) + 4)); |
300 | *p += 8; | 247 | *p += 8; |
301 | if (be32_to_cpu(initial_boot_params->version) < 0x10) | 248 | if (be32_to_cpu(blob->version) < 0x10) |
302 | *p = ALIGN(*p, sz >= 8 ? 8 : 4); | 249 | *p = ALIGN(*p, sz >= 8 ? 8 : 4); |
303 | 250 | ||
304 | pname = find_flat_dt_string(noff); | 251 | pname = of_fdt_get_string(blob, noff); |
305 | if (pname == NULL) { | 252 | if (pname == NULL) { |
306 | pr_info("Can't find property name in list !\n"); | 253 | pr_info("Can't find property name in list !\n"); |
307 | break; | 254 | break; |
@@ -380,7 +327,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem, | |||
380 | if (tag == OF_DT_NOP) | 327 | if (tag == OF_DT_NOP) |
381 | *p += 4; | 328 | *p += 4; |
382 | else | 329 | else |
383 | mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); | 330 | mem = unflatten_dt_node(blob, mem, p, np, allnextpp, |
331 | fpsize); | ||
384 | tag = be32_to_cpup((__be32 *)(*p)); | 332 | tag = be32_to_cpup((__be32 *)(*p)); |
385 | } | 333 | } |
386 | if (tag != OF_DT_END_NODE) { | 334 | if (tag != OF_DT_END_NODE) { |
@@ -391,6 +339,211 @@ unsigned long __init unflatten_dt_node(unsigned long mem, | |||
391 | return mem; | 339 | return mem; |
392 | } | 340 | } |
393 | 341 | ||
342 | /** | ||
343 | * __unflatten_device_tree - create tree of device_nodes from flat blob | ||
344 | * | ||
345 | * unflattens a device-tree, creating the | ||
346 | * tree of struct device_node. It also fills the "name" and "type" | ||
347 | * pointers of the nodes so the normal device-tree walking functions | ||
348 | * can be used. | ||
349 | * @blob: The blob to expand | ||
350 | * @mynodes: The device_node tree created by the call | ||
351 | * @dt_alloc: An allocator that provides a virtual address to memory | ||
352 | * for the resulting tree | ||
353 | */ | ||
354 | void __unflatten_device_tree(struct boot_param_header *blob, | ||
355 | struct device_node **mynodes, | ||
356 | void * (*dt_alloc)(u64 size, u64 align)) | ||
357 | { | ||
358 | unsigned long start, mem, size; | ||
359 | struct device_node **allnextp = mynodes; | ||
360 | |||
361 | pr_debug(" -> unflatten_device_tree()\n"); | ||
362 | |||
363 | if (!blob) { | ||
364 | pr_debug("No device tree pointer\n"); | ||
365 | return; | ||
366 | } | ||
367 | |||
368 | pr_debug("Unflattening device tree:\n"); | ||
369 | pr_debug("magic: %08x\n", be32_to_cpu(blob->magic)); | ||
370 | pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize)); | ||
371 | pr_debug("version: %08x\n", be32_to_cpu(blob->version)); | ||
372 | |||
373 | if (be32_to_cpu(blob->magic) != OF_DT_HEADER) { | ||
374 | pr_err("Invalid device tree blob header\n"); | ||
375 | return; | ||
376 | } | ||
377 | |||
378 | /* First pass, scan for size */ | ||
379 | start = ((unsigned long)blob) + | ||
380 | be32_to_cpu(blob->off_dt_struct); | ||
381 | size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0); | ||
382 | size = (size | 3) + 1; | ||
383 | |||
384 | pr_debug(" size is %lx, allocating...\n", size); | ||
385 | |||
386 | /* Allocate memory for the expanded device tree */ | ||
387 | mem = (unsigned long) | ||
388 | dt_alloc(size + 4, __alignof__(struct device_node)); | ||
389 | |||
390 | ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); | ||
391 | |||
392 | pr_debug(" unflattening %lx...\n", mem); | ||
393 | |||
394 | /* Second pass, do actual unflattening */ | ||
395 | start = ((unsigned long)blob) + | ||
396 | be32_to_cpu(blob->off_dt_struct); | ||
397 | unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); | ||
398 | if (be32_to_cpup((__be32 *)start) != OF_DT_END) | ||
399 | pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); | ||
400 | if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) | ||
401 | pr_warning("End of tree marker overwritten: %08x\n", | ||
402 | be32_to_cpu(((__be32 *)mem)[size / 4])); | ||
403 | *allnextp = NULL; | ||
404 | |||
405 | pr_debug(" <- unflatten_device_tree()\n"); | ||
406 | } | ||
407 | |||
408 | static void *kernel_tree_alloc(u64 size, u64 align) | ||
409 | { | ||
410 | return kzalloc(size, GFP_KERNEL); | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * of_fdt_unflatten_tree - create tree of device_nodes from flat blob | ||
415 | * | ||
416 | * unflattens the device-tree passed by the firmware, creating the | ||
417 | * tree of struct device_node. It also fills the "name" and "type" | ||
418 | * pointers of the nodes so the normal device-tree walking functions | ||
419 | * can be used. | ||
420 | */ | ||
421 | void of_fdt_unflatten_tree(unsigned long *blob, | ||
422 | struct device_node **mynodes) | ||
423 | { | ||
424 | struct boot_param_header *device_tree = | ||
425 | (struct boot_param_header *)blob; | ||
426 | __unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc); | ||
427 | } | ||
428 | EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); | ||
429 | |||
430 | /* Everything below here references initial_boot_params directly. */ | ||
431 | int __initdata dt_root_addr_cells; | ||
432 | int __initdata dt_root_size_cells; | ||
433 | |||
434 | struct boot_param_header *initial_boot_params; | ||
435 | |||
436 | #ifdef CONFIG_OF_EARLY_FLATTREE | ||
437 | |||
438 | /** | ||
439 | * of_scan_flat_dt - scan flattened tree blob and call callback on each. | ||
440 | * @it: callback function | ||
441 | * @data: context data pointer | ||
442 | * | ||
443 | * This function is used to scan the flattened device-tree, it is | ||
444 | * used to extract the memory information at boot before we can | ||
445 | * unflatten the tree | ||
446 | */ | ||
447 | int __init of_scan_flat_dt(int (*it)(unsigned long node, | ||
448 | const char *uname, int depth, | ||
449 | void *data), | ||
450 | void *data) | ||
451 | { | ||
452 | unsigned long p = ((unsigned long)initial_boot_params) + | ||
453 | be32_to_cpu(initial_boot_params->off_dt_struct); | ||
454 | int rc = 0; | ||
455 | int depth = -1; | ||
456 | |||
457 | do { | ||
458 | u32 tag = be32_to_cpup((__be32 *)p); | ||
459 | char *pathp; | ||
460 | |||
461 | p += 4; | ||
462 | if (tag == OF_DT_END_NODE) { | ||
463 | depth--; | ||
464 | continue; | ||
465 | } | ||
466 | if (tag == OF_DT_NOP) | ||
467 | continue; | ||
468 | if (tag == OF_DT_END) | ||
469 | break; | ||
470 | if (tag == OF_DT_PROP) { | ||
471 | u32 sz = be32_to_cpup((__be32 *)p); | ||
472 | p += 8; | ||
473 | if (be32_to_cpu(initial_boot_params->version) < 0x10) | ||
474 | p = ALIGN(p, sz >= 8 ? 8 : 4); | ||
475 | p += sz; | ||
476 | p = ALIGN(p, 4); | ||
477 | continue; | ||
478 | } | ||
479 | if (tag != OF_DT_BEGIN_NODE) { | ||
480 | pr_err("Invalid tag %x in flat device tree!\n", tag); | ||
481 | return -EINVAL; | ||
482 | } | ||
483 | depth++; | ||
484 | pathp = (char *)p; | ||
485 | p = ALIGN(p + strlen(pathp) + 1, 4); | ||
486 | if ((*pathp) == '/') { | ||
487 | char *lp, *np; | ||
488 | for (lp = NULL, np = pathp; *np; np++) | ||
489 | if ((*np) == '/') | ||
490 | lp = np+1; | ||
491 | if (lp != NULL) | ||
492 | pathp = lp; | ||
493 | } | ||
494 | rc = it(p, pathp, depth, data); | ||
495 | if (rc != 0) | ||
496 | break; | ||
497 | } while (1); | ||
498 | |||
499 | return rc; | ||
500 | } | ||
501 | |||
502 | /** | ||
503 | * of_get_flat_dt_root - find the root node in the flat blob | ||
504 | */ | ||
505 | unsigned long __init of_get_flat_dt_root(void) | ||
506 | { | ||
507 | unsigned long p = ((unsigned long)initial_boot_params) + | ||
508 | be32_to_cpu(initial_boot_params->off_dt_struct); | ||
509 | |||
510 | while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) | ||
511 | p += 4; | ||
512 | BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); | ||
513 | p += 4; | ||
514 | return ALIGN(p + strlen((char *)p) + 1, 4); | ||
515 | } | ||
516 | |||
517 | /** | ||
518 | * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr | ||
519 | * | ||
520 | * This function can be used within scan_flattened_dt callback to get | ||
521 | * access to properties | ||
522 | */ | ||
523 | void *__init of_get_flat_dt_prop(unsigned long node, const char *name, | ||
524 | unsigned long *size) | ||
525 | { | ||
526 | return of_fdt_get_property(initial_boot_params, node, name, size); | ||
527 | } | ||
528 | |||
529 | /** | ||
530 | * of_flat_dt_is_compatible - Return true if given node has compat in compatible list | ||
531 | * @node: node to test | ||
532 | * @compat: compatible string to compare with compatible list. | ||
533 | */ | ||
534 | int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) | ||
535 | { | ||
536 | return of_fdt_is_compatible(initial_boot_params, node, compat); | ||
537 | } | ||
538 | |||
539 | /** | ||
540 | * of_flat_dt_match - Return true if node matches a list of compatible values | ||
541 | */ | ||
542 | int __init of_flat_dt_match(unsigned long node, const char **compat) | ||
543 | { | ||
544 | return of_fdt_match(initial_boot_params, node, compat); | ||
545 | } | ||
546 | |||
394 | #ifdef CONFIG_BLK_DEV_INITRD | 547 | #ifdef CONFIG_BLK_DEV_INITRD |
395 | /** | 548 | /** |
396 | * early_init_dt_check_for_initrd - Decode initrd location from flat tree | 549 | * early_init_dt_check_for_initrd - Decode initrd location from flat tree |
@@ -539,6 +692,12 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | |||
539 | return 1; | 692 | return 1; |
540 | } | 693 | } |
541 | 694 | ||
695 | static void *__init early_device_tree_alloc(u64 size, u64 align) | ||
696 | { | ||
697 | unsigned long mem = early_init_dt_alloc_memory_arch(size, align); | ||
698 | return __va(mem); | ||
699 | } | ||
700 | |||
542 | /** | 701 | /** |
543 | * unflatten_device_tree - create tree of device_nodes from flat blob | 702 | * unflatten_device_tree - create tree of device_nodes from flat blob |
544 | * | 703 | * |
@@ -549,58 +708,13 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | |||
549 | */ | 708 | */ |
550 | void __init unflatten_device_tree(void) | 709 | void __init unflatten_device_tree(void) |
551 | { | 710 | { |
552 | unsigned long start, mem, size; | 711 | __unflatten_device_tree(initial_boot_params, &allnodes, |
553 | struct device_node **allnextp = &allnodes; | 712 | early_device_tree_alloc); |
554 | |||
555 | pr_debug(" -> unflatten_device_tree()\n"); | ||
556 | |||
557 | if (!initial_boot_params) { | ||
558 | pr_debug("No device tree pointer\n"); | ||
559 | return; | ||
560 | } | ||
561 | |||
562 | pr_debug("Unflattening device tree:\n"); | ||
563 | pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic)); | ||
564 | pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize)); | ||
565 | pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version)); | ||
566 | |||
567 | if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { | ||
568 | pr_err("Invalid device tree blob header\n"); | ||
569 | return; | ||
570 | } | ||
571 | |||
572 | /* First pass, scan for size */ | ||
573 | start = ((unsigned long)initial_boot_params) + | ||
574 | be32_to_cpu(initial_boot_params->off_dt_struct); | ||
575 | size = unflatten_dt_node(0, &start, NULL, NULL, 0); | ||
576 | size = (size | 3) + 1; | ||
577 | |||
578 | pr_debug(" size is %lx, allocating...\n", size); | ||
579 | |||
580 | /* Allocate memory for the expanded device tree */ | ||
581 | mem = early_init_dt_alloc_memory_arch(size + 4, | ||
582 | __alignof__(struct device_node)); | ||
583 | mem = (unsigned long) __va(mem); | ||
584 | |||
585 | ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); | ||
586 | |||
587 | pr_debug(" unflattening %lx...\n", mem); | ||
588 | |||
589 | /* Second pass, do actual unflattening */ | ||
590 | start = ((unsigned long)initial_boot_params) + | ||
591 | be32_to_cpu(initial_boot_params->off_dt_struct); | ||
592 | unflatten_dt_node(mem, &start, NULL, &allnextp, 0); | ||
593 | if (be32_to_cpup((__be32 *)start) != OF_DT_END) | ||
594 | pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); | ||
595 | if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) | ||
596 | pr_warning("End of tree marker overwritten: %08x\n", | ||
597 | be32_to_cpu(((__be32 *)mem)[size / 4])); | ||
598 | *allnextp = NULL; | ||
599 | 713 | ||
600 | /* Get pointer to OF "/chosen" node for use everywhere */ | 714 | /* Get pointer to OF "/chosen" node for use everywhere */ |
601 | of_chosen = of_find_node_by_path("/chosen"); | 715 | of_chosen = of_find_node_by_path("/chosen"); |
602 | if (of_chosen == NULL) | 716 | if (of_chosen == NULL) |
603 | of_chosen = of_find_node_by_path("/chosen@0"); | 717 | of_chosen = of_find_node_by_path("/chosen@0"); |
604 | |||
605 | pr_debug(" <- unflatten_device_tree()\n"); | ||
606 | } | 718 | } |
719 | |||
720 | #endif /* CONFIG_OF_EARLY_FLATTREE */ | ||
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 1fce00eb421b..dcd7857784f2 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -52,27 +52,35 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
52 | 52 | ||
53 | /* Loop over the child nodes and register a phy_device for each one */ | 53 | /* Loop over the child nodes and register a phy_device for each one */ |
54 | for_each_child_of_node(np, child) { | 54 | for_each_child_of_node(np, child) { |
55 | const __be32 *addr; | 55 | const __be32 *paddr; |
56 | u32 addr; | ||
56 | int len; | 57 | int len; |
57 | 58 | ||
58 | /* A PHY must have a reg property in the range [0-31] */ | 59 | /* A PHY must have a reg property in the range [0-31] */ |
59 | addr = of_get_property(child, "reg", &len); | 60 | paddr = of_get_property(child, "reg", &len); |
60 | if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) { | 61 | if (!paddr || len < sizeof(*paddr)) { |
61 | dev_err(&mdio->dev, "%s has invalid PHY address\n", | 62 | dev_err(&mdio->dev, "%s has invalid PHY address\n", |
62 | child->full_name); | 63 | child->full_name); |
63 | continue; | 64 | continue; |
64 | } | 65 | } |
65 | 66 | ||
67 | addr = be32_to_cpup(paddr); | ||
68 | if (addr >= 32) { | ||
69 | dev_err(&mdio->dev, "%s PHY address %i is too large\n", | ||
70 | child->full_name, addr); | ||
71 | continue; | ||
72 | } | ||
73 | |||
66 | if (mdio->irq) { | 74 | if (mdio->irq) { |
67 | mdio->irq[*addr] = irq_of_parse_and_map(child, 0); | 75 | mdio->irq[addr] = irq_of_parse_and_map(child, 0); |
68 | if (!mdio->irq[*addr]) | 76 | if (!mdio->irq[addr]) |
69 | mdio->irq[*addr] = PHY_POLL; | 77 | mdio->irq[addr] = PHY_POLL; |
70 | } | 78 | } |
71 | 79 | ||
72 | phy = get_phy_device(mdio, be32_to_cpup(addr)); | 80 | phy = get_phy_device(mdio, addr); |
73 | if (!phy || IS_ERR(phy)) { | 81 | if (!phy || IS_ERR(phy)) { |
74 | dev_err(&mdio->dev, "error probing PHY at address %i\n", | 82 | dev_err(&mdio->dev, "error probing PHY at address %i\n", |
75 | *addr); | 83 | addr); |
76 | continue; | 84 | continue; |
77 | } | 85 | } |
78 | phy_scan_fixups(phy); | 86 | phy_scan_fixups(phy); |
@@ -91,7 +99,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
91 | } | 99 | } |
92 | 100 | ||
93 | dev_dbg(&mdio->dev, "registered phy %s at address %i\n", | 101 | dev_dbg(&mdio->dev, "registered phy %s at address %i\n", |
94 | child->name, *addr); | 102 | child->name, addr); |
95 | } | 103 | } |
96 | 104 | ||
97 | return 0; | 105 | return 0; |
diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c new file mode 100644 index 000000000000..86f334a2769c --- /dev/null +++ b/drivers/of/of_net.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * OF helpers for network devices. | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | * | ||
6 | * Initially copied out of arch/powerpc/kernel/prom_parse.c | ||
7 | */ | ||
8 | #include <linux/etherdevice.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/of_net.h> | ||
11 | |||
12 | /** | ||
13 | * Search the device tree for the best MAC address to use. 'mac-address' is | ||
14 | * checked first, because that is supposed to contain to "most recent" MAC | ||
15 | * address. If that isn't set, then 'local-mac-address' is checked next, | ||
16 | * because that is the default address. If that isn't set, then the obsolete | ||
17 | * 'address' is checked, just in case we're using an old device tree. | ||
18 | * | ||
19 | * Note that the 'address' property is supposed to contain a virtual address of | ||
20 | * the register set, but some DTS files have redefined that property to be the | ||
21 | * MAC address. | ||
22 | * | ||
23 | * All-zero MAC addresses are rejected, because those could be properties that | ||
24 | * exist in the device tree, but were not set by U-Boot. For example, the | ||
25 | * DTS could define 'mac-address' and 'local-mac-address', with zero MAC | ||
26 | * addresses. Some older U-Boots only initialized 'local-mac-address'. In | ||
27 | * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists | ||
28 | * but is all zeros. | ||
29 | */ | ||
30 | const void *of_get_mac_address(struct device_node *np) | ||
31 | { | ||
32 | struct property *pp; | ||
33 | |||
34 | pp = of_find_property(np, "mac-address", NULL); | ||
35 | if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) | ||
36 | return pp->value; | ||
37 | |||
38 | pp = of_find_property(np, "local-mac-address", NULL); | ||
39 | if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) | ||
40 | return pp->value; | ||
41 | |||
42 | pp = of_find_property(np, "address", NULL); | ||
43 | if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) | ||
44 | return pp->value; | ||
45 | |||
46 | return NULL; | ||
47 | } | ||
48 | EXPORT_SYMBOL(of_get_mac_address); | ||
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 5b4a07f1220e..c01cd1ac7617 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -633,6 +633,9 @@ EXPORT_SYMBOL(of_device_alloc); | |||
633 | * @np: pointer to node to create device for | 633 | * @np: pointer to node to create device for |
634 | * @bus_id: name to assign device | 634 | * @bus_id: name to assign device |
635 | * @parent: Linux device model parent device. | 635 | * @parent: Linux device model parent device. |
636 | * | ||
637 | * Returns pointer to created platform device, or NULL if a device was not | ||
638 | * registered. Unavailable devices will not get registered. | ||
636 | */ | 639 | */ |
637 | struct platform_device *of_platform_device_create(struct device_node *np, | 640 | struct platform_device *of_platform_device_create(struct device_node *np, |
638 | const char *bus_id, | 641 | const char *bus_id, |
@@ -640,6 +643,9 @@ struct platform_device *of_platform_device_create(struct device_node *np, | |||
640 | { | 643 | { |
641 | struct platform_device *dev; | 644 | struct platform_device *dev; |
642 | 645 | ||
646 | if (!of_device_is_available(np)) | ||
647 | return NULL; | ||
648 | |||
643 | dev = of_device_alloc(np, bus_id, parent); | 649 | dev = of_device_alloc(np, bus_id, parent); |
644 | if (!dev) | 650 | if (!dev) |
645 | return NULL; | 651 | return NULL; |
@@ -683,8 +689,9 @@ static int of_platform_bus_create(const struct device_node *bus, | |||
683 | pr_debug(" create child: %s\n", child->full_name); | 689 | pr_debug(" create child: %s\n", child->full_name); |
684 | dev = of_platform_device_create(child, NULL, parent); | 690 | dev = of_platform_device_create(child, NULL, parent); |
685 | if (dev == NULL) | 691 | if (dev == NULL) |
686 | rc = -ENOMEM; | 692 | continue; |
687 | else if (!of_match_node(matches, child)) | 693 | |
694 | if (!of_match_node(matches, child)) | ||
688 | continue; | 695 | continue; |
689 | if (rc == 0) { | 696 | if (rc == 0) { |
690 | pr_debug(" and sub busses\n"); | 697 | pr_debug(" and sub busses\n"); |
@@ -733,10 +740,9 @@ int of_platform_bus_probe(struct device_node *root, | |||
733 | if (of_match_node(matches, root)) { | 740 | if (of_match_node(matches, root)) { |
734 | pr_debug(" root match, create all sub devices\n"); | 741 | pr_debug(" root match, create all sub devices\n"); |
735 | dev = of_platform_device_create(root, NULL, parent); | 742 | dev = of_platform_device_create(root, NULL, parent); |
736 | if (dev == NULL) { | 743 | if (dev == NULL) |
737 | rc = -ENOMEM; | ||
738 | goto bail; | 744 | goto bail; |
739 | } | 745 | |
740 | pr_debug(" create all sub busses\n"); | 746 | pr_debug(" create all sub busses\n"); |
741 | rc = of_platform_bus_create(root, matches, &dev->dev); | 747 | rc = of_platform_bus_create(root, matches, &dev->dev); |
742 | goto bail; | 748 | goto bail; |
@@ -748,9 +754,9 @@ int of_platform_bus_probe(struct device_node *root, | |||
748 | pr_debug(" match: %s\n", child->full_name); | 754 | pr_debug(" match: %s\n", child->full_name); |
749 | dev = of_platform_device_create(child, NULL, parent); | 755 | dev = of_platform_device_create(child, NULL, parent); |
750 | if (dev == NULL) | 756 | if (dev == NULL) |
751 | rc = -ENOMEM; | 757 | continue; |
752 | else | 758 | |
753 | rc = of_platform_bus_create(child, matches, &dev->dev); | 759 | rc = of_platform_bus_create(child, matches, &dev->dev); |
754 | if (rc) { | 760 | if (rc) { |
755 | of_node_put(child); | 761 | of_node_put(child); |
756 | break; | 762 | break; |