aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 13:02:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 13:02:38 -0400
commitd27050641e9bc056446deb0814e7ba1aa7911f5a (patch)
tree160f46d9a6df3d7234c71a9fbaa31ebcf89c04d0 /drivers/of
parentb77279bc2e81545b20824da701b349272a78e4e7 (diff)
parent43cb43678705e39b175b325f17938295996aefc7 (diff)
Merge tag 'devicetree-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux into next
Pull DeviceTree updates from Rob Herring: - Another round of clean-up of FDT related code in architecture code. This removes knowledge of internal FDT details from most architectures except powerpc. - Conversion of kernel's custom FDT parsing code to use libfdt. - DT based initialization for generic serial earlycon. The introduction of generic serial earlycon support went in through the tty tree. - Improve the platform device naming for DT probed devices to ensure unique naming and use parent names instead of a global index. - Fix a race condition in of_update_property. - Unify the various linker section OF match tables and fix several function prototype errors. - Update platform_get_irq_byname to work in deferred probe cases. - 2 binding doc updates * tag 'devicetree-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (58 commits) of: handle NULL node in next_child iterators of/irq: provide more wrappers for !CONFIG_OF devicetree: bindings: Document micrel vendor prefix dt: bindings: dwc2: fix required value for the phy-names property of_pci_irq: kill useless variable in of_irq_parse_pci() of/irq: do irq resolution in platform_get_irq_byname() of: Add a testcase for of_find_node_by_path() of: Make of_find_node_by_path() handle /aliases of: Create unlocked version of for_each_child_of_node() lib: add glibc style strchrnul() variant of: Handle memory@0 node on PPC32 only pci/of: Remove dead code of: fix race between search and remove in of_update_property() of: Use NULL for pointers of: Stop naming platform_device using dcr address of: Ensure unique names without sacrificing determinism tty/serial: pl011: add DT based earlycon support of/fdt: add FDT serial scanning for earlycon of/fdt: add FDT address translation support serial: earlycon: add DT support ...
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/Kconfig1
-rw-r--r--drivers/of/Makefile4
-rw-r--r--drivers/of/address.c22
-rw-r--r--drivers/of/base.c119
-rw-r--r--drivers/of/fdt.c458
-rw-r--r--drivers/of/fdt_address.c241
-rw-r--r--drivers/of/irq.c22
-rw-r--r--drivers/of/of_pci_irq.c8
-rw-r--r--drivers/of/of_reserved_mem.c6
-rw-r--r--drivers/of/platform.c76
-rw-r--r--drivers/of/selftest.c80
-rw-r--r--drivers/of/testcase-data/testcases.dtsi1
-rw-r--r--drivers/of/testcase-data/tests-phandle.dtsi6
-rw-r--r--drivers/of/testcase-data/tests-platform.dtsi35
14 files changed, 698 insertions, 381 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 889005fa4d04..2dcb0541012d 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -20,6 +20,7 @@ config OF_SELFTEST
20config OF_FLATTREE 20config OF_FLATTREE
21 bool 21 bool
22 select DTC 22 select DTC
23 select LIBFDT
23 24
24config OF_EARLY_FLATTREE 25config OF_EARLY_FLATTREE
25 bool 26 bool
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ed9660adad77..099b1fb00af4 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,5 +1,6 @@
1obj-y = base.o device.o platform.o 1obj-y = base.o device.o platform.o
2obj-$(CONFIG_OF_FLATTREE) += fdt.o 2obj-$(CONFIG_OF_FLATTREE) += fdt.o
3obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
3obj-$(CONFIG_OF_PROMTREE) += pdt.o 4obj-$(CONFIG_OF_PROMTREE) += pdt.o
4obj-$(CONFIG_OF_ADDRESS) += address.o 5obj-$(CONFIG_OF_ADDRESS) += address.o
5obj-$(CONFIG_OF_IRQ) += irq.o 6obj-$(CONFIG_OF_IRQ) += irq.o
@@ -10,3 +11,6 @@ obj-$(CONFIG_OF_PCI) += of_pci.o
10obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o 11obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
11obj-$(CONFIG_OF_MTD) += of_mtd.o 12obj-$(CONFIG_OF_MTD) += of_mtd.o
12obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o 13obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
14
15CFLAGS_fdt.o = -I$(src)/../../scripts/dtc/libfdt
16CFLAGS_fdt_address.o = -I$(src)/../../scripts/dtc/libfdt
diff --git a/drivers/of/address.c b/drivers/of/address.c
index cb4242a69cd5..95351b2a112c 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -498,8 +498,7 @@ static u64 __of_translate_address(struct device_node *dev,
498 /* Count address cells & copy address locally */ 498 /* Count address cells & copy address locally */
499 bus->count_cells(dev, &na, &ns); 499 bus->count_cells(dev, &na, &ns);
500 if (!OF_CHECK_COUNTS(na, ns)) { 500 if (!OF_CHECK_COUNTS(na, ns)) {
501 printk(KERN_ERR "prom_parse: Bad cell count for %s\n", 501 pr_debug("OF: Bad cell count for %s\n", of_node_full_name(dev));
502 of_node_full_name(dev));
503 goto bail; 502 goto bail;
504 } 503 }
505 memcpy(addr, in_addr, na * 4); 504 memcpy(addr, in_addr, na * 4);
@@ -564,25 +563,6 @@ u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
564} 563}
565EXPORT_SYMBOL(of_translate_dma_address); 564EXPORT_SYMBOL(of_translate_dma_address);
566 565
567bool of_can_translate_address(struct device_node *dev)
568{
569 struct device_node *parent;
570 struct of_bus *bus;
571 int na, ns;
572
573 parent = of_get_parent(dev);
574 if (parent == NULL)
575 return false;
576
577 bus = of_match_bus(parent);
578 bus->count_cells(dev, &na, &ns);
579
580 of_node_put(parent);
581
582 return OF_CHECK_COUNTS(na, ns);
583}
584EXPORT_SYMBOL(of_can_translate_address);
585
586const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, 566const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
587 unsigned int *flags) 567 unsigned int *flags)
588{ 568{
diff --git a/drivers/of/base.c b/drivers/of/base.c
index aab9728271fd..8368d96ae7b4 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -695,6 +695,25 @@ struct device_node *of_get_next_parent(struct device_node *node)
695} 695}
696EXPORT_SYMBOL(of_get_next_parent); 696EXPORT_SYMBOL(of_get_next_parent);
697 697
698static struct device_node *__of_get_next_child(const struct device_node *node,
699 struct device_node *prev)
700{
701 struct device_node *next;
702
703 if (!node)
704 return NULL;
705
706 next = prev ? prev->sibling : node->child;
707 for (; next; next = next->sibling)
708 if (of_node_get(next))
709 break;
710 of_node_put(prev);
711 return next;
712}
713#define __for_each_child_of_node(parent, child) \
714 for (child = __of_get_next_child(parent, NULL); child != NULL; \
715 child = __of_get_next_child(parent, child))
716
698/** 717/**
699 * of_get_next_child - Iterate a node childs 718 * of_get_next_child - Iterate a node childs
700 * @node: parent node 719 * @node: parent node
@@ -710,11 +729,7 @@ struct device_node *of_get_next_child(const struct device_node *node,
710 unsigned long flags; 729 unsigned long flags;
711 730
712 raw_spin_lock_irqsave(&devtree_lock, flags); 731 raw_spin_lock_irqsave(&devtree_lock, flags);
713 next = prev ? prev->sibling : node->child; 732 next = __of_get_next_child(node, prev);
714 for (; next; next = next->sibling)
715 if (of_node_get(next))
716 break;
717 of_node_put(prev);
718 raw_spin_unlock_irqrestore(&devtree_lock, flags); 733 raw_spin_unlock_irqrestore(&devtree_lock, flags);
719 return next; 734 return next;
720} 735}
@@ -734,6 +749,9 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
734 struct device_node *next; 749 struct device_node *next;
735 unsigned long flags; 750 unsigned long flags;
736 751
752 if (!node)
753 return NULL;
754
737 raw_spin_lock_irqsave(&devtree_lock, flags); 755 raw_spin_lock_irqsave(&devtree_lock, flags);
738 next = prev ? prev->sibling : node->child; 756 next = prev ? prev->sibling : node->child;
739 for (; next; next = next->sibling) { 757 for (; next; next = next->sibling) {
@@ -771,23 +789,78 @@ struct device_node *of_get_child_by_name(const struct device_node *node,
771} 789}
772EXPORT_SYMBOL(of_get_child_by_name); 790EXPORT_SYMBOL(of_get_child_by_name);
773 791
792static struct device_node *__of_find_node_by_path(struct device_node *parent,
793 const char *path)
794{
795 struct device_node *child;
796 int len = strchrnul(path, '/') - path;
797
798 if (!len)
799 return NULL;
800
801 __for_each_child_of_node(parent, child) {
802 const char *name = strrchr(child->full_name, '/');
803 if (WARN(!name, "malformed device_node %s\n", child->full_name))
804 continue;
805 name++;
806 if (strncmp(path, name, len) == 0 && (strlen(name) == len))
807 return child;
808 }
809 return NULL;
810}
811
774/** 812/**
775 * of_find_node_by_path - Find a node matching a full OF path 813 * of_find_node_by_path - Find a node matching a full OF path
776 * @path: The full path to match 814 * @path: Either the full path to match, or if the path does not
815 * start with '/', the name of a property of the /aliases
816 * node (an alias). In the case of an alias, the node
817 * matching the alias' value will be returned.
818 *
819 * Valid paths:
820 * /foo/bar Full path
821 * foo Valid alias
822 * foo/bar Valid alias + relative path
777 * 823 *
778 * Returns a node pointer with refcount incremented, use 824 * Returns a node pointer with refcount incremented, use
779 * of_node_put() on it when done. 825 * of_node_put() on it when done.
780 */ 826 */
781struct device_node *of_find_node_by_path(const char *path) 827struct device_node *of_find_node_by_path(const char *path)
782{ 828{
783 struct device_node *np = of_allnodes; 829 struct device_node *np = NULL;
830 struct property *pp;
784 unsigned long flags; 831 unsigned long flags;
785 832
833 if (strcmp(path, "/") == 0)
834 return of_node_get(of_allnodes);
835
836 /* The path could begin with an alias */
837 if (*path != '/') {
838 char *p = strchrnul(path, '/');
839 int len = p - path;
840
841 /* of_aliases must not be NULL */
842 if (!of_aliases)
843 return NULL;
844
845 for_each_property_of_node(of_aliases, pp) {
846 if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) {
847 np = of_find_node_by_path(pp->value);
848 break;
849 }
850 }
851 if (!np)
852 return NULL;
853 path = p;
854 }
855
856 /* Step down the tree matching path components */
786 raw_spin_lock_irqsave(&devtree_lock, flags); 857 raw_spin_lock_irqsave(&devtree_lock, flags);
787 for (; np; np = np->allnext) { 858 if (!np)
788 if (np->full_name && (of_node_cmp(np->full_name, path) == 0) 859 np = of_node_get(of_allnodes);
789 && of_node_get(np)) 860 while (np && *path == '/') {
790 break; 861 path++; /* Increment past '/' delimiter */
862 np = __of_find_node_by_path(np, path);
863 path = strchrnul(path, '/');
791 } 864 }
792 raw_spin_unlock_irqrestore(&devtree_lock, flags); 865 raw_spin_unlock_irqrestore(&devtree_lock, flags);
793 return np; 866 return np;
@@ -1800,7 +1873,7 @@ int of_update_property(struct device_node *np, struct property *newprop)
1800{ 1873{
1801 struct property **next, *oldprop; 1874 struct property **next, *oldprop;
1802 unsigned long flags; 1875 unsigned long flags;
1803 int rc, found = 0; 1876 int rc;
1804 1877
1805 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); 1878 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
1806 if (rc) 1879 if (rc)
@@ -1809,34 +1882,34 @@ int of_update_property(struct device_node *np, struct property *newprop)
1809 if (!newprop->name) 1882 if (!newprop->name)
1810 return -EINVAL; 1883 return -EINVAL;
1811 1884
1812 oldprop = of_find_property(np, newprop->name, NULL);
1813 if (!oldprop)
1814 return of_add_property(np, newprop);
1815
1816 raw_spin_lock_irqsave(&devtree_lock, flags); 1885 raw_spin_lock_irqsave(&devtree_lock, flags);
1817 next = &np->properties; 1886 next = &np->properties;
1818 while (*next) { 1887 oldprop = __of_find_property(np, newprop->name, NULL);
1888 if (!oldprop) {
1889 /* add the new node */
1890 rc = __of_add_property(np, newprop);
1891 } else while (*next) {
1892 /* replace the node */
1819 if (*next == oldprop) { 1893 if (*next == oldprop) {
1820 /* found the node */
1821 newprop->next = oldprop->next; 1894 newprop->next = oldprop->next;
1822 *next = newprop; 1895 *next = newprop;
1823 oldprop->next = np->deadprops; 1896 oldprop->next = np->deadprops;
1824 np->deadprops = oldprop; 1897 np->deadprops = oldprop;
1825 found = 1;
1826 break; 1898 break;
1827 } 1899 }
1828 next = &(*next)->next; 1900 next = &(*next)->next;
1829 } 1901 }
1830 raw_spin_unlock_irqrestore(&devtree_lock, flags); 1902 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1831 if (!found) 1903 if (rc)
1832 return -ENODEV; 1904 return rc;
1833 1905
1834 /* At early boot, bail out and defer setup to of_init() */ 1906 /* At early boot, bail out and defer setup to of_init() */
1835 if (!of_kset) 1907 if (!of_kset)
1836 return found ? 0 : -ENODEV; 1908 return 0;
1837 1909
1838 /* Update the sysfs attribute */ 1910 /* Update the sysfs attribute */
1839 sysfs_remove_bin_file(&np->kobj, &oldprop->attr); 1911 if (oldprop)
1912 sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
1840 __of_add_property_sysfs(np, newprop); 1913 __of_add_property_sysfs(np, newprop);
1841 1914
1842 return 0; 1915 return 0;
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 7a2ef7bb8022..c4cddf0cd96d 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -12,7 +12,6 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/initrd.h> 13#include <linux/initrd.h>
14#include <linux/memblock.h> 14#include <linux/memblock.h>
15#include <linux/module.h>
16#include <linux/of.h> 15#include <linux/of.h>
17#include <linux/of_fdt.h> 16#include <linux/of_fdt.h>
18#include <linux/of_reserved_mem.h> 17#include <linux/of_reserved_mem.h>
@@ -20,62 +19,13 @@
20#include <linux/string.h> 19#include <linux/string.h>
21#include <linux/errno.h> 20#include <linux/errno.h>
22#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/libfdt.h>
23#include <linux/debugfs.h>
24#include <linux/serial_core.h>
23 25
24#include <asm/setup.h> /* for COMMAND_LINE_SIZE */ 26#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
25#ifdef CONFIG_PPC
26#include <asm/machdep.h>
27#endif /* CONFIG_PPC */
28
29#include <asm/page.h> 27#include <asm/page.h>
30 28
31char *of_fdt_get_string(struct boot_param_header *blob, u32 offset)
32{
33 return ((char *)blob) +
34 be32_to_cpu(blob->off_dt_strings) + offset;
35}
36
37/**
38 * of_fdt_get_property - Given a node in the given flat blob, return
39 * the property ptr
40 */
41void *of_fdt_get_property(struct boot_param_header *blob,
42 unsigned long node, const char *name,
43 unsigned long *size)
44{
45 unsigned long p = node;
46
47 do {
48 u32 tag = be32_to_cpup((__be32 *)p);
49 u32 sz, noff;
50 const char *nstr;
51
52 p += 4;
53 if (tag == OF_DT_NOP)
54 continue;
55 if (tag != OF_DT_PROP)
56 return NULL;
57
58 sz = be32_to_cpup((__be32 *)p);
59 noff = be32_to_cpup((__be32 *)(p + 4));
60 p += 8;
61 if (be32_to_cpu(blob->version) < 0x10)
62 p = ALIGN(p, sz >= 8 ? 8 : 4);
63
64 nstr = of_fdt_get_string(blob, noff);
65 if (nstr == NULL) {
66 pr_warning("Can't find property index name !\n");
67 return NULL;
68 }
69 if (strcmp(name, nstr) == 0) {
70 if (size)
71 *size = sz;
72 return (void *)p;
73 }
74 p += sz;
75 p = ALIGN(p, 4);
76 } while (1);
77}
78
79/** 29/**
80 * of_fdt_is_compatible - Return true if given node from the given blob has 30 * of_fdt_is_compatible - Return true if given node from the given blob has
81 * compat in its compatible list 31 * compat in its compatible list
@@ -86,13 +36,14 @@ void *of_fdt_get_property(struct boot_param_header *blob,
86 * On match, returns a non-zero value with smaller values returned for more 36 * On match, returns a non-zero value with smaller values returned for more
87 * specific compatible values. 37 * specific compatible values.
88 */ 38 */
89int of_fdt_is_compatible(struct boot_param_header *blob, 39int of_fdt_is_compatible(const void *blob,
90 unsigned long node, const char *compat) 40 unsigned long node, const char *compat)
91{ 41{
92 const char *cp; 42 const char *cp;
93 unsigned long cplen, l, score = 0; 43 int cplen;
44 unsigned long l, score = 0;
94 45
95 cp = of_fdt_get_property(blob, node, "compatible", &cplen); 46 cp = fdt_getprop(blob, node, "compatible", &cplen);
96 if (cp == NULL) 47 if (cp == NULL)
97 return 0; 48 return 0;
98 while (cplen > 0) { 49 while (cplen > 0) {
@@ -110,7 +61,7 @@ int of_fdt_is_compatible(struct boot_param_header *blob,
110/** 61/**
111 * of_fdt_match - Return true if node matches a list of compatible values 62 * of_fdt_match - Return true if node matches a list of compatible values
112 */ 63 */
113int of_fdt_match(struct boot_param_header *blob, unsigned long node, 64int of_fdt_match(const void *blob, unsigned long node,
114 const char *const *compat) 65 const char *const *compat)
115{ 66{
116 unsigned int tmp, score = 0; 67 unsigned int tmp, score = 0;
@@ -149,30 +100,29 @@ static void *unflatten_dt_alloc(void **mem, unsigned long size,
149 * @allnextpp: pointer to ->allnext from last allocated device_node 100 * @allnextpp: pointer to ->allnext from last allocated device_node
150 * @fpsize: Size of the node path up at the current depth. 101 * @fpsize: Size of the node path up at the current depth.
151 */ 102 */
152static void * unflatten_dt_node(struct boot_param_header *blob, 103static void * unflatten_dt_node(void *blob,
153 void *mem, 104 void *mem,
154 void **p, 105 int *poffset,
155 struct device_node *dad, 106 struct device_node *dad,
156 struct device_node ***allnextpp, 107 struct device_node ***allnextpp,
157 unsigned long fpsize) 108 unsigned long fpsize)
158{ 109{
110 const __be32 *p;
159 struct device_node *np; 111 struct device_node *np;
160 struct property *pp, **prev_pp = NULL; 112 struct property *pp, **prev_pp = NULL;
161 char *pathp; 113 const char *pathp;
162 u32 tag;
163 unsigned int l, allocl; 114 unsigned int l, allocl;
115 static int depth = 0;
116 int old_depth;
117 int offset;
164 int has_name = 0; 118 int has_name = 0;
165 int new_format = 0; 119 int new_format = 0;
166 120
167 tag = be32_to_cpup(*p); 121 pathp = fdt_get_name(blob, *poffset, &l);
168 if (tag != OF_DT_BEGIN_NODE) { 122 if (!pathp)
169 pr_err("Weird tag at start of node: %x\n", tag);
170 return mem; 123 return mem;
171 } 124
172 *p += 4; 125 allocl = l++;
173 pathp = *p;
174 l = allocl = strlen(pathp) + 1;
175 *p = PTR_ALIGN(*p + l, 4);
176 126
177 /* version 0x10 has a more compact unit name here instead of the full 127 /* version 0x10 has a more compact unit name here instead of the full
178 * path. we accumulate the full path size using "fpsize", we'll rebuild 128 * path. we accumulate the full path size using "fpsize", we'll rebuild
@@ -190,7 +140,7 @@ static void * unflatten_dt_node(struct boot_param_header *blob,
190 fpsize = 1; 140 fpsize = 1;
191 allocl = 2; 141 allocl = 2;
192 l = 1; 142 l = 1;
193 *pathp = '\0'; 143 pathp = "";
194 } else { 144 } else {
195 /* account for '/' and path size minus terminal 0 145 /* account for '/' and path size minus terminal 0
196 * already in 'l' 146 * already in 'l'
@@ -237,32 +187,23 @@ static void * unflatten_dt_node(struct boot_param_header *blob,
237 } 187 }
238 } 188 }
239 /* process properties */ 189 /* process properties */
240 while (1) { 190 for (offset = fdt_first_property_offset(blob, *poffset);
241 u32 sz, noff; 191 (offset >= 0);
242 char *pname; 192 (offset = fdt_next_property_offset(blob, offset))) {
243 193 const char *pname;
244 tag = be32_to_cpup(*p); 194 u32 sz;
245 if (tag == OF_DT_NOP) { 195
246 *p += 4; 196 if (!(p = fdt_getprop_by_offset(blob, offset, &pname, &sz))) {
247 continue; 197 offset = -FDT_ERR_INTERNAL;
248 }
249 if (tag != OF_DT_PROP)
250 break; 198 break;
251 *p += 4; 199 }
252 sz = be32_to_cpup(*p); 200
253 noff = be32_to_cpup(*p + 4);
254 *p += 8;
255 if (be32_to_cpu(blob->version) < 0x10)
256 *p = PTR_ALIGN(*p, sz >= 8 ? 8 : 4);
257
258 pname = of_fdt_get_string(blob, noff);
259 if (pname == NULL) { 201 if (pname == NULL) {
260 pr_info("Can't find property name in list !\n"); 202 pr_info("Can't find property name in list !\n");
261 break; 203 break;
262 } 204 }
263 if (strcmp(pname, "name") == 0) 205 if (strcmp(pname, "name") == 0)
264 has_name = 1; 206 has_name = 1;
265 l = strlen(pname) + 1;
266 pp = unflatten_dt_alloc(&mem, sizeof(struct property), 207 pp = unflatten_dt_alloc(&mem, sizeof(struct property),
267 __alignof__(struct property)); 208 __alignof__(struct property));
268 if (allnextpp) { 209 if (allnextpp) {
@@ -274,26 +215,25 @@ static void * unflatten_dt_node(struct boot_param_header *blob,
274 if ((strcmp(pname, "phandle") == 0) || 215 if ((strcmp(pname, "phandle") == 0) ||
275 (strcmp(pname, "linux,phandle") == 0)) { 216 (strcmp(pname, "linux,phandle") == 0)) {
276 if (np->phandle == 0) 217 if (np->phandle == 0)
277 np->phandle = be32_to_cpup((__be32*)*p); 218 np->phandle = be32_to_cpup(p);
278 } 219 }
279 /* And we process the "ibm,phandle" property 220 /* And we process the "ibm,phandle" property
280 * used in pSeries dynamic device tree 221 * used in pSeries dynamic device tree
281 * stuff */ 222 * stuff */
282 if (strcmp(pname, "ibm,phandle") == 0) 223 if (strcmp(pname, "ibm,phandle") == 0)
283 np->phandle = be32_to_cpup((__be32 *)*p); 224 np->phandle = be32_to_cpup(p);
284 pp->name = pname; 225 pp->name = (char *)pname;
285 pp->length = sz; 226 pp->length = sz;
286 pp->value = *p; 227 pp->value = (__be32 *)p;
287 *prev_pp = pp; 228 *prev_pp = pp;
288 prev_pp = &pp->next; 229 prev_pp = &pp->next;
289 } 230 }
290 *p = PTR_ALIGN((*p) + sz, 4);
291 } 231 }
292 /* with version 0x10 we may not have the name property, recreate 232 /* with version 0x10 we may not have the name property, recreate
293 * it here from the unit name if absent 233 * it here from the unit name if absent
294 */ 234 */
295 if (!has_name) { 235 if (!has_name) {
296 char *p1 = pathp, *ps = pathp, *pa = NULL; 236 const char *p1 = pathp, *ps = pathp, *pa = NULL;
297 int sz; 237 int sz;
298 238
299 while (*p1) { 239 while (*p1) {
@@ -330,19 +270,18 @@ static void * unflatten_dt_node(struct boot_param_header *blob,
330 if (!np->type) 270 if (!np->type)
331 np->type = "<NULL>"; 271 np->type = "<NULL>";
332 } 272 }
333 while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) { 273
334 if (tag == OF_DT_NOP) 274 old_depth = depth;
335 *p += 4; 275 *poffset = fdt_next_node(blob, *poffset, &depth);
336 else 276 if (depth < 0)
337 mem = unflatten_dt_node(blob, mem, p, np, allnextpp, 277 depth = 0;
338 fpsize); 278 while (*poffset > 0 && depth > old_depth)
339 tag = be32_to_cpup(*p); 279 mem = unflatten_dt_node(blob, mem, poffset, np, allnextpp,
340 } 280 fpsize);
341 if (tag != OF_DT_END_NODE) { 281
342 pr_err("Weird tag at end of node: %x\n", tag); 282 if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND)
343 return mem; 283 pr_err("unflatten: error %d processing FDT\n", *poffset);
344 } 284
345 *p += 4;
346 return mem; 285 return mem;
347} 286}
348 287
@@ -358,12 +297,13 @@ static void * unflatten_dt_node(struct boot_param_header *blob,
358 * @dt_alloc: An allocator that provides a virtual address to memory 297 * @dt_alloc: An allocator that provides a virtual address to memory
359 * for the resulting tree 298 * for the resulting tree
360 */ 299 */
361static void __unflatten_device_tree(struct boot_param_header *blob, 300static void __unflatten_device_tree(void *blob,
362 struct device_node **mynodes, 301 struct device_node **mynodes,
363 void * (*dt_alloc)(u64 size, u64 align)) 302 void * (*dt_alloc)(u64 size, u64 align))
364{ 303{
365 unsigned long size; 304 unsigned long size;
366 void *start, *mem; 305 int start;
306 void *mem;
367 struct device_node **allnextp = mynodes; 307 struct device_node **allnextp = mynodes;
368 308
369 pr_debug(" -> unflatten_device_tree()\n"); 309 pr_debug(" -> unflatten_device_tree()\n");
@@ -374,18 +314,18 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
374 } 314 }
375 315
376 pr_debug("Unflattening device tree:\n"); 316 pr_debug("Unflattening device tree:\n");
377 pr_debug("magic: %08x\n", be32_to_cpu(blob->magic)); 317 pr_debug("magic: %08x\n", fdt_magic(blob));
378 pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize)); 318 pr_debug("size: %08x\n", fdt_totalsize(blob));
379 pr_debug("version: %08x\n", be32_to_cpu(blob->version)); 319 pr_debug("version: %08x\n", fdt_version(blob));
380 320
381 if (be32_to_cpu(blob->magic) != OF_DT_HEADER) { 321 if (fdt_check_header(blob)) {
382 pr_err("Invalid device tree blob header\n"); 322 pr_err("Invalid device tree blob header\n");
383 return; 323 return;
384 } 324 }
385 325
386 /* First pass, scan for size */ 326 /* First pass, scan for size */
387 start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct); 327 start = 0;
388 size = (unsigned long)unflatten_dt_node(blob, 0, &start, NULL, NULL, 0); 328 size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0);
389 size = ALIGN(size, 4); 329 size = ALIGN(size, 4);
390 330
391 pr_debug(" size is %lx, allocating...\n", size); 331 pr_debug(" size is %lx, allocating...\n", size);
@@ -399,10 +339,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
399 pr_debug(" unflattening %p...\n", mem); 339 pr_debug(" unflattening %p...\n", mem);
400 340
401 /* Second pass, do actual unflattening */ 341 /* Second pass, do actual unflattening */
402 start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct); 342 start = 0;
403 unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); 343 unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
404 if (be32_to_cpup(start) != OF_DT_END)
405 pr_warning("Weird tag at end of tree: %08x\n", be32_to_cpup(start));
406 if (be32_to_cpup(mem + size) != 0xdeadbeef) 344 if (be32_to_cpup(mem + size) != 0xdeadbeef)
407 pr_warning("End of tree marker overwritten: %08x\n", 345 pr_warning("End of tree marker overwritten: %08x\n",
408 be32_to_cpup(mem + size)); 346 be32_to_cpup(mem + size));
@@ -427,9 +365,7 @@ static void *kernel_tree_alloc(u64 size, u64 align)
427void of_fdt_unflatten_tree(unsigned long *blob, 365void of_fdt_unflatten_tree(unsigned long *blob,
428 struct device_node **mynodes) 366 struct device_node **mynodes)
429{ 367{
430 struct boot_param_header *device_tree = 368 __unflatten_device_tree(blob, mynodes, &kernel_tree_alloc);
431 (struct boot_param_header *)blob;
432 __unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
433} 369}
434EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); 370EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
435 371
@@ -437,7 +373,7 @@ EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
437int __initdata dt_root_addr_cells; 373int __initdata dt_root_addr_cells;
438int __initdata dt_root_size_cells; 374int __initdata dt_root_size_cells;
439 375
440struct boot_param_header *initial_boot_params; 376void *initial_boot_params;
441 377
442#ifdef CONFIG_OF_EARLY_FLATTREE 378#ifdef CONFIG_OF_EARLY_FLATTREE
443 379
@@ -449,8 +385,8 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
449{ 385{
450 int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32); 386 int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
451 phys_addr_t base, size; 387 phys_addr_t base, size;
452 unsigned long len; 388 int len;
453 __be32 *prop; 389 const __be32 *prop;
454 int nomap, first = 1; 390 int nomap, first = 1;
455 391
456 prop = of_get_flat_dt_prop(node, "reg", &len); 392 prop = of_get_flat_dt_prop(node, "reg", &len);
@@ -493,7 +429,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
493 */ 429 */
494static int __init __reserved_mem_check_root(unsigned long node) 430static int __init __reserved_mem_check_root(unsigned long node)
495{ 431{
496 __be32 *prop; 432 const __be32 *prop;
497 433
498 prop = of_get_flat_dt_prop(node, "#size-cells", NULL); 434 prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
499 if (!prop || be32_to_cpup(prop) != dt_root_size_cells) 435 if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
@@ -557,9 +493,25 @@ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname,
557 */ 493 */
558void __init early_init_fdt_scan_reserved_mem(void) 494void __init early_init_fdt_scan_reserved_mem(void)
559{ 495{
496 int n;
497 u64 base, size;
498
560 if (!initial_boot_params) 499 if (!initial_boot_params)
561 return; 500 return;
562 501
502 /* Reserve the dtb region */
503 early_init_dt_reserve_memory_arch(__pa(initial_boot_params),
504 fdt_totalsize(initial_boot_params),
505 0);
506
507 /* Process header /memreserve/ fields */
508 for (n = 0; ; n++) {
509 fdt_get_mem_rsv(initial_boot_params, n, &base, &size);
510 if (!size)
511 break;
512 early_init_dt_reserve_memory_arch(base, size, 0);
513 }
514
563 of_scan_flat_dt(__fdt_scan_reserved_mem, NULL); 515 of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
564 fdt_init_reserved_mem(); 516 fdt_init_reserved_mem();
565} 517}
@@ -578,47 +530,19 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
578 void *data), 530 void *data),
579 void *data) 531 void *data)
580{ 532{
581 unsigned long p = ((unsigned long)initial_boot_params) + 533 const void *blob = initial_boot_params;
582 be32_to_cpu(initial_boot_params->off_dt_struct); 534 const char *pathp;
583 int rc = 0; 535 int offset, rc = 0, depth = -1;
584 int depth = -1; 536
585 537 for (offset = fdt_next_node(blob, -1, &depth);
586 do { 538 offset >= 0 && depth >= 0 && !rc;
587 u32 tag = be32_to_cpup((__be32 *)p); 539 offset = fdt_next_node(blob, offset, &depth)) {
588 const char *pathp; 540
589 541 pathp = fdt_get_name(blob, offset, NULL);
590 p += 4;
591 if (tag == OF_DT_END_NODE) {
592 depth--;
593 continue;
594 }
595 if (tag == OF_DT_NOP)
596 continue;
597 if (tag == OF_DT_END)
598 break;
599 if (tag == OF_DT_PROP) {
600 u32 sz = be32_to_cpup((__be32 *)p);
601 p += 8;
602 if (be32_to_cpu(initial_boot_params->version) < 0x10)
603 p = ALIGN(p, sz >= 8 ? 8 : 4);
604 p += sz;
605 p = ALIGN(p, 4);
606 continue;
607 }
608 if (tag != OF_DT_BEGIN_NODE) {
609 pr_err("Invalid tag %x in flat device tree!\n", tag);
610 return -EINVAL;
611 }
612 depth++;
613 pathp = (char *)p;
614 p = ALIGN(p + strlen(pathp) + 1, 4);
615 if (*pathp == '/') 542 if (*pathp == '/')
616 pathp = kbasename(pathp); 543 pathp = kbasename(pathp);
617 rc = it(p, pathp, depth, data); 544 rc = it(offset, pathp, depth, data);
618 if (rc != 0) 545 }
619 break;
620 } while (1);
621
622 return rc; 546 return rc;
623} 547}
624 548
@@ -627,14 +551,15 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
627 */ 551 */
628unsigned long __init of_get_flat_dt_root(void) 552unsigned long __init of_get_flat_dt_root(void)
629{ 553{
630 unsigned long p = ((unsigned long)initial_boot_params) + 554 return 0;
631 be32_to_cpu(initial_boot_params->off_dt_struct); 555}
632 556
633 while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) 557/**
634 p += 4; 558 * of_get_flat_dt_size - Return the total size of the FDT
635 BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); 559 */
636 p += 4; 560int __init of_get_flat_dt_size(void)
637 return ALIGN(p + strlen((char *)p) + 1, 4); 561{
562 return fdt_totalsize(initial_boot_params);
638} 563}
639 564
640/** 565/**
@@ -643,10 +568,10 @@ unsigned long __init of_get_flat_dt_root(void)
643 * This function can be used within scan_flattened_dt callback to get 568 * This function can be used within scan_flattened_dt callback to get
644 * access to properties 569 * access to properties
645 */ 570 */
646void *__init of_get_flat_dt_prop(unsigned long node, const char *name, 571const void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
647 unsigned long *size) 572 int *size)
648{ 573{
649 return of_fdt_get_property(initial_boot_params, node, name, size); 574 return fdt_getprop(initial_boot_params, node, name, size);
650} 575}
651 576
652/** 577/**
@@ -676,73 +601,6 @@ struct fdt_scan_status {
676 void *data; 601 void *data;
677}; 602};
678 603
679/**
680 * fdt_scan_node_by_path - iterator for of_scan_flat_dt_by_path function
681 */
682static int __init fdt_scan_node_by_path(unsigned long node, const char *uname,
683 int depth, void *data)
684{
685 struct fdt_scan_status *st = data;
686
687 /*
688 * if scan at the requested fdt node has been completed,
689 * return -ENXIO to abort further scanning
690 */
691 if (depth <= st->depth)
692 return -ENXIO;
693
694 /* requested fdt node has been found, so call iterator function */
695 if (st->found)
696 return st->iterator(node, uname, depth, st->data);
697
698 /* check if scanning automata is entering next level of fdt nodes */
699 if (depth == st->depth + 1 &&
700 strncmp(st->name, uname, st->namelen) == 0 &&
701 uname[st->namelen] == 0) {
702 st->depth += 1;
703 if (st->name[st->namelen] == 0) {
704 st->found = 1;
705 } else {
706 const char *next = st->name + st->namelen + 1;
707 st->name = next;
708 st->namelen = strcspn(next, "/");
709 }
710 return 0;
711 }
712
713 /* scan next fdt node */
714 return 0;
715}
716
717/**
718 * of_scan_flat_dt_by_path - scan flattened tree blob and call callback on each
719 * child of the given path.
720 * @path: path to start searching for children
721 * @it: callback function
722 * @data: context data pointer
723 *
724 * This function is used to scan the flattened device-tree starting from the
725 * node given by path. It is used to extract information (like reserved
726 * memory), which is required on ealy boot before we can unflatten the tree.
727 */
728int __init of_scan_flat_dt_by_path(const char *path,
729 int (*it)(unsigned long node, const char *name, int depth, void *data),
730 void *data)
731{
732 struct fdt_scan_status st = {path, 0, -1, 0, it, data};
733 int ret = 0;
734
735 if (initial_boot_params)
736 ret = of_scan_flat_dt(fdt_scan_node_by_path, &st);
737
738 if (!st.found)
739 return -ENOENT;
740 else if (ret == -ENXIO) /* scan has been completed */
741 return 0;
742 else
743 return ret;
744}
745
746const char * __init of_flat_dt_get_machine_name(void) 604const char * __init of_flat_dt_get_machine_name(void)
747{ 605{
748 const char *name; 606 const char *name;
@@ -782,7 +640,7 @@ const void * __init of_flat_dt_match_machine(const void *default_match,
782 } 640 }
783 if (!best_data) { 641 if (!best_data) {
784 const char *prop; 642 const char *prop;
785 long size; 643 int size;
786 644
787 pr_err("\n unrecognized device tree list:\n[ "); 645 pr_err("\n unrecognized device tree list:\n[ ");
788 646
@@ -811,8 +669,8 @@ const void * __init of_flat_dt_match_machine(const void *default_match,
811static void __init early_init_dt_check_for_initrd(unsigned long node) 669static void __init early_init_dt_check_for_initrd(unsigned long node)
812{ 670{
813 u64 start, end; 671 u64 start, end;
814 unsigned long len; 672 int len;
815 __be32 *prop; 673 const __be32 *prop;
816 674
817 pr_debug("Looking for initrd properties... "); 675 pr_debug("Looking for initrd properties... ");
818 676
@@ -839,13 +697,68 @@ static inline void early_init_dt_check_for_initrd(unsigned long node)
839} 697}
840#endif /* CONFIG_BLK_DEV_INITRD */ 698#endif /* CONFIG_BLK_DEV_INITRD */
841 699
700#ifdef CONFIG_SERIAL_EARLYCON
701extern struct of_device_id __earlycon_of_table[];
702
703int __init early_init_dt_scan_chosen_serial(void)
704{
705 int offset;
706 const char *p;
707 int l;
708 const struct of_device_id *match = __earlycon_of_table;
709 const void *fdt = initial_boot_params;
710
711 offset = fdt_path_offset(fdt, "/chosen");
712 if (offset < 0)
713 offset = fdt_path_offset(fdt, "/chosen@0");
714 if (offset < 0)
715 return -ENOENT;
716
717 p = fdt_getprop(fdt, offset, "stdout-path", &l);
718 if (!p)
719 p = fdt_getprop(fdt, offset, "linux,stdout-path", &l);
720 if (!p || !l)
721 return -ENOENT;
722
723 /* Get the node specified by stdout-path */
724 offset = fdt_path_offset(fdt, p);
725 if (offset < 0)
726 return -ENODEV;
727
728 while (match->compatible) {
729 unsigned long addr;
730 if (fdt_node_check_compatible(fdt, offset, match->compatible)) {
731 match++;
732 continue;
733 }
734
735 addr = fdt_translate_address(fdt, offset);
736 if (!addr)
737 return -ENXIO;
738
739 of_setup_earlycon(addr, match->data);
740 return 0;
741 }
742 return -ENODEV;
743}
744
745static int __init setup_of_earlycon(char *buf)
746{
747 if (buf)
748 return 0;
749
750 return early_init_dt_scan_chosen_serial();
751}
752early_param("earlycon", setup_of_earlycon);
753#endif
754
842/** 755/**
843 * early_init_dt_scan_root - fetch the top level address and size cells 756 * early_init_dt_scan_root - fetch the top level address and size cells
844 */ 757 */
845int __init early_init_dt_scan_root(unsigned long node, const char *uname, 758int __init early_init_dt_scan_root(unsigned long node, const char *uname,
846 int depth, void *data) 759 int depth, void *data)
847{ 760{
848 __be32 *prop; 761 const __be32 *prop;
849 762
850 if (depth != 0) 763 if (depth != 0)
851 return 0; 764 return 0;
@@ -867,9 +780,9 @@ int __init early_init_dt_scan_root(unsigned long node, const char *uname,
867 return 1; 780 return 1;
868} 781}
869 782
870u64 __init dt_mem_next_cell(int s, __be32 **cellp) 783u64 __init dt_mem_next_cell(int s, const __be32 **cellp)
871{ 784{
872 __be32 *p = *cellp; 785 const __be32 *p = *cellp;
873 786
874 *cellp = p + s; 787 *cellp = p + s;
875 return of_read_number(p, s); 788 return of_read_number(p, s);
@@ -881,9 +794,9 @@ u64 __init dt_mem_next_cell(int s, __be32 **cellp)
881int __init early_init_dt_scan_memory(unsigned long node, const char *uname, 794int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
882 int depth, void *data) 795 int depth, void *data)
883{ 796{
884 char *type = of_get_flat_dt_prop(node, "device_type", NULL); 797 const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
885 __be32 *reg, *endp; 798 const __be32 *reg, *endp;
886 unsigned long l; 799 int l;
887 800
888 /* We are scanning "memory" nodes only */ 801 /* We are scanning "memory" nodes only */
889 if (type == NULL) { 802 if (type == NULL) {
@@ -891,7 +804,7 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
891 * The longtrail doesn't have a device_type on the 804 * The longtrail doesn't have a device_type on the
892 * /memory node, so look for the node called /memory@0. 805 * /memory node, so look for the node called /memory@0.
893 */ 806 */
894 if (depth != 1 || strcmp(uname, "memory@0") != 0) 807 if (!IS_ENABLED(CONFIG_PPC32) || depth != 1 || strcmp(uname, "memory@0") != 0)
895 return 0; 808 return 0;
896 } else if (strcmp(type, "memory") != 0) 809 } else if (strcmp(type, "memory") != 0)
897 return 0; 810 return 0;
@@ -904,7 +817,7 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
904 817
905 endp = reg + (l / sizeof(__be32)); 818 endp = reg + (l / sizeof(__be32));
906 819
907 pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n", 820 pr_debug("memory scan node %s, reg size %d, data: %x %x %x %x,\n",
908 uname, l, reg[0], reg[1], reg[2], reg[3]); 821 uname, l, reg[0], reg[1], reg[2], reg[3]);
909 822
910 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { 823 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
@@ -927,8 +840,8 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
927int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, 840int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
928 int depth, void *data) 841 int depth, void *data)
929{ 842{
930 unsigned long l; 843 int l;
931 char *p; 844 const char *p;
932 845
933 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); 846 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
934 847
@@ -1003,8 +916,8 @@ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align)
1003int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base, 916int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
1004 phys_addr_t size, bool nomap) 917 phys_addr_t size, bool nomap)
1005{ 918{
1006 pr_err("Reserved memory not supported, ignoring range 0x%llx - 0x%llx%s\n", 919 pr_err("Reserved memory not supported, ignoring range 0x%pa - 0x%pa%s\n",
1007 base, size, nomap ? " (nomap)" : ""); 920 &base, &size, nomap ? " (nomap)" : "");
1008 return -ENOSYS; 921 return -ENOSYS;
1009} 922}
1010#endif 923#endif
@@ -1018,7 +931,7 @@ bool __init early_init_dt_scan(void *params)
1018 initial_boot_params = params; 931 initial_boot_params = params;
1019 932
1020 /* check device tree validity */ 933 /* check device tree validity */
1021 if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { 934 if (fdt_check_header(params)) {
1022 initial_boot_params = NULL; 935 initial_boot_params = NULL;
1023 return false; 936 return false;
1024 } 937 }
@@ -1073,9 +986,9 @@ void __init unflatten_and_copy_device_tree(void)
1073 return; 986 return;
1074 } 987 }
1075 988
1076 size = __be32_to_cpu(initial_boot_params->totalsize); 989 size = fdt_totalsize(initial_boot_params);
1077 dt = early_init_dt_alloc_memory_arch(size, 990 dt = early_init_dt_alloc_memory_arch(size,
1078 __alignof__(struct boot_param_header)); 991 roundup_pow_of_two(FDT_V17_SIZE));
1079 992
1080 if (dt) { 993 if (dt) {
1081 memcpy(dt, initial_boot_params, size); 994 memcpy(dt, initial_boot_params, size);
@@ -1084,4 +997,27 @@ void __init unflatten_and_copy_device_tree(void)
1084 unflatten_device_tree(); 997 unflatten_device_tree();
1085} 998}
1086 999
1000#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
1001static struct debugfs_blob_wrapper flat_dt_blob;
1002
1003static int __init of_flat_dt_debugfs_export_fdt(void)
1004{
1005 struct dentry *d = debugfs_create_dir("device-tree", NULL);
1006
1007 if (!d)
1008 return -ENOENT;
1009
1010 flat_dt_blob.data = initial_boot_params;
1011 flat_dt_blob.size = fdt_totalsize(initial_boot_params);
1012
1013 d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
1014 d, &flat_dt_blob);
1015 if (!d)
1016 return -ENOENT;
1017
1018 return 0;
1019}
1020module_init(of_flat_dt_debugfs_export_fdt);
1021#endif
1022
1087#endif /* CONFIG_OF_EARLY_FLATTREE */ 1023#endif /* CONFIG_OF_EARLY_FLATTREE */
diff --git a/drivers/of/fdt_address.c b/drivers/of/fdt_address.c
new file mode 100644
index 000000000000..8d3dc6fbdb7a
--- /dev/null
+++ b/drivers/of/fdt_address.c
@@ -0,0 +1,241 @@
1/*
2 * FDT Address translation based on u-boot fdt_support.c which in turn was
3 * based on the kernel unflattened DT address translation code.
4 *
5 * (C) Copyright 2007
6 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
7 *
8 * Copyright 2010-2011 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 */
15#include <linux/kernel.h>
16#include <linux/libfdt.h>
17#include <linux/of.h>
18#include <linux/of_fdt.h>
19#include <linux/sizes.h>
20
21/* Max address size we deal with */
22#define OF_MAX_ADDR_CELLS 4
23#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
24 (ns) > 0)
25
26/* Debug utility */
27#ifdef DEBUG
28static void __init of_dump_addr(const char *s, const __be32 *addr, int na)
29{
30 pr_debug("%s", s);
31 while(na--)
32 pr_cont(" %08x", *(addr++));
33 pr_debug("\n");
34}
35#else
36static void __init of_dump_addr(const char *s, const __be32 *addr, int na) { }
37#endif
38
39/* Callbacks for bus specific translators */
40struct of_bus {
41 void (*count_cells)(const void *blob, int parentoffset,
42 int *addrc, int *sizec);
43 u64 (*map)(__be32 *addr, const __be32 *range,
44 int na, int ns, int pna);
45 int (*translate)(__be32 *addr, u64 offset, int na);
46};
47
48/* Default translator (generic bus) */
49static void __init fdt_bus_default_count_cells(const void *blob, int parentoffset,
50 int *addrc, int *sizec)
51{
52 const __be32 *prop;
53
54 if (addrc) {
55 prop = fdt_getprop(blob, parentoffset, "#address-cells", NULL);
56 if (prop)
57 *addrc = be32_to_cpup(prop);
58 else
59 *addrc = dt_root_addr_cells;
60 }
61
62 if (sizec) {
63 prop = fdt_getprop(blob, parentoffset, "#size-cells", NULL);
64 if (prop)
65 *sizec = be32_to_cpup(prop);
66 else
67 *sizec = dt_root_size_cells;
68 }
69}
70
71static u64 __init fdt_bus_default_map(__be32 *addr, const __be32 *range,
72 int na, int ns, int pna)
73{
74 u64 cp, s, da;
75
76 cp = of_read_number(range, na);
77 s = of_read_number(range + na + pna, ns);
78 da = of_read_number(addr, na);
79
80 pr_debug("FDT: default map, cp=%llx, s=%llx, da=%llx\n",
81 cp, s, da);
82
83 if (da < cp || da >= (cp + s))
84 return OF_BAD_ADDR;
85 return da - cp;
86}
87
88static int __init fdt_bus_default_translate(__be32 *addr, u64 offset, int na)
89{
90 u64 a = of_read_number(addr, na);
91 memset(addr, 0, na * 4);
92 a += offset;
93 if (na > 1)
94 addr[na - 2] = cpu_to_fdt32(a >> 32);
95 addr[na - 1] = cpu_to_fdt32(a & 0xffffffffu);
96
97 return 0;
98}
99
100/* Array of bus specific translators */
101static const struct of_bus of_busses[] __initconst = {
102 /* Default */
103 {
104 .count_cells = fdt_bus_default_count_cells,
105 .map = fdt_bus_default_map,
106 .translate = fdt_bus_default_translate,
107 },
108};
109
110static int __init fdt_translate_one(const void *blob, int parent,
111 const struct of_bus *bus,
112 const struct of_bus *pbus, __be32 *addr,
113 int na, int ns, int pna, const char *rprop)
114{
115 const __be32 *ranges;
116 int rlen;
117 int rone;
118 u64 offset = OF_BAD_ADDR;
119
120 ranges = fdt_getprop(blob, parent, rprop, &rlen);
121 if (!ranges)
122 return 1;
123 if (rlen == 0) {
124 offset = of_read_number(addr, na);
125 memset(addr, 0, pna * 4);
126 pr_debug("FDT: empty ranges, 1:1 translation\n");
127 goto finish;
128 }
129
130 pr_debug("FDT: walking ranges...\n");
131
132 /* Now walk through the ranges */
133 rlen /= 4;
134 rone = na + pna + ns;
135 for (; rlen >= rone; rlen -= rone, ranges += rone) {
136 offset = bus->map(addr, ranges, na, ns, pna);
137 if (offset != OF_BAD_ADDR)
138 break;
139 }
140 if (offset == OF_BAD_ADDR) {
141 pr_debug("FDT: not found !\n");
142 return 1;
143 }
144 memcpy(addr, ranges + na, 4 * pna);
145
146 finish:
147 of_dump_addr("FDT: parent translation for:", addr, pna);
148 pr_debug("FDT: with offset: %llx\n", offset);
149
150 /* Translate it into parent bus space */
151 return pbus->translate(addr, offset, pna);
152}
153
154/*
155 * Translate an address from the device-tree into a CPU physical address,
156 * this walks up the tree and applies the various bus mappings on the
157 * way.
158 *
159 * Note: We consider that crossing any level with #size-cells == 0 to mean
160 * that translation is impossible (that is we are not dealing with a value
161 * that can be mapped to a cpu physical address). This is not really specified
162 * that way, but this is traditionally the way IBM at least do things
163 */
164u64 __init fdt_translate_address(const void *blob, int node_offset)
165{
166 int parent, len;
167 const struct of_bus *bus, *pbus;
168 const __be32 *reg;
169 __be32 addr[OF_MAX_ADDR_CELLS];
170 int na, ns, pna, pns;
171 u64 result = OF_BAD_ADDR;
172
173 pr_debug("FDT: ** translation for device %s **\n",
174 fdt_get_name(blob, node_offset, NULL));
175
176 reg = fdt_getprop(blob, node_offset, "reg", &len);
177 if (!reg) {
178 pr_err("FDT: warning: device tree node '%s' has no address.\n",
179 fdt_get_name(blob, node_offset, NULL));
180 goto bail;
181 }
182
183 /* Get parent & match bus type */
184 parent = fdt_parent_offset(blob, node_offset);
185 if (parent < 0)
186 goto bail;
187 bus = &of_busses[0];
188
189 /* Cound address cells & copy address locally */
190 bus->count_cells(blob, parent, &na, &ns);
191 if (!OF_CHECK_COUNTS(na, ns)) {
192 pr_err("FDT: Bad cell count for %s\n",
193 fdt_get_name(blob, node_offset, NULL));
194 goto bail;
195 }
196 memcpy(addr, reg, na * 4);
197
198 pr_debug("FDT: bus (na=%d, ns=%d) on %s\n",
199 na, ns, fdt_get_name(blob, parent, NULL));
200 of_dump_addr("OF: translating address:", addr, na);
201
202 /* Translate */
203 for (;;) {
204 /* Switch to parent bus */
205 node_offset = parent;
206 parent = fdt_parent_offset(blob, node_offset);
207
208 /* If root, we have finished */
209 if (parent < 0) {
210 pr_debug("FDT: reached root node\n");
211 result = of_read_number(addr, na);
212 break;
213 }
214
215 /* Get new parent bus and counts */
216 pbus = &of_busses[0];
217 pbus->count_cells(blob, parent, &pna, &pns);
218 if (!OF_CHECK_COUNTS(pna, pns)) {
219 pr_err("FDT: Bad cell count for %s\n",
220 fdt_get_name(blob, node_offset, NULL));
221 break;
222 }
223
224 pr_debug("FDT: parent bus (na=%d, ns=%d) on %s\n",
225 pna, pns, fdt_get_name(blob, parent, NULL));
226
227 /* Apply bus translation */
228 if (fdt_translate_one(blob, node_offset, bus, pbus,
229 addr, na, ns, pna, "ranges"))
230 break;
231
232 /* Complete the move up one level */
233 na = pna;
234 ns = pns;
235 bus = pbus;
236
237 of_dump_addr("FDT: one level translation:", addr, na);
238 }
239 bail:
240 return result;
241}
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 5aeb89411350..3e06a699352d 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -406,6 +406,28 @@ int of_irq_get(struct device_node *dev, int index)
406} 406}
407 407
408/** 408/**
409 * of_irq_get_byname - Decode a node's IRQ and return it as a Linux irq number
410 * @dev: pointer to device tree node
411 * @name: irq name
412 *
413 * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
414 * is not yet created, or error code in case of any other failure.
415 */
416int of_irq_get_byname(struct device_node *dev, const char *name)
417{
418 int index;
419
420 if (unlikely(!name))
421 return -EINVAL;
422
423 index = of_property_match_string(dev, "interrupt-names", name);
424 if (index < 0)
425 return index;
426
427 return of_irq_get(dev, index);
428}
429
430/**
409 * of_irq_count - Count the number of IRQs a node uses 431 * of_irq_count - Count the number of IRQs a node uses
410 * @dev: pointer to device tree node 432 * @dev: pointer to device tree node
411 */ 433 */
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
index 8736bc7676c5..1710d9dc7fc2 100644
--- a/drivers/of/of_pci_irq.c
+++ b/drivers/of/of_pci_irq.c
@@ -18,8 +18,6 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq
18{ 18{
19 struct device_node *dn, *ppnode; 19 struct device_node *dn, *ppnode;
20 struct pci_dev *ppdev; 20 struct pci_dev *ppdev;
21 u32 lspec;
22 __be32 lspec_be;
23 __be32 laddr[3]; 21 __be32 laddr[3];
24 u8 pin; 22 u8 pin;
25 int rc; 23 int rc;
@@ -46,7 +44,6 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq
46 return -ENODEV; 44 return -ENODEV;
47 45
48 /* Now we walk up the PCI tree */ 46 /* Now we walk up the PCI tree */
49 lspec = pin;
50 for (;;) { 47 for (;;) {
51 /* Get the pci_dev of our parent */ 48 /* Get the pci_dev of our parent */
52 ppdev = pdev->bus->self; 49 ppdev = pdev->bus->self;
@@ -80,14 +77,13 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq
80 /* We can only get here if we hit a P2P bridge with no node, 77 /* We can only get here if we hit a P2P bridge with no node,
81 * let's do standard swizzling and try again 78 * let's do standard swizzling and try again
82 */ 79 */
83 lspec = pci_swizzle_interrupt_pin(pdev, lspec); 80 pin = pci_swizzle_interrupt_pin(pdev, pin);
84 pdev = ppdev; 81 pdev = ppdev;
85 } 82 }
86 83
87 out_irq->np = ppnode; 84 out_irq->np = ppnode;
88 out_irq->args_count = 1; 85 out_irq->args_count = 1;
89 out_irq->args[0] = lspec; 86 out_irq->args[0] = pin;
90 lspec_be = cpu_to_be32(lspec);
91 laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); 87 laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
92 laddr[1] = laddr[2] = cpu_to_be32(0); 88 laddr[1] = laddr[2] = cpu_to_be32(0);
93 return of_irq_parse_raw(laddr, out_irq); 89 return of_irq_parse_raw(laddr, out_irq);
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index daaaf935911d..632aae861375 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -95,8 +95,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
95 int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32); 95 int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
96 phys_addr_t start = 0, end = 0; 96 phys_addr_t start = 0, end = 0;
97 phys_addr_t base = 0, align = 0, size; 97 phys_addr_t base = 0, align = 0, size;
98 unsigned long len; 98 int len;
99 __be32 *prop; 99 const __be32 *prop;
100 int nomap; 100 int nomap;
101 int ret; 101 int ret;
102 102
@@ -188,7 +188,7 @@ static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
188 if (!of_flat_dt_is_compatible(rmem->fdt_node, compat)) 188 if (!of_flat_dt_is_compatible(rmem->fdt_node, compat))
189 continue; 189 continue;
190 190
191 if (initfn(rmem, rmem->fdt_node, rmem->name) == 0) { 191 if (initfn(rmem) == 0) {
192 pr_info("Reserved memory: initialized node %s, compatible id %s\n", 192 pr_info("Reserved memory: initialized node %s, compatible id %s\n",
193 rmem->name, compat); 193 rmem->name, compat);
194 return 0; 194 return 0;
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index e8376d646d98..92c060e58b02 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -51,10 +51,6 @@ struct platform_device *of_find_device_by_node(struct device_node *np)
51} 51}
52EXPORT_SYMBOL(of_find_device_by_node); 52EXPORT_SYMBOL(of_find_device_by_node);
53 53
54#if defined(CONFIG_PPC_DCR)
55#include <asm/dcr.h>
56#endif
57
58#ifdef CONFIG_OF_ADDRESS 54#ifdef CONFIG_OF_ADDRESS
59/* 55/*
60 * The following routines scan a subtree and registers a device for 56 * The following routines scan a subtree and registers a device for
@@ -68,66 +64,35 @@ EXPORT_SYMBOL(of_find_device_by_node);
68 * of_device_make_bus_id - Use the device node data to assign a unique name 64 * of_device_make_bus_id - Use the device node data to assign a unique name
69 * @dev: pointer to device structure that is linked to a device tree node 65 * @dev: pointer to device structure that is linked to a device tree node
70 * 66 *
71 * This routine will first try using either the dcr-reg or the reg property 67 * This routine will first try using the translated bus address to
72 * value to derive a unique name. As a last resort it will use the node 68 * derive a unique name. If it cannot, then it will prepend names from
73 * name followed by a unique number. 69 * parent nodes until a unique name can be derived.
74 */ 70 */
75void of_device_make_bus_id(struct device *dev) 71void of_device_make_bus_id(struct device *dev)
76{ 72{
77 static atomic_t bus_no_reg_magic;
78 struct device_node *node = dev->of_node; 73 struct device_node *node = dev->of_node;
79 const __be32 *reg; 74 const __be32 *reg;
80 u64 addr; 75 u64 addr;
81 const __be32 *addrp;
82 int magic;
83 76
84#ifdef CONFIG_PPC_DCR 77 /* Construct the name, using parent nodes if necessary to ensure uniqueness */
85 /* 78 while (node->parent) {
86 * If it's a DCR based device, use 'd' for native DCRs 79 /*
87 * and 'D' for MMIO DCRs. 80 * If the address can be translated, then that is as much
88 */ 81 * uniqueness as we need. Make it the first component and return
89 reg = of_get_property(node, "dcr-reg", NULL); 82 */
90 if (reg) { 83 reg = of_get_property(node, "reg", NULL);
91#ifdef CONFIG_PPC_DCR_NATIVE 84 if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) {
92 dev_set_name(dev, "d%x.%s", *reg, node->name); 85 dev_set_name(dev, dev_name(dev) ? "%llx.%s:%s" : "%llx.%s",
93#else /* CONFIG_PPC_DCR_NATIVE */ 86 (unsigned long long)addr, node->name,
94 u64 addr = of_translate_dcr_address(node, *reg, NULL); 87 dev_name(dev));
95 if (addr != OF_BAD_ADDR) {
96 dev_set_name(dev, "D%llx.%s",
97 (unsigned long long)addr, node->name);
98 return; 88 return;
99 } 89 }
100#endif /* !CONFIG_PPC_DCR_NATIVE */
101 }
102#endif /* CONFIG_PPC_DCR */
103 90
104 /* 91 /* format arguments only used if dev_name() resolves to NULL */
105 * For MMIO, get the physical address 92 dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s",
106 */ 93 strrchr(node->full_name, '/') + 1, dev_name(dev));
107 reg = of_get_property(node, "reg", NULL); 94 node = node->parent;
108 if (reg) {
109 if (of_can_translate_address(node)) {
110 addr = of_translate_address(node, reg);
111 } else {
112 addrp = of_get_address(node, 0, NULL, NULL);
113 if (addrp)
114 addr = of_read_number(addrp, 1);
115 else
116 addr = OF_BAD_ADDR;
117 }
118 if (addr != OF_BAD_ADDR) {
119 dev_set_name(dev, "%llx.%s",
120 (unsigned long long)addr, node->name);
121 return;
122 }
123 } 95 }
124
125 /*
126 * No BusID, use the node name and add a globally incremented
127 * counter (and pray...)
128 */
129 magic = atomic_add_return(1, &bus_no_reg_magic);
130 dev_set_name(dev, "%s.%d", node->name, magic - 1);
131} 96}
132 97
133/** 98/**
@@ -149,9 +114,8 @@ struct platform_device *of_device_alloc(struct device_node *np,
149 return NULL; 114 return NULL;
150 115
151 /* count the io and irq resources */ 116 /* count the io and irq resources */
152 if (of_can_translate_address(np)) 117 while (of_address_to_resource(np, num_reg, &temp_res) == 0)
153 while (of_address_to_resource(np, num_reg, &temp_res) == 0) 118 num_reg++;
154 num_reg++;
155 num_irq = of_irq_count(np); 119 num_irq = of_irq_count(np);
156 120
157 /* Populate the resource table */ 121 /* Populate the resource table */
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index fe70b86bcffb..077314eebb95 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -31,6 +31,51 @@ static struct selftest_results {
31 } \ 31 } \
32} 32}
33 33
34static void __init of_selftest_find_node_by_name(void)
35{
36 struct device_node *np;
37
38 np = of_find_node_by_path("/testcase-data");
39 selftest(np && !strcmp("/testcase-data", np->full_name),
40 "find /testcase-data failed\n");
41 of_node_put(np);
42
43 /* Test if trailing '/' works */
44 np = of_find_node_by_path("/testcase-data/");
45 selftest(!np, "trailing '/' on /testcase-data/ should fail\n");
46
47 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
48 selftest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", np->full_name),
49 "find /testcase-data/phandle-tests/consumer-a failed\n");
50 of_node_put(np);
51
52 np = of_find_node_by_path("testcase-alias");
53 selftest(np && !strcmp("/testcase-data", np->full_name),
54 "find testcase-alias failed\n");
55 of_node_put(np);
56
57 /* Test if trailing '/' works on aliases */
58 np = of_find_node_by_path("testcase-alias/");
59 selftest(!np, "trailing '/' on testcase-alias/ should fail\n");
60
61 np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a");
62 selftest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", np->full_name),
63 "find testcase-alias/phandle-tests/consumer-a failed\n");
64 of_node_put(np);
65
66 np = of_find_node_by_path("/testcase-data/missing-path");
67 selftest(!np, "non-existent path returned node %s\n", np->full_name);
68 of_node_put(np);
69
70 np = of_find_node_by_path("missing-alias");
71 selftest(!np, "non-existent alias returned node %s\n", np->full_name);
72 of_node_put(np);
73
74 np = of_find_node_by_path("testcase-alias/missing-path");
75 selftest(!np, "non-existent alias with relative path returned node %s\n", np->full_name);
76 of_node_put(np);
77}
78
34static void __init of_selftest_dynamic(void) 79static void __init of_selftest_dynamic(void)
35{ 80{
36 struct device_node *np; 81 struct device_node *np;
@@ -431,8 +476,12 @@ static void __init of_selftest_match_node(void)
431static void __init of_selftest_platform_populate(void) 476static void __init of_selftest_platform_populate(void)
432{ 477{
433 int irq; 478 int irq;
434 struct device_node *np; 479 struct device_node *np, *child;
435 struct platform_device *pdev; 480 struct platform_device *pdev;
481 struct of_device_id match[] = {
482 { .compatible = "test-device", },
483 {}
484 };
436 485
437 np = of_find_node_by_path("/testcase-data"); 486 np = of_find_node_by_path("/testcase-data");
438 of_platform_populate(np, of_default_bus_match_table, NULL, NULL); 487 of_platform_populate(np, of_default_bus_match_table, NULL, NULL);
@@ -440,22 +489,32 @@ static void __init of_selftest_platform_populate(void)
440 /* Test that a missing irq domain returns -EPROBE_DEFER */ 489 /* Test that a missing irq domain returns -EPROBE_DEFER */
441 np = of_find_node_by_path("/testcase-data/testcase-device1"); 490 np = of_find_node_by_path("/testcase-data/testcase-device1");
442 pdev = of_find_device_by_node(np); 491 pdev = of_find_device_by_node(np);
443 if (!pdev) 492 selftest(pdev, "device 1 creation failed\n");
444 selftest(0, "device 1 creation failed\n"); 493
445 irq = platform_get_irq(pdev, 0); 494 irq = platform_get_irq(pdev, 0);
446 if (irq != -EPROBE_DEFER) 495 selftest(irq == -EPROBE_DEFER, "device deferred probe failed - %d\n", irq);
447 selftest(0, "device deferred probe failed - %d\n", irq);
448 496
449 /* Test that a parsing failure does not return -EPROBE_DEFER */ 497 /* Test that a parsing failure does not return -EPROBE_DEFER */
450 np = of_find_node_by_path("/testcase-data/testcase-device2"); 498 np = of_find_node_by_path("/testcase-data/testcase-device2");
451 pdev = of_find_device_by_node(np); 499 pdev = of_find_device_by_node(np);
452 if (!pdev) 500 selftest(pdev, "device 2 creation failed\n");
453 selftest(0, "device 2 creation failed\n");
454 irq = platform_get_irq(pdev, 0); 501 irq = platform_get_irq(pdev, 0);
455 if (irq >= 0 || irq == -EPROBE_DEFER) 502 selftest(irq < 0 && irq != -EPROBE_DEFER, "device parsing error failed - %d\n", irq);
456 selftest(0, "device parsing error failed - %d\n", irq);
457 503
458 selftest(1, "passed"); 504 np = of_find_node_by_path("/testcase-data/platform-tests");
505 if (!np) {
506 pr_err("No testcase data in device tree\n");
507 return;
508 }
509
510 for_each_child_of_node(np, child) {
511 struct device_node *grandchild;
512 of_platform_populate(child, match, NULL, NULL);
513 for_each_child_of_node(child, grandchild)
514 selftest(of_find_device_by_node(grandchild),
515 "Could not create device for node '%s'\n",
516 grandchild->name);
517 }
459} 518}
460 519
461static int __init of_selftest(void) 520static int __init of_selftest(void)
@@ -470,6 +529,7 @@ static int __init of_selftest(void)
470 of_node_put(np); 529 of_node_put(np);
471 530
472 pr_info("start of selftest - you will see error messages\n"); 531 pr_info("start of selftest - you will see error messages\n");
532 of_selftest_find_node_by_name();
473 of_selftest_dynamic(); 533 of_selftest_dynamic();
474 of_selftest_parse_phandle_with_args(); 534 of_selftest_parse_phandle_with_args();
475 of_selftest_property_match_string(); 535 of_selftest_property_match_string();
diff --git a/drivers/of/testcase-data/testcases.dtsi b/drivers/of/testcase-data/testcases.dtsi
index 3a5b75a8e4d7..6d8d980ac858 100644
--- a/drivers/of/testcase-data/testcases.dtsi
+++ b/drivers/of/testcase-data/testcases.dtsi
@@ -1,3 +1,4 @@
1#include "tests-phandle.dtsi" 1#include "tests-phandle.dtsi"
2#include "tests-interrupts.dtsi" 2#include "tests-interrupts.dtsi"
3#include "tests-match.dtsi" 3#include "tests-match.dtsi"
4#include "tests-platform.dtsi"
diff --git a/drivers/of/testcase-data/tests-phandle.dtsi b/drivers/of/testcase-data/tests-phandle.dtsi
index 788a4c24b8f5..ce0fe083d406 100644
--- a/drivers/of/testcase-data/tests-phandle.dtsi
+++ b/drivers/of/testcase-data/tests-phandle.dtsi
@@ -1,6 +1,10 @@
1 1
2/ { 2/ {
3 testcase-data { 3 aliases {
4 testcase-alias = &testcase;
5 };
6
7 testcase: testcase-data {
4 security-password = "password"; 8 security-password = "password";
5 duplicate-name = "duplicate"; 9 duplicate-name = "duplicate";
6 duplicate-name { }; 10 duplicate-name { };
diff --git a/drivers/of/testcase-data/tests-platform.dtsi b/drivers/of/testcase-data/tests-platform.dtsi
new file mode 100644
index 000000000000..eb20eeb2b062
--- /dev/null
+++ b/drivers/of/testcase-data/tests-platform.dtsi
@@ -0,0 +1,35 @@
1
2/ {
3 testcase-data {
4 platform-tests {
5 #address-cells = <1>;
6 #size-cells = <0>;
7
8 test-device@0 {
9 compatible = "test-device";
10 reg = <0x0>;
11
12 #address-cells = <1>;
13 #size-cells = <0>;
14
15 dev@100 {
16 compatible = "test-sub-device";
17 reg = <0x100>;
18 };
19 };
20
21 test-device@1 {
22 compatible = "test-device";
23 reg = <0x1>;
24
25 #address-cells = <1>;
26 #size-cells = <0>;
27
28 dev@100 {
29 compatible = "test-sub-device";
30 reg = <0x100>;
31 };
32 };
33 };
34 };
35};