diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 13:02:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 13:02:38 -0400 |
commit | d27050641e9bc056446deb0814e7ba1aa7911f5a (patch) | |
tree | 160f46d9a6df3d7234c71a9fbaa31ebcf89c04d0 | |
parent | b77279bc2e81545b20824da701b349272a78e4e7 (diff) | |
parent | 43cb43678705e39b175b325f17938295996aefc7 (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
...
76 files changed, 1008 insertions, 838 deletions
diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index b8b6871f116f..467ddd15d40c 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt | |||
@@ -13,7 +13,7 @@ Refer to clk/clock-bindings.txt for generic clock consumer properties | |||
13 | 13 | ||
14 | Optional properties: | 14 | Optional properties: |
15 | - phys: phy provider specifier | 15 | - phys: phy provider specifier |
16 | - phy-names: shall be "device" | 16 | - phy-names: shall be "usb2-phy" |
17 | Refer to phy/phy-bindings.txt for generic phy consumer properties | 17 | Refer to phy/phy-bindings.txt for generic phy consumer properties |
18 | 18 | ||
19 | Example: | 19 | Example: |
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 941980474e14..5261271046ce 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -77,6 +77,7 @@ lsi LSI Corp. (LSI Logic) | |||
77 | lltc Linear Technology Corporation | 77 | lltc Linear Technology Corporation |
78 | marvell Marvell Technology Group Ltd. | 78 | marvell Marvell Technology Group Ltd. |
79 | maxim Maxim Integrated Products | 79 | maxim Maxim Integrated Products |
80 | micrel Micrel Inc. | ||
80 | microchip Microchip Technology Inc. | 81 | microchip Microchip Technology Inc. |
81 | mosaixtech Mosaix Technologies, Inc. | 82 | mosaixtech Mosaix Technologies, Inc. |
82 | moxa Moxa | 83 | moxa Moxa |
diff --git a/arch/arc/include/asm/sections.h b/arch/arc/include/asm/sections.h index 764f1e3ba752..09db952e14bd 100644 --- a/arch/arc/include/asm/sections.h +++ b/arch/arc/include/asm/sections.h | |||
@@ -12,6 +12,5 @@ | |||
12 | #include <asm-generic/sections.h> | 12 | #include <asm-generic/sections.h> |
13 | 13 | ||
14 | extern char __arc_dccm_base[]; | 14 | extern char __arc_dccm_base[]; |
15 | extern char __dtb_start[]; | ||
16 | 15 | ||
17 | #endif | 16 | #endif |
diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index b6dc4e21fd32..0b3ef4025d89 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c | |||
@@ -42,7 +42,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt) | |||
42 | const struct machine_desc *mdesc; | 42 | const struct machine_desc *mdesc; |
43 | unsigned long dt_root; | 43 | unsigned long dt_root; |
44 | void *clk; | 44 | void *clk; |
45 | unsigned long len; | 45 | int len; |
46 | 46 | ||
47 | if (!early_init_dt_scan(dt)) | 47 | if (!early_init_dt_scan(dt)) |
48 | return NULL; | 48 | return NULL; |
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index b681575ad3de..cd94ef2ef283 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h | |||
@@ -14,7 +14,6 @@ | |||
14 | #ifdef CONFIG_OF | 14 | #ifdef CONFIG_OF |
15 | 15 | ||
16 | extern const struct machine_desc *setup_machine_fdt(unsigned int dt_phys); | 16 | extern const struct machine_desc *setup_machine_fdt(unsigned int dt_phys); |
17 | extern void arm_dt_memblock_reserve(void); | ||
18 | extern void __init arm_dt_init_cpu_maps(void); | 17 | extern void __init arm_dt_init_cpu_maps(void); |
19 | 18 | ||
20 | #else /* CONFIG_OF */ | 19 | #else /* CONFIG_OF */ |
@@ -24,7 +23,6 @@ static inline const struct machine_desc *setup_machine_fdt(unsigned int dt_phys) | |||
24 | return NULL; | 23 | return NULL; |
25 | } | 24 | } |
26 | 25 | ||
27 | static inline void arm_dt_memblock_reserve(void) { } | ||
28 | static inline void arm_dt_init_cpu_maps(void) { } | 26 | static inline void arm_dt_init_cpu_maps(void) { } |
29 | 27 | ||
30 | #endif /* CONFIG_OF */ | 28 | #endif /* CONFIG_OF */ |
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index c7419a585ddc..ea9ce92a4b52 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c | |||
@@ -32,51 +32,22 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) | |||
32 | arm_add_memory(base, size); | 32 | arm_add_memory(base, size); |
33 | } | 33 | } |
34 | 34 | ||
35 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | 35 | #ifdef CONFIG_SMP |
36 | { | 36 | extern struct of_cpu_method __cpu_method_of_table[]; |
37 | return memblock_virt_alloc(size, align); | ||
38 | } | ||
39 | |||
40 | void __init arm_dt_memblock_reserve(void) | ||
41 | { | ||
42 | u64 *reserve_map, base, size; | ||
43 | |||
44 | if (!initial_boot_params) | ||
45 | return; | ||
46 | |||
47 | /* Reserve the dtb region */ | ||
48 | memblock_reserve(virt_to_phys(initial_boot_params), | ||
49 | be32_to_cpu(initial_boot_params->totalsize)); | ||
50 | 37 | ||
51 | /* | 38 | static const struct of_cpu_method __cpu_method_of_table_sentinel |
52 | * Process the reserve map. This will probably overlap the initrd | 39 | __used __section(__cpu_method_of_table_end); |
53 | * and dtb locations which are already reserved, but overlaping | ||
54 | * doesn't hurt anything | ||
55 | */ | ||
56 | reserve_map = ((void*)initial_boot_params) + | ||
57 | be32_to_cpu(initial_boot_params->off_mem_rsvmap); | ||
58 | while (1) { | ||
59 | base = be64_to_cpup(reserve_map++); | ||
60 | size = be64_to_cpup(reserve_map++); | ||
61 | if (!size) | ||
62 | break; | ||
63 | memblock_reserve(base, size); | ||
64 | } | ||
65 | } | ||
66 | 40 | ||
67 | #ifdef CONFIG_SMP | ||
68 | extern struct of_cpu_method __cpu_method_of_table_begin[]; | ||
69 | extern struct of_cpu_method __cpu_method_of_table_end[]; | ||
70 | 41 | ||
71 | static int __init set_smp_ops_by_method(struct device_node *node) | 42 | static int __init set_smp_ops_by_method(struct device_node *node) |
72 | { | 43 | { |
73 | const char *method; | 44 | const char *method; |
74 | struct of_cpu_method *m = __cpu_method_of_table_begin; | 45 | struct of_cpu_method *m = __cpu_method_of_table; |
75 | 46 | ||
76 | if (of_property_read_string(node, "enable-method", &method)) | 47 | if (of_property_read_string(node, "enable-method", &method)) |
77 | return 0; | 48 | return 0; |
78 | 49 | ||
79 | for (; m < __cpu_method_of_table_end; m++) | 50 | for (; m->method; m++) |
80 | if (!strcmp(m->method, method)) { | 51 | if (!strcmp(m->method, method)) { |
81 | smp_set_ops(m->ops); | 52 | smp_set_ops(m->ops); |
82 | return 1; | 53 | return 1; |
@@ -252,7 +223,7 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) | |||
252 | 223 | ||
253 | if (!mdesc) { | 224 | if (!mdesc) { |
254 | const char *prop; | 225 | const char *prop; |
255 | long size; | 226 | int size; |
256 | unsigned long dt_root; | 227 | unsigned long dt_root; |
257 | 228 | ||
258 | early_print("\nError: unrecognized/unsupported " | 229 | early_print("\nError: unrecognized/unsupported " |
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index bc43e22693b7..a56ce45a3f90 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c | |||
@@ -202,7 +202,7 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname, | |||
202 | { | 202 | { |
203 | struct map_desc iodesc; | 203 | struct map_desc iodesc; |
204 | __be32 *reg; | 204 | __be32 *reg; |
205 | unsigned long len; | 205 | int len; |
206 | 206 | ||
207 | if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") && | 207 | if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") && |
208 | !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock")) | 208 | !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock")) |
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index a4d5e425cd82..71c86a2f856d 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c | |||
@@ -289,14 +289,12 @@ int __init mx35_clocks_init(void) | |||
289 | return 0; | 289 | return 0; |
290 | } | 290 | } |
291 | 291 | ||
292 | static int __init mx35_clocks_init_dt(struct device_node *ccm_node) | 292 | static void __init mx35_clocks_init_dt(struct device_node *ccm_node) |
293 | { | 293 | { |
294 | clk_data.clks = clk; | 294 | clk_data.clks = clk; |
295 | clk_data.clk_num = ARRAY_SIZE(clk); | 295 | clk_data.clk_num = ARRAY_SIZE(clk); |
296 | of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); | 296 | of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); |
297 | 297 | ||
298 | mx35_clocks_init(); | 298 | mx35_clocks_init(); |
299 | |||
300 | return 0; | ||
301 | } | 299 | } |
302 | CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt); | 300 | CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt); |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 2a77ba8796ae..928d596d9ab4 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -317,7 +317,6 @@ void __init arm_memblock_init(struct meminfo *mi, | |||
317 | #endif | 317 | #endif |
318 | 318 | ||
319 | arm_mm_memblock_reserve(); | 319 | arm_mm_memblock_reserve(); |
320 | arm_dt_memblock_reserve(); | ||
321 | 320 | ||
322 | /* reserve any platform specific memblock areas */ | 321 | /* reserve any platform specific memblock areas */ |
323 | if (mdesc->reserve) | 322 | if (mdesc->reserve) |
diff --git a/arch/arm/plat-samsung/s5p-dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c index 98087b655df0..469b86260fe3 100644 --- a/arch/arm/plat-samsung/s5p-dev-mfc.c +++ b/arch/arm/plat-samsung/s5p-dev-mfc.c | |||
@@ -125,8 +125,8 @@ device_initcall(s5p_mfc_memory_init); | |||
125 | int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname, | 125 | int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname, |
126 | int depth, void *data) | 126 | int depth, void *data) |
127 | { | 127 | { |
128 | __be32 *prop; | 128 | const __be32 *prop; |
129 | unsigned long len; | 129 | int len; |
130 | struct s5p_mfc_dt_meminfo mfc_mem; | 130 | struct s5p_mfc_dt_meminfo mfc_mem; |
131 | 131 | ||
132 | if (!data) | 132 | if (!data) |
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 51d5352e6ad5..091d428d64ac 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
@@ -126,8 +126,6 @@ static void arm64_memory_present(void) | |||
126 | 126 | ||
127 | void __init arm64_memblock_init(void) | 127 | void __init arm64_memblock_init(void) |
128 | { | 128 | { |
129 | u64 *reserve_map, base, size; | ||
130 | |||
131 | /* Register the kernel text, kernel data and initrd with memblock */ | 129 | /* Register the kernel text, kernel data and initrd with memblock */ |
132 | memblock_reserve(__pa(_text), _end - _text); | 130 | memblock_reserve(__pa(_text), _end - _text); |
133 | #ifdef CONFIG_BLK_DEV_INITRD | 131 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -142,25 +140,6 @@ void __init arm64_memblock_init(void) | |||
142 | memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE); | 140 | memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE); |
143 | memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE); | 141 | memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE); |
144 | 142 | ||
145 | /* Reserve the dtb region */ | ||
146 | memblock_reserve(virt_to_phys(initial_boot_params), | ||
147 | be32_to_cpu(initial_boot_params->totalsize)); | ||
148 | |||
149 | /* | ||
150 | * Process the reserve map. This will probably overlap the initrd | ||
151 | * and dtb locations which are already reserved, but overlapping | ||
152 | * doesn't hurt anything | ||
153 | */ | ||
154 | reserve_map = ((void*)initial_boot_params) + | ||
155 | be32_to_cpu(initial_boot_params->off_mem_rsvmap); | ||
156 | while (1) { | ||
157 | base = be64_to_cpup(reserve_map++); | ||
158 | size = be64_to_cpup(reserve_map++); | ||
159 | if (!size) | ||
160 | break; | ||
161 | memblock_reserve(base, size); | ||
162 | } | ||
163 | |||
164 | early_init_fdt_scan_reserved_mem(); | 143 | early_init_fdt_scan_reserved_mem(); |
165 | dma_contiguous_reserve(0); | 144 | dma_contiguous_reserve(0); |
166 | 145 | ||
diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c index 731db4b9014d..757128868d43 100644 --- a/arch/c6x/kernel/setup.c +++ b/arch/c6x/kernel/setup.c | |||
@@ -265,8 +265,8 @@ int __init c6x_add_memory(phys_addr_t start, unsigned long size) | |||
265 | */ | 265 | */ |
266 | notrace void __init machine_init(unsigned long dt_ptr) | 266 | notrace void __init machine_init(unsigned long dt_ptr) |
267 | { | 267 | { |
268 | struct boot_param_header *dtb = __va(dt_ptr); | 268 | const void *dtb = __va(dt_ptr); |
269 | struct boot_param_header *fdt = (struct boot_param_header *)_fdt_start; | 269 | const void *fdt = _fdt_start; |
270 | 270 | ||
271 | /* interrupts must be masked */ | 271 | /* interrupts must be masked */ |
272 | set_creg(IER, 2); | 272 | set_creg(IER, 2); |
diff --git a/arch/metag/kernel/setup.c b/arch/metag/kernel/setup.c index 129c7cdda1ce..31cf53d0eba2 100644 --- a/arch/metag/kernel/setup.c +++ b/arch/metag/kernel/setup.c | |||
@@ -105,10 +105,6 @@ | |||
105 | 105 | ||
106 | extern char _heap_start[]; | 106 | extern char _heap_start[]; |
107 | 107 | ||
108 | #ifdef CONFIG_METAG_BUILTIN_DTB | ||
109 | extern u32 __dtb_start[]; | ||
110 | #endif | ||
111 | |||
112 | #ifdef CONFIG_DA_CONSOLE | 108 | #ifdef CONFIG_DA_CONSOLE |
113 | /* Our early channel based console driver */ | 109 | /* Our early channel based console driver */ |
114 | extern struct console dash_console; | 110 | extern struct console dash_console; |
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index abdfb10e7eca..68f099960ebc 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c | |||
@@ -43,13 +43,13 @@ | |||
43 | #include <asm/pci-bridge.h> | 43 | #include <asm/pci-bridge.h> |
44 | 44 | ||
45 | #ifdef CONFIG_EARLY_PRINTK | 45 | #ifdef CONFIG_EARLY_PRINTK |
46 | static char *stdout; | 46 | static const char *stdout; |
47 | 47 | ||
48 | static int __init early_init_dt_scan_chosen_serial(unsigned long node, | 48 | static int __init early_init_dt_scan_chosen_serial(unsigned long node, |
49 | const char *uname, int depth, void *data) | 49 | const char *uname, int depth, void *data) |
50 | { | 50 | { |
51 | unsigned long l; | 51 | int l; |
52 | char *p; | 52 | const char *p; |
53 | 53 | ||
54 | pr_debug("%s: depth: %d, uname: %s\n", __func__, depth, uname); | 54 | pr_debug("%s: depth: %d, uname: %s\n", __func__, depth, uname); |
55 | 55 | ||
@@ -80,7 +80,7 @@ static int __init early_init_dt_scan_chosen_serial(unsigned long node, | |||
80 | (strncmp(p, "xlnx,opb-uartlite", 17) == 0) || | 80 | (strncmp(p, "xlnx,opb-uartlite", 17) == 0) || |
81 | (strncmp(p, "xlnx,axi-uartlite", 17) == 0) || | 81 | (strncmp(p, "xlnx,axi-uartlite", 17) == 0) || |
82 | (strncmp(p, "xlnx,mdm", 8) == 0)) { | 82 | (strncmp(p, "xlnx,mdm", 8) == 0)) { |
83 | unsigned int *addrp; | 83 | const unsigned int *addrp; |
84 | 84 | ||
85 | *(u32 *)data = UARTLITE; | 85 | *(u32 *)data = UARTLITE; |
86 | 86 | ||
@@ -114,34 +114,3 @@ void __init early_init_devtree(void *params) | |||
114 | 114 | ||
115 | pr_debug(" <- early_init_devtree()\n"); | 115 | pr_debug(" <- early_init_devtree()\n"); |
116 | } | 116 | } |
117 | |||
118 | /******* | ||
119 | * | ||
120 | * New implementation of the OF "find" APIs, return a refcounted | ||
121 | * object, call of_node_put() when done. The device tree and list | ||
122 | * are protected by a rw_lock. | ||
123 | * | ||
124 | * Note that property management will need some locking as well, | ||
125 | * this isn't dealt with yet. | ||
126 | * | ||
127 | *******/ | ||
128 | |||
129 | #if defined(CONFIG_DEBUG_FS) && defined(DEBUG) | ||
130 | static struct debugfs_blob_wrapper flat_dt_blob; | ||
131 | |||
132 | static int __init export_flat_device_tree(void) | ||
133 | { | ||
134 | struct dentry *d; | ||
135 | |||
136 | flat_dt_blob.data = initial_boot_params; | ||
137 | flat_dt_blob.size = initial_boot_params->totalsize; | ||
138 | |||
139 | d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, | ||
140 | of_debugfs_root, &flat_dt_blob); | ||
141 | if (!d) | ||
142 | return 1; | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | device_initcall(export_flat_device_tree); | ||
147 | #endif | ||
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 331b837cec57..f1bec00d5a85 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c | |||
@@ -1053,36 +1053,26 @@ void prom_free_prom_memory(void) | |||
1053 | int octeon_prune_device_tree(void); | 1053 | int octeon_prune_device_tree(void); |
1054 | 1054 | ||
1055 | extern const char __dtb_octeon_3xxx_begin; | 1055 | extern const char __dtb_octeon_3xxx_begin; |
1056 | extern const char __dtb_octeon_3xxx_end; | ||
1057 | extern const char __dtb_octeon_68xx_begin; | 1056 | extern const char __dtb_octeon_68xx_begin; |
1058 | extern const char __dtb_octeon_68xx_end; | ||
1059 | void __init device_tree_init(void) | 1057 | void __init device_tree_init(void) |
1060 | { | 1058 | { |
1061 | int dt_size; | 1059 | const void *fdt; |
1062 | struct boot_param_header *fdt; | ||
1063 | bool do_prune; | 1060 | bool do_prune; |
1064 | 1061 | ||
1065 | if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) { | 1062 | if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) { |
1066 | fdt = phys_to_virt(octeon_bootinfo->fdt_addr); | 1063 | fdt = phys_to_virt(octeon_bootinfo->fdt_addr); |
1067 | if (fdt_check_header(fdt)) | 1064 | if (fdt_check_header(fdt)) |
1068 | panic("Corrupt Device Tree passed to kernel."); | 1065 | panic("Corrupt Device Tree passed to kernel."); |
1069 | dt_size = be32_to_cpu(fdt->totalsize); | ||
1070 | do_prune = false; | 1066 | do_prune = false; |
1071 | } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { | 1067 | } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { |
1072 | fdt = (struct boot_param_header *)&__dtb_octeon_68xx_begin; | 1068 | fdt = &__dtb_octeon_68xx_begin; |
1073 | dt_size = &__dtb_octeon_68xx_end - &__dtb_octeon_68xx_begin; | ||
1074 | do_prune = true; | 1069 | do_prune = true; |
1075 | } else { | 1070 | } else { |
1076 | fdt = (struct boot_param_header *)&__dtb_octeon_3xxx_begin; | 1071 | fdt = &__dtb_octeon_3xxx_begin; |
1077 | dt_size = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin; | ||
1078 | do_prune = true; | 1072 | do_prune = true; |
1079 | } | 1073 | } |
1080 | 1074 | ||
1081 | /* Copy the default tree from init memory. */ | 1075 | initial_boot_params = (void *)fdt; |
1082 | initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8); | ||
1083 | if (initial_boot_params == NULL) | ||
1084 | panic("Could not allocate initial_boot_params"); | ||
1085 | memcpy(initial_boot_params, fdt, dt_size); | ||
1086 | 1076 | ||
1087 | if (do_prune) { | 1077 | if (do_prune) { |
1088 | octeon_prune_device_tree(); | 1078 | octeon_prune_device_tree(); |
@@ -1090,7 +1080,7 @@ void __init device_tree_init(void) | |||
1090 | } else { | 1080 | } else { |
1091 | pr_info("Using passed Device Tree.\n"); | 1081 | pr_info("Using passed Device Tree.\n"); |
1092 | } | 1082 | } |
1093 | unflatten_device_tree(); | 1083 | unflatten_and_copy_device_tree(); |
1094 | } | 1084 | } |
1095 | 1085 | ||
1096 | static int __initdata disable_octeon_edac_p; | 1086 | static int __initdata disable_octeon_edac_p; |
diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h index 48616816bcbc..c904c24550f6 100644 --- a/arch/mips/include/asm/mips-boards/generic.h +++ b/arch/mips/include/asm/mips-boards/generic.h | |||
@@ -67,10 +67,6 @@ | |||
67 | 67 | ||
68 | extern int mips_revision_sconid; | 68 | extern int mips_revision_sconid; |
69 | 69 | ||
70 | #ifdef CONFIG_OF | ||
71 | extern struct boot_param_header __dtb_start; | ||
72 | #endif | ||
73 | |||
74 | #ifdef CONFIG_PCI | 70 | #ifdef CONFIG_PCI |
75 | extern void mips_pcibios_init(void); | 71 | extern void mips_pcibios_init(void); |
76 | #else | 72 | #else |
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index ccd2b75f152c..a9494c0141fb 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h | |||
@@ -21,13 +21,13 @@ extern void device_tree_init(void); | |||
21 | 21 | ||
22 | struct boot_param_header; | 22 | struct boot_param_header; |
23 | 23 | ||
24 | extern void __dt_setup_arch(struct boot_param_header *bph); | 24 | extern void __dt_setup_arch(void *bph); |
25 | 25 | ||
26 | #define dt_setup_arch(sym) \ | 26 | #define dt_setup_arch(sym) \ |
27 | ({ \ | 27 | ({ \ |
28 | extern struct boot_param_header __dtb_##sym##_begin; \ | 28 | extern char __dtb_##sym##_begin[]; \ |
29 | \ | 29 | \ |
30 | __dt_setup_arch(&__dtb_##sym##_begin); \ | 30 | __dt_setup_arch(__dtb_##sym##_begin); \ |
31 | }) | 31 | }) |
32 | 32 | ||
33 | #else /* CONFIG_OF */ | 33 | #else /* CONFIG_OF */ |
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 3c3b0df8f48d..5d39bb85bf35 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
@@ -47,7 +47,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | |||
47 | return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); | 47 | return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); |
48 | } | 48 | } |
49 | 49 | ||
50 | void __init __dt_setup_arch(struct boot_param_header *bph) | 50 | void __init __dt_setup_arch(void *bph) |
51 | { | 51 | { |
52 | if (!early_init_dt_scan(bph)) | 52 | if (!early_init_dt_scan(bph)) |
53 | return; | 53 | return; |
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 19686c5bc5ed..7447d322d14e 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c | |||
@@ -71,23 +71,12 @@ void __init plat_mem_setup(void) | |||
71 | * Load the builtin devicetree. This causes the chosen node to be | 71 | * Load the builtin devicetree. This causes the chosen node to be |
72 | * parsed resulting in our memory appearing | 72 | * parsed resulting in our memory appearing |
73 | */ | 73 | */ |
74 | __dt_setup_arch(&__dtb_start); | 74 | __dt_setup_arch(__dtb_start); |
75 | } | 75 | } |
76 | 76 | ||
77 | void __init device_tree_init(void) | 77 | void __init device_tree_init(void) |
78 | { | 78 | { |
79 | unsigned long base, size; | 79 | unflatten_and_copy_device_tree(); |
80 | |||
81 | if (!initial_boot_params) | ||
82 | return; | ||
83 | |||
84 | base = virt_to_phys((void *)initial_boot_params); | ||
85 | size = be32_to_cpu(initial_boot_params->totalsize); | ||
86 | |||
87 | /* Before we do anything, lets reserve the dt blob */ | ||
88 | reserve_bootmem(base, size, BOOTMEM_DEFAULT); | ||
89 | |||
90 | unflatten_device_tree(); | ||
91 | } | 80 | } |
92 | 81 | ||
93 | void __init prom_init(void) | 82 | void __init prom_init(void) |
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h index 8e07b5f28ef1..bfd2d58c1d69 100644 --- a/arch/mips/lantiq/prom.h +++ b/arch/mips/lantiq/prom.h | |||
@@ -26,6 +26,4 @@ struct ltq_soc_info { | |||
26 | extern void ltq_soc_detect(struct ltq_soc_info *i); | 26 | extern void ltq_soc_detect(struct ltq_soc_info *i); |
27 | extern void ltq_soc_init(void); | 27 | extern void ltq_soc_init(void); |
28 | 28 | ||
29 | extern struct boot_param_header __dtb_start; | ||
30 | |||
31 | #endif | 29 | #endif |
diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c index bf7fe48bf2f9..e43f4801a245 100644 --- a/arch/mips/mti-sead3/sead3-setup.c +++ b/arch/mips/mti-sead3/sead3-setup.c | |||
@@ -69,17 +69,17 @@ static void __init parse_memsize_param(void) | |||
69 | if (!memsize) | 69 | if (!memsize) |
70 | return; | 70 | return; |
71 | 71 | ||
72 | offset = fdt_path_offset(&__dtb_start, "/memory"); | 72 | offset = fdt_path_offset(__dtb_start, "/memory"); |
73 | if (offset > 0) { | 73 | if (offset > 0) { |
74 | uint64_t new_value; | 74 | uint64_t new_value; |
75 | /* | 75 | /* |
76 | * reg contains 2 32-bits BE values, offset and size. We just | 76 | * reg contains 2 32-bits BE values, offset and size. We just |
77 | * want to replace the size value without affecting the offset | 77 | * want to replace the size value without affecting the offset |
78 | */ | 78 | */ |
79 | prop_value = fdt_getprop(&__dtb_start, offset, "reg", &prop_len); | 79 | prop_value = fdt_getprop(__dtb_start, offset, "reg", &prop_len); |
80 | new_value = be64_to_cpu(*prop_value); | 80 | new_value = be64_to_cpu(*prop_value); |
81 | new_value = (new_value & ~0xffffffffllu) | memsize; | 81 | new_value = (new_value & ~0xffffffffllu) | memsize; |
82 | fdt_setprop_inplace_u64(&__dtb_start, offset, "reg", new_value); | 82 | fdt_setprop_inplace_u64(__dtb_start, offset, "reg", new_value); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
@@ -92,7 +92,7 @@ void __init plat_mem_setup(void) | |||
92 | * Load the builtin devicetree. This causes the chosen node to be | 92 | * Load the builtin devicetree. This causes the chosen node to be |
93 | * parsed resulting in our memory appearing | 93 | * parsed resulting in our memory appearing |
94 | */ | 94 | */ |
95 | __dt_setup_arch(&__dtb_start); | 95 | __dt_setup_arch(__dtb_start); |
96 | } | 96 | } |
97 | 97 | ||
98 | void __init device_tree_init(void) | 98 | void __init device_tree_init(void) |
diff --git a/arch/mips/netlogic/xlp/dt.c b/arch/mips/netlogic/xlp/dt.c index 5754097b9cde..bdde33147bce 100644 --- a/arch/mips/netlogic/xlp/dt.c +++ b/arch/mips/netlogic/xlp/dt.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <asm/prom.h> | 42 | #include <asm/prom.h> |
43 | 43 | ||
44 | extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], | 44 | extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], |
45 | __dtb_xlp_fvp_begin[], __dtb_xlp_gvp_begin[], __dtb_start[]; | 45 | __dtb_xlp_fvp_begin[], __dtb_xlp_gvp_begin[]; |
46 | static void *xlp_fdt_blob; | 46 | static void *xlp_fdt_blob; |
47 | 47 | ||
48 | void __init *xlp_dt_init(void *fdtp) | 48 | void __init *xlp_dt_init(void *fdtp) |
@@ -87,22 +87,7 @@ void __init xlp_early_init_devtree(void) | |||
87 | 87 | ||
88 | void __init device_tree_init(void) | 88 | void __init device_tree_init(void) |
89 | { | 89 | { |
90 | unsigned long base, size; | 90 | unflatten_and_copy_device_tree(); |
91 | struct boot_param_header *fdtp = xlp_fdt_blob; | ||
92 | |||
93 | if (!fdtp) | ||
94 | return; | ||
95 | |||
96 | base = virt_to_phys(fdtp); | ||
97 | size = be32_to_cpu(fdtp->totalsize); | ||
98 | |||
99 | /* Before we do anything, lets reserve the dt blob */ | ||
100 | reserve_bootmem(base, size, BOOTMEM_DEFAULT); | ||
101 | |||
102 | unflatten_device_tree(); | ||
103 | |||
104 | /* free the space reserved for the dt blob */ | ||
105 | free_bootmem(base, size); | ||
106 | } | 91 | } |
107 | 92 | ||
108 | static struct of_device_id __initdata xlp_ids[] = { | 93 | static struct of_device_id __initdata xlp_ids[] = { |
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index eccc5526155e..251395210e23 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c | |||
@@ -28,8 +28,6 @@ | |||
28 | __iomem void *rt_sysc_membase; | 28 | __iomem void *rt_sysc_membase; |
29 | __iomem void *rt_memc_membase; | 29 | __iomem void *rt_memc_membase; |
30 | 30 | ||
31 | extern struct boot_param_header __dtb_start; | ||
32 | |||
33 | __iomem void *plat_of_remap_node(const char *node) | 31 | __iomem void *plat_of_remap_node(const char *node) |
34 | { | 32 | { |
35 | struct resource res; | 33 | struct resource res; |
@@ -52,30 +50,7 @@ __iomem void *plat_of_remap_node(const char *node) | |||
52 | 50 | ||
53 | void __init device_tree_init(void) | 51 | void __init device_tree_init(void) |
54 | { | 52 | { |
55 | unsigned long base, size; | 53 | unflatten_and_copy_device_tree(); |
56 | void *fdt_copy; | ||
57 | |||
58 | if (!initial_boot_params) | ||
59 | return; | ||
60 | |||
61 | base = virt_to_phys((void *)initial_boot_params); | ||
62 | size = be32_to_cpu(initial_boot_params->totalsize); | ||
63 | |||
64 | /* Before we do anything, lets reserve the dt blob */ | ||
65 | reserve_bootmem(base, size, BOOTMEM_DEFAULT); | ||
66 | |||
67 | /* The strings in the flattened tree are referenced directly by the | ||
68 | * device tree, so copy the flattened device tree from init memory | ||
69 | * to regular memory. | ||
70 | */ | ||
71 | fdt_copy = alloc_bootmem(size); | ||
72 | memcpy(fdt_copy, initial_boot_params, size); | ||
73 | initial_boot_params = fdt_copy; | ||
74 | |||
75 | unflatten_device_tree(); | ||
76 | |||
77 | /* free the space reserved for the dt blob */ | ||
78 | free_bootmem(base, size); | ||
79 | } | 54 | } |
80 | 55 | ||
81 | void __init plat_mem_setup(void) | 56 | void __init plat_mem_setup(void) |
@@ -86,7 +61,7 @@ void __init plat_mem_setup(void) | |||
86 | * Load the builtin devicetree. This causes the chosen node to be | 61 | * Load the builtin devicetree. This causes the chosen node to be |
87 | * parsed resulting in our memory appearing | 62 | * parsed resulting in our memory appearing |
88 | */ | 63 | */ |
89 | __dt_setup_arch(&__dtb_start); | 64 | __dt_setup_arch(__dtb_start); |
90 | 65 | ||
91 | if (soc_info.mem_size) | 66 | if (soc_info.mem_size) |
92 | add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, | 67 | add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, |
diff --git a/arch/openrisc/kernel/vmlinux.h b/arch/openrisc/kernel/vmlinux.h index 70b9ce41835c..bbcdf21b0b35 100644 --- a/arch/openrisc/kernel/vmlinux.h +++ b/arch/openrisc/kernel/vmlinux.h | |||
@@ -5,6 +5,4 @@ | |||
5 | extern char __initrd_start, __initrd_end; | 5 | extern char __initrd_start, __initrd_end; |
6 | #endif | 6 | #endif |
7 | 7 | ||
8 | extern u32 __dtb_start[]; | ||
9 | |||
10 | #endif | 8 | #endif |
diff --git a/arch/powerpc/include/asm/dcr-mmio.h b/arch/powerpc/include/asm/dcr-mmio.h index acd491dbd45a..93a68b28e695 100644 --- a/arch/powerpc/include/asm/dcr-mmio.h +++ b/arch/powerpc/include/asm/dcr-mmio.h | |||
@@ -51,10 +51,6 @@ static inline void dcr_write_mmio(dcr_host_mmio_t host, | |||
51 | out_be32(host.token + ((host.base + dcr_n) * host.stride), value); | 51 | out_be32(host.token + ((host.base + dcr_n) * host.stride), value); |
52 | } | 52 | } |
53 | 53 | ||
54 | extern u64 of_translate_dcr_address(struct device_node *dev, | ||
55 | unsigned int dcr_n, | ||
56 | unsigned int *stride); | ||
57 | |||
58 | #endif /* __KERNEL__ */ | 54 | #endif /* __KERNEL__ */ |
59 | #endif /* _ASM_POWERPC_DCR_MMIO_H */ | 55 | #endif /* _ASM_POWERPC_DCR_MMIO_H */ |
60 | 56 | ||
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index d977b9b78696..74b79f07f041 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h | |||
@@ -26,6 +26,45 @@ | |||
26 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | 28 | ||
29 | #define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ | ||
30 | #define OF_DT_END_NODE 0x2 /* End node */ | ||
31 | #define OF_DT_PROP 0x3 /* Property: name off, size, | ||
32 | * content */ | ||
33 | #define OF_DT_NOP 0x4 /* nop */ | ||
34 | #define OF_DT_END 0x9 | ||
35 | |||
36 | #define OF_DT_VERSION 0x10 | ||
37 | |||
38 | /* | ||
39 | * This is what gets passed to the kernel by prom_init or kexec | ||
40 | * | ||
41 | * The dt struct contains the device tree structure, full pathes and | ||
42 | * property contents. The dt strings contain a separate block with just | ||
43 | * the strings for the property names, and is fully page aligned and | ||
44 | * self contained in a page, so that it can be kept around by the kernel, | ||
45 | * each property name appears only once in this page (cheap compression) | ||
46 | * | ||
47 | * the mem_rsvmap contains a map of reserved ranges of physical memory, | ||
48 | * passing it here instead of in the device-tree itself greatly simplifies | ||
49 | * the job of everybody. It's just a list of u64 pairs (base/size) that | ||
50 | * ends when size is 0 | ||
51 | */ | ||
52 | struct boot_param_header { | ||
53 | __be32 magic; /* magic word OF_DT_HEADER */ | ||
54 | __be32 totalsize; /* total size of DT block */ | ||
55 | __be32 off_dt_struct; /* offset to structure */ | ||
56 | __be32 off_dt_strings; /* offset to strings */ | ||
57 | __be32 off_mem_rsvmap; /* offset to memory reserve map */ | ||
58 | __be32 version; /* format version */ | ||
59 | __be32 last_comp_version; /* last compatible version */ | ||
60 | /* version 2 fields below */ | ||
61 | __be32 boot_cpuid_phys; /* Physical CPU id we're booting on */ | ||
62 | /* version 3 fields below */ | ||
63 | __be32 dt_strings_size; /* size of the DT strings block */ | ||
64 | /* version 17 fields below */ | ||
65 | __be32 dt_struct_size; /* size of the DT structure block */ | ||
66 | }; | ||
67 | |||
29 | /* | 68 | /* |
30 | * OF address retreival & translation | 69 | * OF address retreival & translation |
31 | */ | 70 | */ |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index fcc9a89a4695..fab19ec25597 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -2,6 +2,7 @@ | |||
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | CFLAGS_prom.o = -I$(src)/../../../scripts/dtc/libfdt | ||
5 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | 6 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' |
6 | 7 | ||
7 | subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror | 8 | subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror |
diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c index d9b79358b833..60d1a2259dbe 100644 --- a/arch/powerpc/kernel/epapr_paravirt.c +++ b/arch/powerpc/kernel/epapr_paravirt.c | |||
@@ -36,7 +36,7 @@ static int __init early_init_dt_scan_epapr(unsigned long node, | |||
36 | int depth, void *data) | 36 | int depth, void *data) |
37 | { | 37 | { |
38 | const u32 *insts; | 38 | const u32 *insts; |
39 | unsigned long len; | 39 | int len; |
40 | int i; | 40 | int i; |
41 | 41 | ||
42 | insts = of_get_flat_dt_prop(node, "hcall-instructions", &len); | 42 | insts = of_get_flat_dt_prop(node, "hcall-instructions", &len); |
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 2230fd0ca3e4..7213d930918d 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c | |||
@@ -55,9 +55,9 @@ int crash_mem_ranges; | |||
55 | int __init early_init_dt_scan_fw_dump(unsigned long node, | 55 | int __init early_init_dt_scan_fw_dump(unsigned long node, |
56 | const char *uname, int depth, void *data) | 56 | const char *uname, int depth, void *data) |
57 | { | 57 | { |
58 | __be32 *sections; | 58 | const __be32 *sections; |
59 | int i, num_sections; | 59 | int i, num_sections; |
60 | unsigned long size; | 60 | int size; |
61 | const int *token; | 61 | const int *token; |
62 | 62 | ||
63 | if (depth != 1 || strcmp(uname, "rtas") != 0) | 63 | if (depth != 1 || strcmp(uname, "rtas") != 0) |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 668aa4791fd7..613a860a203c 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -29,11 +29,11 @@ | |||
29 | #include <linux/bitops.h> | 29 | #include <linux/bitops.h> |
30 | #include <linux/export.h> | 30 | #include <linux/export.h> |
31 | #include <linux/kexec.h> | 31 | #include <linux/kexec.h> |
32 | #include <linux/debugfs.h> | ||
33 | #include <linux/irq.h> | 32 | #include <linux/irq.h> |
34 | #include <linux/memblock.h> | 33 | #include <linux/memblock.h> |
35 | #include <linux/of.h> | 34 | #include <linux/of.h> |
36 | #include <linux/of_fdt.h> | 35 | #include <linux/of_fdt.h> |
36 | #include <linux/libfdt.h> | ||
37 | 37 | ||
38 | #include <asm/prom.h> | 38 | #include <asm/prom.h> |
39 | #include <asm/rtas.h> | 39 | #include <asm/rtas.h> |
@@ -118,14 +118,14 @@ static void __init move_device_tree(void) | |||
118 | DBG("-> move_device_tree\n"); | 118 | DBG("-> move_device_tree\n"); |
119 | 119 | ||
120 | start = __pa(initial_boot_params); | 120 | start = __pa(initial_boot_params); |
121 | size = be32_to_cpu(initial_boot_params->totalsize); | 121 | size = fdt_totalsize(initial_boot_params); |
122 | 122 | ||
123 | if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) || | 123 | if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) || |
124 | overlaps_crashkernel(start, size) || | 124 | overlaps_crashkernel(start, size) || |
125 | overlaps_initrd(start, size)) { | 125 | overlaps_initrd(start, size)) { |
126 | p = __va(memblock_alloc(size, PAGE_SIZE)); | 126 | p = __va(memblock_alloc(size, PAGE_SIZE)); |
127 | memcpy(p, initial_boot_params, size); | 127 | memcpy(p, initial_boot_params, size); |
128 | initial_boot_params = (struct boot_param_header *)p; | 128 | initial_boot_params = p; |
129 | DBG("Moved device tree to 0x%p\n", p); | 129 | DBG("Moved device tree to 0x%p\n", p); |
130 | } | 130 | } |
131 | 131 | ||
@@ -163,7 +163,7 @@ static struct ibm_pa_feature { | |||
163 | {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, | 163 | {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, |
164 | }; | 164 | }; |
165 | 165 | ||
166 | static void __init scan_features(unsigned long node, unsigned char *ftrs, | 166 | static void __init scan_features(unsigned long node, const unsigned char *ftrs, |
167 | unsigned long tablelen, | 167 | unsigned long tablelen, |
168 | struct ibm_pa_feature *fp, | 168 | struct ibm_pa_feature *fp, |
169 | unsigned long ft_size) | 169 | unsigned long ft_size) |
@@ -202,8 +202,8 @@ static void __init scan_features(unsigned long node, unsigned char *ftrs, | |||
202 | 202 | ||
203 | static void __init check_cpu_pa_features(unsigned long node) | 203 | static void __init check_cpu_pa_features(unsigned long node) |
204 | { | 204 | { |
205 | unsigned char *pa_ftrs; | 205 | const unsigned char *pa_ftrs; |
206 | unsigned long tablelen; | 206 | int tablelen; |
207 | 207 | ||
208 | pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen); | 208 | pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen); |
209 | if (pa_ftrs == NULL) | 209 | if (pa_ftrs == NULL) |
@@ -216,7 +216,7 @@ static void __init check_cpu_pa_features(unsigned long node) | |||
216 | #ifdef CONFIG_PPC_STD_MMU_64 | 216 | #ifdef CONFIG_PPC_STD_MMU_64 |
217 | static void __init check_cpu_slb_size(unsigned long node) | 217 | static void __init check_cpu_slb_size(unsigned long node) |
218 | { | 218 | { |
219 | __be32 *slb_size_ptr; | 219 | const __be32 *slb_size_ptr; |
220 | 220 | ||
221 | slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL); | 221 | slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL); |
222 | if (slb_size_ptr != NULL) { | 222 | if (slb_size_ptr != NULL) { |
@@ -257,7 +257,7 @@ static struct feature_property { | |||
257 | static inline void identical_pvr_fixup(unsigned long node) | 257 | static inline void identical_pvr_fixup(unsigned long node) |
258 | { | 258 | { |
259 | unsigned int pvr; | 259 | unsigned int pvr; |
260 | char *model = of_get_flat_dt_prop(node, "model", NULL); | 260 | const char *model = of_get_flat_dt_prop(node, "model", NULL); |
261 | 261 | ||
262 | /* | 262 | /* |
263 | * Since 440GR(x)/440EP(x) processors have the same pvr, | 263 | * Since 440GR(x)/440EP(x) processors have the same pvr, |
@@ -295,11 +295,11 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
295 | const char *uname, int depth, | 295 | const char *uname, int depth, |
296 | void *data) | 296 | void *data) |
297 | { | 297 | { |
298 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | 298 | const char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
299 | const __be32 *prop; | 299 | const __be32 *prop; |
300 | const __be32 *intserv; | 300 | const __be32 *intserv; |
301 | int i, nthreads; | 301 | int i, nthreads; |
302 | unsigned long len; | 302 | int len; |
303 | int found = -1; | 303 | int found = -1; |
304 | int found_thread = 0; | 304 | int found_thread = 0; |
305 | 305 | ||
@@ -325,9 +325,9 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
325 | * version 2 of the kexec param format adds the phys cpuid of | 325 | * version 2 of the kexec param format adds the phys cpuid of |
326 | * booted proc. | 326 | * booted proc. |
327 | */ | 327 | */ |
328 | if (be32_to_cpu(initial_boot_params->version) >= 2) { | 328 | if (fdt_version(initial_boot_params) >= 2) { |
329 | if (be32_to_cpu(intserv[i]) == | 329 | if (be32_to_cpu(intserv[i]) == |
330 | be32_to_cpu(initial_boot_params->boot_cpuid_phys)) { | 330 | fdt_boot_cpuid_phys(initial_boot_params)) { |
331 | found = boot_cpu_count; | 331 | found = boot_cpu_count; |
332 | found_thread = i; | 332 | found_thread = i; |
333 | } | 333 | } |
@@ -392,7 +392,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
392 | int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname, | 392 | int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname, |
393 | int depth, void *data) | 393 | int depth, void *data) |
394 | { | 394 | { |
395 | unsigned long *lprop; /* All these set by kernel, so no need to convert endian */ | 395 | const unsigned long *lprop; /* All these set by kernel, so no need to convert endian */ |
396 | 396 | ||
397 | /* Use common scan routine to determine if this is the chosen node */ | 397 | /* Use common scan routine to determine if this is the chosen node */ |
398 | if (early_init_dt_scan_chosen(node, uname, depth, data) == 0) | 398 | if (early_init_dt_scan_chosen(node, uname, depth, data) == 0) |
@@ -443,8 +443,9 @@ int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname, | |||
443 | */ | 443 | */ |
444 | static int __init early_init_dt_scan_drconf_memory(unsigned long node) | 444 | static int __init early_init_dt_scan_drconf_memory(unsigned long node) |
445 | { | 445 | { |
446 | __be32 *dm, *ls, *usm; | 446 | const __be32 *dm, *ls, *usm; |
447 | unsigned long l, n, flags; | 447 | int l; |
448 | unsigned long n, flags; | ||
448 | u64 base, size, memblock_size; | 449 | u64 base, size, memblock_size; |
449 | unsigned int is_kexec_kdump = 0, rngs; | 450 | unsigned int is_kexec_kdump = 0, rngs; |
450 | 451 | ||
@@ -564,9 +565,12 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) | |||
564 | 565 | ||
565 | static void __init early_reserve_mem_dt(void) | 566 | static void __init early_reserve_mem_dt(void) |
566 | { | 567 | { |
567 | unsigned long i, len, dt_root; | 568 | unsigned long i, dt_root; |
569 | int len; | ||
568 | const __be32 *prop; | 570 | const __be32 *prop; |
569 | 571 | ||
572 | early_init_fdt_scan_reserved_mem(); | ||
573 | |||
570 | dt_root = of_get_flat_dt_root(); | 574 | dt_root = of_get_flat_dt_root(); |
571 | 575 | ||
572 | prop = of_get_flat_dt_prop(dt_root, "reserved-ranges", &len); | 576 | prop = of_get_flat_dt_prop(dt_root, "reserved-ranges", &len); |
@@ -589,24 +593,14 @@ static void __init early_reserve_mem_dt(void) | |||
589 | memblock_reserve(base, size); | 593 | memblock_reserve(base, size); |
590 | } | 594 | } |
591 | } | 595 | } |
592 | |||
593 | early_init_fdt_scan_reserved_mem(); | ||
594 | } | 596 | } |
595 | 597 | ||
596 | static void __init early_reserve_mem(void) | 598 | static void __init early_reserve_mem(void) |
597 | { | 599 | { |
598 | u64 base, size; | ||
599 | __be64 *reserve_map; | 600 | __be64 *reserve_map; |
600 | unsigned long self_base; | ||
601 | unsigned long self_size; | ||
602 | 601 | ||
603 | reserve_map = (__be64 *)(((unsigned long)initial_boot_params) + | 602 | reserve_map = (__be64 *)(((unsigned long)initial_boot_params) + |
604 | be32_to_cpu(initial_boot_params->off_mem_rsvmap)); | 603 | fdt_off_mem_rsvmap(initial_boot_params)); |
605 | |||
606 | /* before we do anything, lets reserve the dt blob */ | ||
607 | self_base = __pa((unsigned long)initial_boot_params); | ||
608 | self_size = be32_to_cpu(initial_boot_params->totalsize); | ||
609 | memblock_reserve(self_base, self_size); | ||
610 | 604 | ||
611 | /* Look for the new "reserved-regions" property in the DT */ | 605 | /* Look for the new "reserved-regions" property in the DT */ |
612 | early_reserve_mem_dt(); | 606 | early_reserve_mem_dt(); |
@@ -636,26 +630,12 @@ static void __init early_reserve_mem(void) | |||
636 | size_32 = be32_to_cpup(reserve_map_32++); | 630 | size_32 = be32_to_cpup(reserve_map_32++); |
637 | if (size_32 == 0) | 631 | if (size_32 == 0) |
638 | break; | 632 | break; |
639 | /* skip if the reservation is for the blob */ | ||
640 | if (base_32 == self_base && size_32 == self_size) | ||
641 | continue; | ||
642 | DBG("reserving: %x -> %x\n", base_32, size_32); | 633 | DBG("reserving: %x -> %x\n", base_32, size_32); |
643 | memblock_reserve(base_32, size_32); | 634 | memblock_reserve(base_32, size_32); |
644 | } | 635 | } |
645 | return; | 636 | return; |
646 | } | 637 | } |
647 | #endif | 638 | #endif |
648 | DBG("Processing reserve map\n"); | ||
649 | |||
650 | /* Handle the reserve map in the fdt blob if it exists */ | ||
651 | while (1) { | ||
652 | base = be64_to_cpup(reserve_map++); | ||
653 | size = be64_to_cpup(reserve_map++); | ||
654 | if (size == 0) | ||
655 | break; | ||
656 | DBG("reserving: %llx -> %llx\n", base, size); | ||
657 | memblock_reserve(base, size); | ||
658 | } | ||
659 | } | 639 | } |
660 | 640 | ||
661 | void __init early_init_devtree(void *params) | 641 | void __init early_init_devtree(void *params) |
@@ -922,23 +902,3 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) | |||
922 | { | 902 | { |
923 | return (int)phys_id == get_hard_smp_processor_id(cpu); | 903 | return (int)phys_id == get_hard_smp_processor_id(cpu); |
924 | } | 904 | } |
925 | |||
926 | #if defined(CONFIG_DEBUG_FS) && defined(DEBUG) | ||
927 | static struct debugfs_blob_wrapper flat_dt_blob; | ||
928 | |||
929 | static int __init export_flat_device_tree(void) | ||
930 | { | ||
931 | struct dentry *d; | ||
932 | |||
933 | flat_dt_blob.data = initial_boot_params; | ||
934 | flat_dt_blob.size = be32_to_cpu(initial_boot_params->totalsize); | ||
935 | |||
936 | d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, | ||
937 | powerpc_debugfs_root, &flat_dt_blob); | ||
938 | if (!d) | ||
939 | return 1; | ||
940 | |||
941 | return 0; | ||
942 | } | ||
943 | __initcall(export_flat_device_tree); | ||
944 | #endif | ||
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 8cd5ed049b5d..8b4c857c1421 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -1142,7 +1142,7 @@ void __init rtas_initialize(void) | |||
1142 | int __init early_init_dt_scan_rtas(unsigned long node, | 1142 | int __init early_init_dt_scan_rtas(unsigned long node, |
1143 | const char *uname, int depth, void *data) | 1143 | const char *uname, int depth, void *data) |
1144 | { | 1144 | { |
1145 | u32 *basep, *entryp, *sizep; | 1145 | const u32 *basep, *entryp, *sizep; |
1146 | 1146 | ||
1147 | if (depth != 1 || strcmp(uname, "rtas") != 0) | 1147 | if (depth != 1 || strcmp(uname, "rtas") != 0) |
1148 | return 0; | 1148 | return 0; |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 06ba83b036d3..350aa58a6f95 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -269,9 +269,9 @@ static int __init htab_dt_scan_seg_sizes(unsigned long node, | |||
269 | const char *uname, int depth, | 269 | const char *uname, int depth, |
270 | void *data) | 270 | void *data) |
271 | { | 271 | { |
272 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | 272 | const char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
273 | __be32 *prop; | 273 | const __be32 *prop; |
274 | unsigned long size = 0; | 274 | int size = 0; |
275 | 275 | ||
276 | /* We are scanning "cpu" nodes only */ | 276 | /* We are scanning "cpu" nodes only */ |
277 | if (type == NULL || strcmp(type, "cpu") != 0) | 277 | if (type == NULL || strcmp(type, "cpu") != 0) |
@@ -324,9 +324,9 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, | |||
324 | const char *uname, int depth, | 324 | const char *uname, int depth, |
325 | void *data) | 325 | void *data) |
326 | { | 326 | { |
327 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | 327 | const char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
328 | __be32 *prop; | 328 | const __be32 *prop; |
329 | unsigned long size = 0; | 329 | int size = 0; |
330 | 330 | ||
331 | /* We are scanning "cpu" nodes only */ | 331 | /* We are scanning "cpu" nodes only */ |
332 | if (type == NULL || strcmp(type, "cpu") != 0) | 332 | if (type == NULL || strcmp(type, "cpu") != 0) |
@@ -406,9 +406,9 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, | |||
406 | static int __init htab_dt_scan_hugepage_blocks(unsigned long node, | 406 | static int __init htab_dt_scan_hugepage_blocks(unsigned long node, |
407 | const char *uname, int depth, | 407 | const char *uname, int depth, |
408 | void *data) { | 408 | void *data) { |
409 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | 409 | const char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
410 | __be64 *addr_prop; | 410 | const __be64 *addr_prop; |
411 | __be32 *page_count_prop; | 411 | const __be32 *page_count_prop; |
412 | unsigned int expected_pages; | 412 | unsigned int expected_pages; |
413 | long unsigned int phys_addr; | 413 | long unsigned int phys_addr; |
414 | long unsigned int block_size; | 414 | long unsigned int block_size; |
@@ -550,8 +550,8 @@ static int __init htab_dt_scan_pftsize(unsigned long node, | |||
550 | const char *uname, int depth, | 550 | const char *uname, int depth, |
551 | void *data) | 551 | void *data) |
552 | { | 552 | { |
553 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | 553 | const char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
554 | __be32 *prop; | 554 | const __be32 *prop; |
555 | 555 | ||
556 | /* We are scanning "cpu" nodes only */ | 556 | /* We are scanning "cpu" nodes only */ |
557 | if (type == NULL || strcmp(type, "cpu") != 0) | 557 | if (type == NULL || strcmp(type, "cpu") != 0) |
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 18c104820198..6e19b0ad5d26 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c | |||
@@ -199,8 +199,8 @@ static void __init efika_setup_arch(void) | |||
199 | 199 | ||
200 | static int __init efika_probe(void) | 200 | static int __init efika_probe(void) |
201 | { | 201 | { |
202 | char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), | 202 | const char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), |
203 | "model", NULL); | 203 | "model", NULL); |
204 | 204 | ||
205 | if (model == NULL) | 205 | if (model == NULL) |
206 | return 0; | 206 | return 0; |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index c665d7de6c99..7044fd36197b 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -574,8 +574,8 @@ chrp_init2(void) | |||
574 | 574 | ||
575 | static int __init chrp_probe(void) | 575 | static int __init chrp_probe(void) |
576 | { | 576 | { |
577 | char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), | 577 | const char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), |
578 | "device_type", NULL); | 578 | "device_type", NULL); |
579 | if (dtype == NULL) | 579 | if (dtype == NULL) |
580 | return 0; | 580 | return 0; |
581 | if (strcmp(dtype, "chrp")) | 581 | if (strcmp(dtype, "chrp")) |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 360ad80c754c..f343183add07 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -61,7 +61,7 @@ int __init early_init_dt_scan_opal(unsigned long node, | |||
61 | const char *uname, int depth, void *data) | 61 | const char *uname, int depth, void *data) |
62 | { | 62 | { |
63 | const void *basep, *entryp, *sizep; | 63 | const void *basep, *entryp, *sizep; |
64 | unsigned long basesz, entrysz, runtimesz; | 64 | int basesz, entrysz, runtimesz; |
65 | 65 | ||
66 | if (depth != 1 || strcmp(uname, "ibm,opal") != 0) | 66 | if (depth != 1 || strcmp(uname, "ibm,opal") != 0) |
67 | return 0; | 67 | return 0; |
@@ -77,11 +77,11 @@ int __init early_init_dt_scan_opal(unsigned long node, | |||
77 | opal.entry = of_read_number(entryp, entrysz/4); | 77 | opal.entry = of_read_number(entryp, entrysz/4); |
78 | opal.size = of_read_number(sizep, runtimesz/4); | 78 | opal.size = of_read_number(sizep, runtimesz/4); |
79 | 79 | ||
80 | pr_debug("OPAL Base = 0x%llx (basep=%p basesz=%ld)\n", | 80 | pr_debug("OPAL Base = 0x%llx (basep=%p basesz=%d)\n", |
81 | opal.base, basep, basesz); | 81 | opal.base, basep, basesz); |
82 | pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%ld)\n", | 82 | pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%d)\n", |
83 | opal.entry, entryp, entrysz); | 83 | opal.entry, entryp, entrysz); |
84 | pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%ld)\n", | 84 | pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n", |
85 | opal.size, sizep, runtimesz); | 85 | opal.size, sizep, runtimesz); |
86 | 86 | ||
87 | powerpc_firmware_features |= FW_FEATURE_OPAL; | 87 | powerpc_firmware_features |= FW_FEATURE_OPAL; |
@@ -102,7 +102,7 @@ int __init early_init_dt_scan_opal(unsigned long node, | |||
102 | int __init early_init_dt_scan_recoverable_ranges(unsigned long node, | 102 | int __init early_init_dt_scan_recoverable_ranges(unsigned long node, |
103 | const char *uname, int depth, void *data) | 103 | const char *uname, int depth, void *data) |
104 | { | 104 | { |
105 | unsigned long i, psize, size; | 105 | int i, psize, size; |
106 | const __be32 *prop; | 106 | const __be32 *prop; |
107 | 107 | ||
108 | if (depth != 1 || strcmp(uname, "ibm,opal") != 0) | 108 | if (depth != 1 || strcmp(uname, "ibm,opal") != 0) |
@@ -359,7 +359,7 @@ int opal_get_chars(uint32_t vtermno, char *buf, int count) | |||
359 | if ((be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_INPUT) == 0) | 359 | if ((be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_INPUT) == 0) |
360 | return 0; | 360 | return 0; |
361 | len = cpu_to_be64(count); | 361 | len = cpu_to_be64(count); |
362 | rc = opal_console_read(vtermno, &len, buf); | 362 | rc = opal_console_read(vtermno, &len, buf); |
363 | if (rc == OPAL_SUCCESS) | 363 | if (rc == OPAL_SUCCESS) |
364 | return be64_to_cpu(len); | 364 | return be64_to_cpu(len); |
365 | return 0; | 365 | return 0; |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 2db8cc691bf4..099d2df976a2 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -665,7 +665,7 @@ static int __init pseries_probe_fw_features(unsigned long node, | |||
665 | void *data) | 665 | void *data) |
666 | { | 666 | { |
667 | const char *prop; | 667 | const char *prop; |
668 | unsigned long len; | 668 | int len; |
669 | static int hypertas_found; | 669 | static int hypertas_found; |
670 | static int vec5_found; | 670 | static int vec5_found; |
671 | 671 | ||
@@ -698,7 +698,7 @@ static int __init pseries_probe_fw_features(unsigned long node, | |||
698 | static int __init pSeries_probe(void) | 698 | static int __init pSeries_probe(void) |
699 | { | 699 | { |
700 | unsigned long root = of_get_flat_dt_root(); | 700 | unsigned long root = of_get_flat_dt_root(); |
701 | char *dtype = of_get_flat_dt_prop(root, "device_type", NULL); | 701 | const char *dtype = of_get_flat_dt_prop(root, "device_type", NULL); |
702 | 702 | ||
703 | if (dtype == NULL) | 703 | if (dtype == NULL) |
704 | return 0; | 704 | return 0; |
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 1bd0eba4d355..e9056e438575 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c | |||
@@ -152,9 +152,9 @@ EXPORT_SYMBOL_GPL(dcr_resource_len); | |||
152 | 152 | ||
153 | #ifdef CONFIG_PPC_DCR_MMIO | 153 | #ifdef CONFIG_PPC_DCR_MMIO |
154 | 154 | ||
155 | u64 of_translate_dcr_address(struct device_node *dev, | 155 | static u64 of_translate_dcr_address(struct device_node *dev, |
156 | unsigned int dcr_n, | 156 | unsigned int dcr_n, |
157 | unsigned int *out_stride) | 157 | unsigned int *out_stride) |
158 | { | 158 | { |
159 | struct device_node *dp; | 159 | struct device_node *dp; |
160 | const u32 *p; | 160 | const u32 *p; |
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index d35078ea1446..7db54b5d5f86 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c | |||
@@ -206,23 +206,21 @@ static void __init dtb_apic_setup(void) | |||
206 | static void __init x86_flattree_get_config(void) | 206 | static void __init x86_flattree_get_config(void) |
207 | { | 207 | { |
208 | u32 size, map_len; | 208 | u32 size, map_len; |
209 | struct boot_param_header *dt; | 209 | void *dt; |
210 | 210 | ||
211 | if (!initial_dtb) | 211 | if (!initial_dtb) |
212 | return; | 212 | return; |
213 | 213 | ||
214 | map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), | 214 | map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); |
215 | (u64)sizeof(struct boot_param_header)); | ||
216 | 215 | ||
217 | dt = early_memremap(initial_dtb, map_len); | 216 | initial_boot_params = dt = early_memremap(initial_dtb, map_len); |
218 | size = be32_to_cpu(dt->totalsize); | 217 | size = of_get_flat_dt_size(); |
219 | if (map_len < size) { | 218 | if (map_len < size) { |
220 | early_iounmap(dt, map_len); | 219 | early_iounmap(dt, map_len); |
221 | dt = early_memremap(initial_dtb, size); | 220 | initial_boot_params = dt = early_memremap(initial_dtb, size); |
222 | map_len = size; | 221 | map_len = size; |
223 | } | 222 | } |
224 | 223 | ||
225 | initial_boot_params = dt; | ||
226 | unflatten_and_copy_device_tree(); | 224 | unflatten_and_copy_device_tree(); |
227 | early_iounmap(dt, map_len); | 225 | early_iounmap(dt, map_len); |
228 | } | 226 | } |
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 9757bb74e532..06370ccea9e9 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -74,7 +74,6 @@ extern int initrd_below_start_ok; | |||
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #ifdef CONFIG_OF | 76 | #ifdef CONFIG_OF |
77 | extern u32 __dtb_start[]; | ||
78 | void *dtb_start = __dtb_start; | 77 | void *dtb_start = __dtb_start; |
79 | #endif | 78 | #endif |
80 | 79 | ||
@@ -199,7 +198,7 @@ static int __init xtensa_dt_io_area(unsigned long node, const char *uname, | |||
199 | int depth, void *data) | 198 | int depth, void *data) |
200 | { | 199 | { |
201 | const __be32 *ranges; | 200 | const __be32 *ranges; |
202 | unsigned long len; | 201 | int len; |
203 | 202 | ||
204 | if (depth > 1) | 203 | if (depth > 1) |
205 | return 0; | 204 | return 0; |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 5b47210889e0..9e9227e1762d 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -131,9 +131,12 @@ EXPORT_SYMBOL_GPL(platform_get_resource_byname); | |||
131 | */ | 131 | */ |
132 | int platform_get_irq_byname(struct platform_device *dev, const char *name) | 132 | int platform_get_irq_byname(struct platform_device *dev, const char *name) |
133 | { | 133 | { |
134 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, | 134 | struct resource *r; |
135 | name); | 135 | |
136 | if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) | ||
137 | return of_irq_get_byname(dev->dev.of_node, name); | ||
136 | 138 | ||
139 | r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); | ||
137 | return r ? r->start : -ENXIO; | 140 | return r ? r->start : -ENXIO; |
138 | } | 141 | } |
139 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); | 142 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); |
diff --git a/drivers/clk/rockchip/clk-rockchip.c b/drivers/clk/rockchip/clk-rockchip.c index 967c141b1a20..4cf838d52ef6 100644 --- a/drivers/clk/rockchip/clk-rockchip.c +++ b/drivers/clk/rockchip/clk-rockchip.c | |||
@@ -24,8 +24,7 @@ static DEFINE_SPINLOCK(clk_lock); | |||
24 | * Gate clocks | 24 | * Gate clocks |
25 | */ | 25 | */ |
26 | 26 | ||
27 | static void __init rk2928_gate_clk_init(struct device_node *node, | 27 | static void __init rk2928_gate_clk_init(struct device_node *node) |
28 | void *data) | ||
29 | { | 28 | { |
30 | struct clk_onecell_data *clk_data; | 29 | struct clk_onecell_data *clk_data; |
31 | const char *clk_parent; | 30 | const char *clk_parent; |
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index bd7dc733c1ca..9eddf22d56a4 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -1278,8 +1278,7 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat | |||
1278 | const struct of_device_id *match; | 1278 | const struct of_device_id *match; |
1279 | void (*setup_function)(struct device_node *, const void *) = function; | 1279 | void (*setup_function)(struct device_node *, const void *) = function; |
1280 | 1280 | ||
1281 | for_each_matching_node(np, clk_match) { | 1281 | for_each_matching_node_and_match(np, clk_match, &match) { |
1282 | match = of_match_node(clk_match, np); | ||
1283 | data = match->data; | 1282 | data = match->data; |
1284 | setup_function(np, data); | 1283 | setup_function(np, data); |
1285 | } | 1284 | } |
@@ -1310,7 +1309,7 @@ static void __init sunxi_clock_protect(void) | |||
1310 | } | 1309 | } |
1311 | } | 1310 | } |
1312 | 1311 | ||
1313 | static void __init sunxi_init_clocks(void) | 1312 | static void __init sunxi_init_clocks(struct device_node *np) |
1314 | { | 1313 | { |
1315 | /* Register factor clocks */ | 1314 | /* Register factor clocks */ |
1316 | of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); | 1315 | of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); |
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index 3e2999d11d15..58734817d502 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c | |||
@@ -221,7 +221,7 @@ static void __init of_ti_gate_clk_setup(struct device_node *node) | |||
221 | { | 221 | { |
222 | _of_ti_gate_clk_setup(node, &omap_gate_clk_ops, NULL); | 222 | _of_ti_gate_clk_setup(node, &omap_gate_clk_ops, NULL); |
223 | } | 223 | } |
224 | CLK_OF_DECLARE(ti_gate_clk, "ti,gate-clock", of_ti_gate_clk_setup) | 224 | CLK_OF_DECLARE(ti_gate_clk, "ti,gate-clock", of_ti_gate_clk_setup); |
225 | 225 | ||
226 | static void __init of_ti_wait_gate_clk_setup(struct device_node *node) | 226 | static void __init of_ti_wait_gate_clk_setup(struct device_node *node) |
227 | { | 227 | { |
diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index ae2e4278c42a..0093a8e49e14 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c | |||
@@ -27,7 +27,7 @@ void __init clocksource_of_init(void) | |||
27 | { | 27 | { |
28 | struct device_node *np; | 28 | struct device_node *np; |
29 | const struct of_device_id *match; | 29 | const struct of_device_id *match; |
30 | clocksource_of_init_fn init_func; | 30 | of_init_fn_1 init_func; |
31 | unsigned clocksources = 0; | 31 | unsigned clocksources = 0; |
32 | 32 | ||
33 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { | 33 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { |
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index 63b3d4eb0ef7..4044ff287663 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c | |||
@@ -96,7 +96,7 @@ static struct irq_domain_ops icoll_irq_domain_ops = { | |||
96 | .xlate = irq_domain_xlate_onecell, | 96 | .xlate = irq_domain_xlate_onecell, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static void __init icoll_of_init(struct device_node *np, | 99 | static int __init icoll_of_init(struct device_node *np, |
100 | struct device_node *interrupt_parent) | 100 | struct device_node *interrupt_parent) |
101 | { | 101 | { |
102 | icoll_base = of_iomap(np, 0); | 102 | icoll_base = of_iomap(np, 0); |
@@ -110,6 +110,6 @@ static void __init icoll_of_init(struct device_node *np, | |||
110 | 110 | ||
111 | icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS, | 111 | icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS, |
112 | &icoll_irq_domain_ops, NULL); | 112 | &icoll_irq_domain_ops, NULL); |
113 | WARN_ON(!icoll_domain); | 113 | return icoll_domain ? 0 : -ENODEV; |
114 | } | 114 | } |
115 | IRQCHIP_DECLARE(mxs, "fsl,icoll", icoll_of_init); | 115 | IRQCHIP_DECLARE(mxs, "fsl,icoll", icoll_of_init); |
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c index bbcc944ed94f..78a6accd205f 100644 --- a/drivers/irqchip/irq-s3c24xx.c +++ b/drivers/irqchip/irq-s3c24xx.c | |||
@@ -1323,8 +1323,7 @@ static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = { | |||
1323 | }; | 1323 | }; |
1324 | 1324 | ||
1325 | int __init s3c2410_init_intc_of(struct device_node *np, | 1325 | int __init s3c2410_init_intc_of(struct device_node *np, |
1326 | struct device_node *interrupt_parent, | 1326 | struct device_node *interrupt_parent) |
1327 | struct s3c24xx_irq_of_ctrl *ctrl, int num_ctrl) | ||
1328 | { | 1327 | { |
1329 | return s3c_init_intc_of(np, interrupt_parent, | 1328 | return s3c_init_intc_of(np, interrupt_parent, |
1330 | s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl)); | 1329 | s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl)); |
@@ -1346,8 +1345,7 @@ static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = { | |||
1346 | }; | 1345 | }; |
1347 | 1346 | ||
1348 | int __init s3c2416_init_intc_of(struct device_node *np, | 1347 | int __init s3c2416_init_intc_of(struct device_node *np, |
1349 | struct device_node *interrupt_parent, | 1348 | struct device_node *interrupt_parent) |
1350 | struct s3c24xx_irq_of_ctrl *ctrl, int num_ctrl) | ||
1351 | { | 1349 | { |
1352 | return s3c_init_intc_of(np, interrupt_parent, | 1350 | return s3c_init_intc_of(np, interrupt_parent, |
1353 | s3c2416_ctrl, ARRAY_SIZE(s3c2416_ctrl)); | 1351 | s3c2416_ctrl, ARRAY_SIZE(s3c2416_ctrl)); |
diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c index cad3e2495552..0fe2f718d81c 100644 --- a/drivers/irqchip/irqchip.c +++ b/drivers/irqchip/irqchip.c | |||
@@ -19,11 +19,11 @@ | |||
19 | * special section. | 19 | * special section. |
20 | */ | 20 | */ |
21 | static const struct of_device_id | 21 | static const struct of_device_id |
22 | irqchip_of_match_end __used __section(__irqchip_of_end); | 22 | irqchip_of_match_end __used __section(__irqchip_of_table_end); |
23 | 23 | ||
24 | extern struct of_device_id __irqchip_begin[]; | 24 | extern struct of_device_id __irqchip_of_table[]; |
25 | 25 | ||
26 | void __init irqchip_init(void) | 26 | void __init irqchip_init(void) |
27 | { | 27 | { |
28 | of_irq_init(__irqchip_begin); | 28 | of_irq_init(__irqchip_of_table); |
29 | } | 29 | } |
diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h index e445ba2d6add..0f6486d4f1b0 100644 --- a/drivers/irqchip/irqchip.h +++ b/drivers/irqchip/irqchip.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #ifndef _IRQCHIP_H | 11 | #ifndef _IRQCHIP_H |
12 | #define _IRQCHIP_H | 12 | #define _IRQCHIP_H |
13 | 13 | ||
14 | #include <linux/of.h> | ||
15 | |||
14 | /* | 16 | /* |
15 | * This macro must be used by the different irqchip drivers to declare | 17 | * This macro must be used by the different irqchip drivers to declare |
16 | * the association between their DT compatible string and their | 18 | * the association between their DT compatible string and their |
@@ -21,9 +23,6 @@ | |||
21 | * @compstr: compatible string of the irqchip driver | 23 | * @compstr: compatible string of the irqchip driver |
22 | * @fn: initialization function | 24 | * @fn: initialization function |
23 | */ | 25 | */ |
24 | #define IRQCHIP_DECLARE(name,compstr,fn) \ | 26 | #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn) |
25 | static const struct of_device_id irqchip_of_match_##name \ | ||
26 | __used __section(__irqchip_of_table) \ | ||
27 | = { .compatible = compstr, .data = fn } | ||
28 | 27 | ||
29 | #endif | 28 | #endif |
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 | |||
20 | config OF_FLATTREE | 20 | config OF_FLATTREE |
21 | bool | 21 | bool |
22 | select DTC | 22 | select DTC |
23 | select LIBFDT | ||
23 | 24 | ||
24 | config OF_EARLY_FLATTREE | 25 | config 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 @@ | |||
1 | obj-y = base.o device.o platform.o | 1 | obj-y = base.o device.o platform.o |
2 | obj-$(CONFIG_OF_FLATTREE) += fdt.o | 2 | obj-$(CONFIG_OF_FLATTREE) += fdt.o |
3 | obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o | ||
3 | obj-$(CONFIG_OF_PROMTREE) += pdt.o | 4 | obj-$(CONFIG_OF_PROMTREE) += pdt.o |
4 | obj-$(CONFIG_OF_ADDRESS) += address.o | 5 | obj-$(CONFIG_OF_ADDRESS) += address.o |
5 | obj-$(CONFIG_OF_IRQ) += irq.o | 6 | obj-$(CONFIG_OF_IRQ) += irq.o |
@@ -10,3 +11,6 @@ obj-$(CONFIG_OF_PCI) += of_pci.o | |||
10 | obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o | 11 | obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o |
11 | obj-$(CONFIG_OF_MTD) += of_mtd.o | 12 | obj-$(CONFIG_OF_MTD) += of_mtd.o |
12 | obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o | 13 | obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o |
14 | |||
15 | CFLAGS_fdt.o = -I$(src)/../../scripts/dtc/libfdt | ||
16 | CFLAGS_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 | } |
565 | EXPORT_SYMBOL(of_translate_dma_address); | 564 | EXPORT_SYMBOL(of_translate_dma_address); |
566 | 565 | ||
567 | bool 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 | } | ||
584 | EXPORT_SYMBOL(of_can_translate_address); | ||
585 | |||
586 | const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, | 566 | const __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 | } |
696 | EXPORT_SYMBOL(of_get_next_parent); | 696 | EXPORT_SYMBOL(of_get_next_parent); |
697 | 697 | ||
698 | static 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 | } |
772 | EXPORT_SYMBOL(of_get_child_by_name); | 790 | EXPORT_SYMBOL(of_get_child_by_name); |
773 | 791 | ||
792 | static 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 | */ |
781 | struct device_node *of_find_node_by_path(const char *path) | 827 | struct 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 | ||
31 | char *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 | */ | ||
41 | void *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 | */ |
89 | int of_fdt_is_compatible(struct boot_param_header *blob, | 39 | int 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 | */ |
113 | int of_fdt_match(struct boot_param_header *blob, unsigned long node, | 64 | int 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 | */ |
152 | static void * unflatten_dt_node(struct boot_param_header *blob, | 103 | static 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 | */ |
361 | static void __unflatten_device_tree(struct boot_param_header *blob, | 300 | static 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) | |||
427 | void of_fdt_unflatten_tree(unsigned long *blob, | 365 | void 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 | } |
434 | EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); | 370 | EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); |
435 | 371 | ||
@@ -437,7 +373,7 @@ EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); | |||
437 | int __initdata dt_root_addr_cells; | 373 | int __initdata dt_root_addr_cells; |
438 | int __initdata dt_root_size_cells; | 374 | int __initdata dt_root_size_cells; |
439 | 375 | ||
440 | struct boot_param_header *initial_boot_params; | 376 | void *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 | */ |
494 | static int __init __reserved_mem_check_root(unsigned long node) | 430 | static 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 | */ |
558 | void __init early_init_fdt_scan_reserved_mem(void) | 494 | void __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 | */ |
628 | unsigned long __init of_get_flat_dt_root(void) | 552 | unsigned 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; | 560 | int __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 | */ |
646 | void *__init of_get_flat_dt_prop(unsigned long node, const char *name, | 571 | const 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 | */ | ||
682 | static 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 | */ | ||
728 | int __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 | |||
746 | const char * __init of_flat_dt_get_machine_name(void) | 604 | const 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, | |||
811 | static void __init early_init_dt_check_for_initrd(unsigned long node) | 669 | static 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 | ||
701 | extern struct of_device_id __earlycon_of_table[]; | ||
702 | |||
703 | int __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 | |||
745 | static int __init setup_of_earlycon(char *buf) | ||
746 | { | ||
747 | if (buf) | ||
748 | return 0; | ||
749 | |||
750 | return early_init_dt_scan_chosen_serial(); | ||
751 | } | ||
752 | early_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 | */ |
845 | int __init early_init_dt_scan_root(unsigned long node, const char *uname, | 758 | int __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 | ||
870 | u64 __init dt_mem_next_cell(int s, __be32 **cellp) | 783 | u64 __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) | |||
881 | int __init early_init_dt_scan_memory(unsigned long node, const char *uname, | 794 | int __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, | |||
927 | int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | 840 | int __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) | |||
1003 | int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base, | 916 | int __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) | ||
1001 | static struct debugfs_blob_wrapper flat_dt_blob; | ||
1002 | |||
1003 | static 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 | } | ||
1020 | module_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 | ||
28 | static 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 | ||
36 | static void __init of_dump_addr(const char *s, const __be32 *addr, int na) { } | ||
37 | #endif | ||
38 | |||
39 | /* Callbacks for bus specific translators */ | ||
40 | struct 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) */ | ||
49 | static 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 | |||
71 | static 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 | |||
88 | static 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 */ | ||
101 | static 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 | |||
110 | static 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 | */ | ||
164 | u64 __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 | */ | ||
416 | int 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 | } |
52 | EXPORT_SYMBOL(of_find_device_by_node); | 52 | EXPORT_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 | */ |
75 | void of_device_make_bus_id(struct device *dev) | 71 | void 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 | ||
34 | static 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 | |||
34 | static void __init of_selftest_dynamic(void) | 79 | static 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) | |||
431 | static void __init of_selftest_platform_populate(void) | 476 | static 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 | ||
461 | static int __init of_selftest(void) | 520 | static 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 | }; | ||
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index ee3d80346780..908a6e3142a2 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -2072,6 +2072,7 @@ static int __init pl011_early_console_setup(struct earlycon_device *device, | |||
2072 | return 0; | 2072 | return 0; |
2073 | } | 2073 | } |
2074 | EARLYCON_DECLARE(pl011, pl011_early_console_setup); | 2074 | EARLYCON_DECLARE(pl011, pl011_early_console_setup); |
2075 | OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup); | ||
2075 | 2076 | ||
2076 | #else | 2077 | #else |
2077 | #define AMBA_CONSOLE NULL | 2078 | #define AMBA_CONSOLE NULL |
diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index c92e83088adb..5131b5ee6164 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/serial_core.h> | 17 | #include <linux/serial_core.h> |
18 | #include <linux/sizes.h> | ||
19 | #include <linux/mod_devicetable.h> | ||
18 | 20 | ||
19 | #ifdef CONFIG_FIX_EARLYCON_MEM | 21 | #ifdef CONFIG_FIX_EARLYCON_MEM |
20 | #include <asm/fixmap.h> | 22 | #include <asm/fixmap.h> |
@@ -32,6 +34,9 @@ static struct earlycon_device early_console_dev = { | |||
32 | .con = &early_con, | 34 | .con = &early_con, |
33 | }; | 35 | }; |
34 | 36 | ||
37 | static const struct of_device_id __earlycon_of_table_sentinel | ||
38 | __used __section(__earlycon_of_table_end); | ||
39 | |||
35 | static void __iomem * __init earlycon_map(unsigned long paddr, size_t size) | 40 | static void __iomem * __init earlycon_map(unsigned long paddr, size_t size) |
36 | { | 41 | { |
37 | void __iomem *base; | 42 | void __iomem *base; |
@@ -142,3 +147,26 @@ int __init setup_earlycon(char *buf, const char *match, | |||
142 | register_console(early_console_dev.con); | 147 | register_console(early_console_dev.con); |
143 | return 0; | 148 | return 0; |
144 | } | 149 | } |
150 | |||
151 | int __init of_setup_earlycon(unsigned long addr, | ||
152 | int (*setup)(struct earlycon_device *, const char *)) | ||
153 | { | ||
154 | int err; | ||
155 | struct uart_port *port = &early_console_dev.port; | ||
156 | |||
157 | port->iotype = UPIO_MEM; | ||
158 | port->mapbase = addr; | ||
159 | port->uartclk = BASE_BAUD * 16; | ||
160 | port->membase = earlycon_map(addr, SZ_4K); | ||
161 | |||
162 | early_console_dev.con->data = &early_console_dev; | ||
163 | err = setup(&early_console_dev, NULL); | ||
164 | if (err < 0) | ||
165 | return err; | ||
166 | if (!early_console_dev.con->write) | ||
167 | return -ENODEV; | ||
168 | |||
169 | |||
170 | register_console(early_console_dev.con); | ||
171 | return 0; | ||
172 | } | ||
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 146e4fffd710..d647637cd699 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -139,52 +139,23 @@ | |||
139 | #define TRACE_SYSCALLS() | 139 | #define TRACE_SYSCALLS() |
140 | #endif | 140 | #endif |
141 | 141 | ||
142 | #ifdef CONFIG_CLKSRC_OF | ||
143 | #define CLKSRC_OF_TABLES() . = ALIGN(8); \ | ||
144 | VMLINUX_SYMBOL(__clksrc_of_table) = .; \ | ||
145 | *(__clksrc_of_table) \ | ||
146 | *(__clksrc_of_table_end) | ||
147 | #else | ||
148 | #define CLKSRC_OF_TABLES() | ||
149 | #endif | ||
150 | 142 | ||
151 | #ifdef CONFIG_IRQCHIP | 143 | #define ___OF_TABLE(cfg, name) _OF_TABLE_##cfg(name) |
152 | #define IRQCHIP_OF_MATCH_TABLE() \ | 144 | #define __OF_TABLE(cfg, name) ___OF_TABLE(cfg, name) |
145 | #define OF_TABLE(cfg, name) __OF_TABLE(config_enabled(cfg), name) | ||
146 | #define _OF_TABLE_0(name) | ||
147 | #define _OF_TABLE_1(name) \ | ||
153 | . = ALIGN(8); \ | 148 | . = ALIGN(8); \ |
154 | VMLINUX_SYMBOL(__irqchip_begin) = .; \ | 149 | VMLINUX_SYMBOL(__##name##_of_table) = .; \ |
155 | *(__irqchip_of_table) \ | 150 | *(__##name##_of_table) \ |
156 | *(__irqchip_of_end) | 151 | *(__##name##_of_table_end) |
157 | #else | ||
158 | #define IRQCHIP_OF_MATCH_TABLE() | ||
159 | #endif | ||
160 | |||
161 | #ifdef CONFIG_COMMON_CLK | ||
162 | #define CLK_OF_TABLES() . = ALIGN(8); \ | ||
163 | VMLINUX_SYMBOL(__clk_of_table) = .; \ | ||
164 | *(__clk_of_table) \ | ||
165 | *(__clk_of_table_end) | ||
166 | #else | ||
167 | #define CLK_OF_TABLES() | ||
168 | #endif | ||
169 | |||
170 | #ifdef CONFIG_OF_RESERVED_MEM | ||
171 | #define RESERVEDMEM_OF_TABLES() \ | ||
172 | . = ALIGN(8); \ | ||
173 | VMLINUX_SYMBOL(__reservedmem_of_table) = .; \ | ||
174 | *(__reservedmem_of_table) \ | ||
175 | *(__reservedmem_of_table_end) | ||
176 | #else | ||
177 | #define RESERVEDMEM_OF_TABLES() | ||
178 | #endif | ||
179 | 152 | ||
180 | #ifdef CONFIG_SMP | 153 | #define CLKSRC_OF_TABLES() OF_TABLE(CONFIG_CLKSRC_OF, clksrc) |
181 | #define CPU_METHOD_OF_TABLES() . = ALIGN(8); \ | 154 | #define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip) |
182 | VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \ | 155 | #define CLK_OF_TABLES() OF_TABLE(CONFIG_COMMON_CLK, clk) |
183 | *(__cpu_method_of_table) \ | 156 | #define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) |
184 | VMLINUX_SYMBOL(__cpu_method_of_table_end) = .; | 157 | #define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) |
185 | #else | 158 | #define EARLYCON_OF_TABLES() OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon) |
186 | #define CPU_METHOD_OF_TABLES() | ||
187 | #endif | ||
188 | 159 | ||
189 | #define KERNEL_DTB() \ | 160 | #define KERNEL_DTB() \ |
190 | STRUCT_ALIGN(); \ | 161 | STRUCT_ALIGN(); \ |
@@ -513,7 +484,8 @@ | |||
513 | CLKSRC_OF_TABLES() \ | 484 | CLKSRC_OF_TABLES() \ |
514 | CPU_METHOD_OF_TABLES() \ | 485 | CPU_METHOD_OF_TABLES() \ |
515 | KERNEL_DTB() \ | 486 | KERNEL_DTB() \ |
516 | IRQCHIP_OF_MATCH_TABLE() | 487 | IRQCHIP_OF_MATCH_TABLE() \ |
488 | EARLYCON_OF_TABLES() | ||
517 | 489 | ||
518 | #define INIT_TEXT \ | 490 | #define INIT_TEXT \ |
519 | *(.init.text) \ | 491 | *(.init.text) \ |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index fb4eca6907cd..f295bab1865d 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -529,10 +529,7 @@ struct clk_onecell_data { | |||
529 | 529 | ||
530 | extern struct of_device_id __clk_of_table; | 530 | extern struct of_device_id __clk_of_table; |
531 | 531 | ||
532 | #define CLK_OF_DECLARE(name, compat, fn) \ | 532 | #define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn) |
533 | static const struct of_device_id __clk_of_table_##name \ | ||
534 | __used __section(__clk_of_table) \ | ||
535 | = { .compatible = compat, .data = fn }; | ||
536 | 533 | ||
537 | #ifdef CONFIG_OF | 534 | #ifdef CONFIG_OF |
538 | int of_clk_add_provider(struct device_node *np, | 535 | int of_clk_add_provider(struct device_node *np, |
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 67301a405712..a16b497d5159 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h | |||
@@ -339,23 +339,13 @@ extern int clocksource_mmio_init(void __iomem *, const char *, | |||
339 | 339 | ||
340 | extern int clocksource_i8253_init(void); | 340 | extern int clocksource_i8253_init(void); |
341 | 341 | ||
342 | struct device_node; | 342 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ |
343 | typedef void(*clocksource_of_init_fn)(struct device_node *); | 343 | OF_DECLARE_1(clksrc, name, compat, fn) |
344 | |||
344 | #ifdef CONFIG_CLKSRC_OF | 345 | #ifdef CONFIG_CLKSRC_OF |
345 | extern void clocksource_of_init(void); | 346 | extern void clocksource_of_init(void); |
346 | |||
347 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ | ||
348 | static const struct of_device_id __clksrc_of_table_##name \ | ||
349 | __used __section(__clksrc_of_table) \ | ||
350 | = { .compatible = compat, \ | ||
351 | .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn } | ||
352 | #else | 347 | #else |
353 | static inline void clocksource_of_init(void) {} | 348 | static inline void clocksource_of_init(void) {} |
354 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ | ||
355 | static const struct of_device_id __clksrc_of_table_##name \ | ||
356 | __attribute__((unused)) \ | ||
357 | = { .compatible = compat, \ | ||
358 | .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn } | ||
359 | #endif | 349 | #endif |
360 | 350 | ||
361 | #endif /* _LINUX_CLOCKSOURCE_H */ | 351 | #endif /* _LINUX_CLOCKSOURCE_H */ |
diff --git a/include/linux/of.h b/include/linux/of.h index fa362867b453..196b34c1ef4e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -764,4 +764,26 @@ static inline int of_get_available_child_count(const struct device_node *np) | |||
764 | return num; | 764 | return num; |
765 | } | 765 | } |
766 | 766 | ||
767 | #ifdef CONFIG_OF | ||
768 | #define _OF_DECLARE(table, name, compat, fn, fn_type) \ | ||
769 | static const struct of_device_id __of_table_##name \ | ||
770 | __used __section(__##table##_of_table) \ | ||
771 | = { .compatible = compat, \ | ||
772 | .data = (fn == (fn_type)NULL) ? fn : fn } | ||
773 | #else | ||
774 | #define _OF_DECLARE(table, name, compat, fn, fn_type) \ | ||
775 | static const struct of_device_id __of_table_##name \ | ||
776 | __attribute__((unused)) \ | ||
777 | = { .compatible = compat, \ | ||
778 | .data = (fn == (fn_type)NULL) ? fn : fn } | ||
779 | #endif | ||
780 | |||
781 | typedef int (*of_init_fn_2)(struct device_node *, struct device_node *); | ||
782 | typedef void (*of_init_fn_1)(struct device_node *); | ||
783 | |||
784 | #define OF_DECLARE_1(table, name, compat, fn) \ | ||
785 | _OF_DECLARE(table, name, compat, fn, of_init_fn_1) | ||
786 | #define OF_DECLARE_2(table, name, compat, fn) \ | ||
787 | _OF_DECLARE(table, name, compat, fn, of_init_fn_2) | ||
788 | |||
767 | #endif /* _LINUX_OF_H */ | 789 | #endif /* _LINUX_OF_H */ |
diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 5f6ed6b182b8..906ca7681756 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h | |||
@@ -40,7 +40,6 @@ extern u64 of_translate_dma_address(struct device_node *dev, | |||
40 | 40 | ||
41 | #ifdef CONFIG_OF_ADDRESS | 41 | #ifdef CONFIG_OF_ADDRESS |
42 | extern u64 of_translate_address(struct device_node *np, const __be32 *addr); | 42 | extern u64 of_translate_address(struct device_node *np, const __be32 *addr); |
43 | extern bool of_can_translate_address(struct device_node *dev); | ||
44 | extern int of_address_to_resource(struct device_node *dev, int index, | 43 | extern int of_address_to_resource(struct device_node *dev, int index, |
45 | struct resource *r); | 44 | struct resource *r); |
46 | extern struct device_node *of_find_matching_node_by_address( | 45 | extern struct device_node *of_find_matching_node_by_address( |
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index ddd7219af8ac..05117899fcb4 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h | |||
@@ -17,60 +17,23 @@ | |||
17 | 17 | ||
18 | /* Definitions used by the flattened device tree */ | 18 | /* Definitions used by the flattened device tree */ |
19 | #define OF_DT_HEADER 0xd00dfeed /* marker */ | 19 | #define OF_DT_HEADER 0xd00dfeed /* marker */ |
20 | #define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ | ||
21 | #define OF_DT_END_NODE 0x2 /* End node */ | ||
22 | #define OF_DT_PROP 0x3 /* Property: name off, size, | ||
23 | * content */ | ||
24 | #define OF_DT_NOP 0x4 /* nop */ | ||
25 | #define OF_DT_END 0x9 | ||
26 | |||
27 | #define OF_DT_VERSION 0x10 | ||
28 | 20 | ||
29 | #ifndef __ASSEMBLY__ | 21 | #ifndef __ASSEMBLY__ |
30 | /* | ||
31 | * This is what gets passed to the kernel by prom_init or kexec | ||
32 | * | ||
33 | * The dt struct contains the device tree structure, full pathes and | ||
34 | * property contents. The dt strings contain a separate block with just | ||
35 | * the strings for the property names, and is fully page aligned and | ||
36 | * self contained in a page, so that it can be kept around by the kernel, | ||
37 | * each property name appears only once in this page (cheap compression) | ||
38 | * | ||
39 | * the mem_rsvmap contains a map of reserved ranges of physical memory, | ||
40 | * passing it here instead of in the device-tree itself greatly simplifies | ||
41 | * the job of everybody. It's just a list of u64 pairs (base/size) that | ||
42 | * ends when size is 0 | ||
43 | */ | ||
44 | struct boot_param_header { | ||
45 | __be32 magic; /* magic word OF_DT_HEADER */ | ||
46 | __be32 totalsize; /* total size of DT block */ | ||
47 | __be32 off_dt_struct; /* offset to structure */ | ||
48 | __be32 off_dt_strings; /* offset to strings */ | ||
49 | __be32 off_mem_rsvmap; /* offset to memory reserve map */ | ||
50 | __be32 version; /* format version */ | ||
51 | __be32 last_comp_version; /* last compatible version */ | ||
52 | /* version 2 fields below */ | ||
53 | __be32 boot_cpuid_phys; /* Physical CPU id we're booting on */ | ||
54 | /* version 3 fields below */ | ||
55 | __be32 dt_strings_size; /* size of the DT strings block */ | ||
56 | /* version 17 fields below */ | ||
57 | __be32 dt_struct_size; /* size of the DT structure block */ | ||
58 | }; | ||
59 | 22 | ||
60 | #if defined(CONFIG_OF_FLATTREE) | 23 | #if defined(CONFIG_OF_FLATTREE) |
61 | 24 | ||
62 | struct device_node; | 25 | struct device_node; |
63 | 26 | ||
64 | /* For scanning an arbitrary device-tree at any time */ | 27 | /* For scanning an arbitrary device-tree at any time */ |
65 | extern char *of_fdt_get_string(struct boot_param_header *blob, u32 offset); | 28 | extern char *of_fdt_get_string(const void *blob, u32 offset); |
66 | extern void *of_fdt_get_property(struct boot_param_header *blob, | 29 | extern void *of_fdt_get_property(const void *blob, |
67 | unsigned long node, | 30 | unsigned long node, |
68 | const char *name, | 31 | const char *name, |
69 | unsigned long *size); | 32 | int *size); |
70 | extern int of_fdt_is_compatible(struct boot_param_header *blob, | 33 | extern int of_fdt_is_compatible(const void *blob, |
71 | unsigned long node, | 34 | unsigned long node, |
72 | const char *compat); | 35 | const char *compat); |
73 | extern int of_fdt_match(struct boot_param_header *blob, unsigned long node, | 36 | extern int of_fdt_match(const void *blob, unsigned long node, |
74 | const char *const *compat); | 37 | const char *const *compat); |
75 | extern void of_fdt_unflatten_tree(unsigned long *blob, | 38 | extern void of_fdt_unflatten_tree(unsigned long *blob, |
76 | struct device_node **mynodes); | 39 | struct device_node **mynodes); |
@@ -78,21 +41,21 @@ extern void of_fdt_unflatten_tree(unsigned long *blob, | |||
78 | /* TBD: Temporary export of fdt globals - remove when code fully merged */ | 41 | /* TBD: Temporary export of fdt globals - remove when code fully merged */ |
79 | extern int __initdata dt_root_addr_cells; | 42 | extern int __initdata dt_root_addr_cells; |
80 | extern int __initdata dt_root_size_cells; | 43 | extern int __initdata dt_root_size_cells; |
81 | extern struct boot_param_header *initial_boot_params; | 44 | extern void *initial_boot_params; |
45 | |||
46 | extern char __dtb_start[]; | ||
47 | extern char __dtb_end[]; | ||
82 | 48 | ||
83 | /* For scanning the flat device-tree at boot time */ | 49 | /* For scanning the flat device-tree at boot time */ |
84 | extern char *find_flat_dt_string(u32 offset); | ||
85 | extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname, | 50 | extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname, |
86 | int depth, void *data), | 51 | int depth, void *data), |
87 | void *data); | 52 | void *data); |
88 | extern void *of_get_flat_dt_prop(unsigned long node, const char *name, | 53 | extern const void *of_get_flat_dt_prop(unsigned long node, const char *name, |
89 | unsigned long *size); | 54 | int *size); |
90 | extern int of_flat_dt_is_compatible(unsigned long node, const char *name); | 55 | extern int of_flat_dt_is_compatible(unsigned long node, const char *name); |
91 | extern int of_flat_dt_match(unsigned long node, const char *const *matches); | 56 | extern int of_flat_dt_match(unsigned long node, const char *const *matches); |
92 | extern unsigned long of_get_flat_dt_root(void); | 57 | extern unsigned long of_get_flat_dt_root(void); |
93 | extern int of_scan_flat_dt_by_path(const char *path, | 58 | extern int of_get_flat_dt_size(void); |
94 | int (*it)(unsigned long node, const char *name, int depth, void *data), | ||
95 | void *data); | ||
96 | 59 | ||
97 | extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, | 60 | extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, |
98 | int depth, void *data); | 61 | int depth, void *data); |
@@ -103,7 +66,7 @@ extern void early_init_dt_add_memory_arch(u64 base, u64 size); | |||
103 | extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, | 66 | extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, |
104 | bool no_map); | 67 | bool no_map); |
105 | extern void * early_init_dt_alloc_memory_arch(u64 size, u64 align); | 68 | extern void * early_init_dt_alloc_memory_arch(u64 size, u64 align); |
106 | extern u64 dt_mem_next_cell(int s, __be32 **cellp); | 69 | extern u64 dt_mem_next_cell(int s, const __be32 **cellp); |
107 | 70 | ||
108 | /* Early flat tree scan hooks */ | 71 | /* Early flat tree scan hooks */ |
109 | extern int early_init_dt_scan_root(unsigned long node, const char *uname, | 72 | extern int early_init_dt_scan_root(unsigned long node, const char *uname, |
@@ -120,6 +83,7 @@ extern void unflatten_device_tree(void); | |||
120 | extern void unflatten_and_copy_device_tree(void); | 83 | extern void unflatten_and_copy_device_tree(void); |
121 | extern void early_init_devtree(void *); | 84 | extern void early_init_devtree(void *); |
122 | extern void early_get_first_memblock_info(void *, phys_addr_t *); | 85 | extern void early_get_first_memblock_info(void *, phys_addr_t *); |
86 | extern u64 fdt_translate_address(const void *blob, int node_offset); | ||
123 | #else /* CONFIG_OF_FLATTREE */ | 87 | #else /* CONFIG_OF_FLATTREE */ |
124 | static inline void early_init_fdt_scan_reserved_mem(void) {} | 88 | static inline void early_init_fdt_scan_reserved_mem(void) {} |
125 | static inline const char *of_flat_dt_get_machine_name(void) { return NULL; } | 89 | static inline const char *of_flat_dt_get_machine_name(void) { return NULL; } |
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 6404253d810d..bfec136a6d1e 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h | |||
@@ -45,6 +45,7 @@ extern void of_irq_init(const struct of_device_id *matches); | |||
45 | #ifdef CONFIG_OF_IRQ | 45 | #ifdef CONFIG_OF_IRQ |
46 | extern int of_irq_count(struct device_node *dev); | 46 | extern int of_irq_count(struct device_node *dev); |
47 | extern int of_irq_get(struct device_node *dev, int index); | 47 | extern int of_irq_get(struct device_node *dev, int index); |
48 | extern int of_irq_get_byname(struct device_node *dev, const char *name); | ||
48 | #else | 49 | #else |
49 | static inline int of_irq_count(struct device_node *dev) | 50 | static inline int of_irq_count(struct device_node *dev) |
50 | { | 51 | { |
@@ -54,6 +55,10 @@ static inline int of_irq_get(struct device_node *dev, int index) | |||
54 | { | 55 | { |
55 | return 0; | 56 | return 0; |
56 | } | 57 | } |
58 | static inline int of_irq_get_byname(struct device_node *dev, const char *name) | ||
59 | { | ||
60 | return 0; | ||
61 | } | ||
57 | #endif | 62 | #endif |
58 | 63 | ||
59 | #if defined(CONFIG_OF) | 64 | #if defined(CONFIG_OF) |
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index 1a1f5ffd5288..dde3a4a0fa5d 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h | |||
@@ -6,14 +6,44 @@ | |||
6 | 6 | ||
7 | struct pci_dev; | 7 | struct pci_dev; |
8 | struct of_phandle_args; | 8 | struct of_phandle_args; |
9 | int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq); | ||
10 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); | ||
11 | |||
12 | struct device_node; | 9 | struct device_node; |
10 | |||
11 | #ifdef CONFIG_OF | ||
12 | int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq); | ||
13 | struct device_node *of_pci_find_child_device(struct device_node *parent, | 13 | struct device_node *of_pci_find_child_device(struct device_node *parent, |
14 | unsigned int devfn); | 14 | unsigned int devfn); |
15 | int of_pci_get_devfn(struct device_node *np); | 15 | int of_pci_get_devfn(struct device_node *np); |
16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); | ||
16 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); | 17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); |
18 | #else | ||
19 | static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) | ||
20 | { | ||
21 | return 0; | ||
22 | } | ||
23 | |||
24 | static inline struct device_node *of_pci_find_child_device(struct device_node *parent, | ||
25 | unsigned int devfn) | ||
26 | { | ||
27 | return NULL; | ||
28 | } | ||
29 | |||
30 | static inline int of_pci_get_devfn(struct device_node *np) | ||
31 | { | ||
32 | return -EINVAL; | ||
33 | } | ||
34 | |||
35 | static inline int | ||
36 | of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) | ||
37 | { | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static inline int | ||
42 | of_pci_parse_bus_range(struct device_node *node, struct resource *res) | ||
43 | { | ||
44 | return -EINVAL; | ||
45 | } | ||
46 | #endif | ||
17 | 47 | ||
18 | #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) | 48 | #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) |
19 | int of_pci_msi_chip_add(struct msi_chip *chip); | 49 | int of_pci_msi_chip_add(struct msi_chip *chip); |
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h index 9b1fbb7f29fc..4669ddfdd5af 100644 --- a/include/linux/of_reserved_mem.h +++ b/include/linux/of_reserved_mem.h | |||
@@ -21,33 +21,19 @@ struct reserved_mem_ops { | |||
21 | struct device *dev); | 21 | struct device *dev); |
22 | }; | 22 | }; |
23 | 23 | ||
24 | typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem, | 24 | typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem); |
25 | unsigned long node, const char *uname); | 25 | |
26 | #define RESERVEDMEM_OF_DECLARE(name, compat, init) \ | ||
27 | _OF_DECLARE(reservedmem, name, compat, init, reservedmem_of_init_fn) | ||
26 | 28 | ||
27 | #ifdef CONFIG_OF_RESERVED_MEM | 29 | #ifdef CONFIG_OF_RESERVED_MEM |
28 | void fdt_init_reserved_mem(void); | 30 | void fdt_init_reserved_mem(void); |
29 | void fdt_reserved_mem_save_node(unsigned long node, const char *uname, | 31 | void fdt_reserved_mem_save_node(unsigned long node, const char *uname, |
30 | phys_addr_t base, phys_addr_t size); | 32 | phys_addr_t base, phys_addr_t size); |
31 | |||
32 | #define RESERVEDMEM_OF_DECLARE(name, compat, init) \ | ||
33 | static const struct of_device_id __reservedmem_of_table_##name \ | ||
34 | __used __section(__reservedmem_of_table) \ | ||
35 | = { .compatible = compat, \ | ||
36 | .data = (init == (reservedmem_of_init_fn)NULL) ? \ | ||
37 | init : init } | ||
38 | |||
39 | #else | 33 | #else |
40 | static inline void fdt_init_reserved_mem(void) { } | 34 | static inline void fdt_init_reserved_mem(void) { } |
41 | static inline void fdt_reserved_mem_save_node(unsigned long node, | 35 | static inline void fdt_reserved_mem_save_node(unsigned long node, |
42 | const char *uname, phys_addr_t base, phys_addr_t size) { } | 36 | const char *uname, phys_addr_t base, phys_addr_t size) { } |
43 | |||
44 | #define RESERVEDMEM_OF_DECLARE(name, compat, init) \ | ||
45 | static const struct of_device_id __reservedmem_of_table_##name \ | ||
46 | __attribute__((unused)) \ | ||
47 | = { .compatible = compat, \ | ||
48 | .data = (init == (reservedmem_of_init_fn)NULL) ? \ | ||
49 | init : init } | ||
50 | |||
51 | #endif | 37 | #endif |
52 | 38 | ||
53 | #endif /* __OF_RESERVED_MEM_H */ | 39 | #endif /* __OF_RESERVED_MEM_H */ |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 7a15b5b24c0b..5bbb809ee197 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -294,6 +294,9 @@ struct earlycon_device { | |||
294 | int setup_earlycon(char *buf, const char *match, | 294 | int setup_earlycon(char *buf, const char *match, |
295 | int (*setup)(struct earlycon_device *, const char *)); | 295 | int (*setup)(struct earlycon_device *, const char *)); |
296 | 296 | ||
297 | extern int of_setup_earlycon(unsigned long addr, | ||
298 | int (*setup)(struct earlycon_device *, const char *)); | ||
299 | |||
297 | #define EARLYCON_DECLARE(name, func) \ | 300 | #define EARLYCON_DECLARE(name, func) \ |
298 | static int __init name ## _setup_earlycon(char *buf) \ | 301 | static int __init name ## _setup_earlycon(char *buf) \ |
299 | { \ | 302 | { \ |
@@ -301,6 +304,9 @@ static int __init name ## _setup_earlycon(char *buf) \ | |||
301 | } \ | 304 | } \ |
302 | early_param("earlycon", name ## _setup_earlycon); | 305 | early_param("earlycon", name ## _setup_earlycon); |
303 | 306 | ||
307 | #define OF_EARLYCON_DECLARE(name, compat, fn) \ | ||
308 | _OF_DECLARE(earlycon, name, compat, fn, void *) | ||
309 | |||
304 | struct uart_port *uart_get_console(struct uart_port *ports, int nr, | 310 | struct uart_port *uart_get_console(struct uart_port *ports, int nr, |
305 | struct console *c); | 311 | struct console *c); |
306 | void uart_parse_options(char *options, int *baud, int *parity, int *bits, | 312 | void uart_parse_options(char *options, int *baud, int *parity, int *bits, |
diff --git a/include/linux/string.h b/include/linux/string.h index ac889c5ea11b..d36977e029af 100644 --- a/include/linux/string.h +++ b/include/linux/string.h | |||
@@ -52,6 +52,9 @@ extern int strncasecmp(const char *s1, const char *s2, size_t n); | |||
52 | #ifndef __HAVE_ARCH_STRCHR | 52 | #ifndef __HAVE_ARCH_STRCHR |
53 | extern char * strchr(const char *,int); | 53 | extern char * strchr(const char *,int); |
54 | #endif | 54 | #endif |
55 | #ifndef __HAVE_ARCH_STRCHRNUL | ||
56 | extern char * strchrnul(const char *,int); | ||
57 | #endif | ||
55 | #ifndef __HAVE_ARCH_STRNCHR | 58 | #ifndef __HAVE_ARCH_STRNCHR |
56 | extern char * strnchr(const char *, size_t, int); | 59 | extern char * strnchr(const char *, size_t, int); |
57 | #endif | 60 | #endif |
diff --git a/lib/string.c b/lib/string.c index 9b1f9062a202..e0c20eb362f0 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -301,6 +301,24 @@ char *strchr(const char *s, int c) | |||
301 | EXPORT_SYMBOL(strchr); | 301 | EXPORT_SYMBOL(strchr); |
302 | #endif | 302 | #endif |
303 | 303 | ||
304 | #ifndef __HAVE_ARCH_STRCHRNUL | ||
305 | /** | ||
306 | * strchrnul - Find and return a character in a string, or end of string | ||
307 | * @s: The string to be searched | ||
308 | * @c: The character to search for | ||
309 | * | ||
310 | * Returns pointer to first occurrence of 'c' in s. If c is not found, then | ||
311 | * return a pointer to the null byte at the end of s. | ||
312 | */ | ||
313 | char *strchrnul(const char *s, int c) | ||
314 | { | ||
315 | while (*s && *s != (char)c) | ||
316 | s++; | ||
317 | return (char *)s; | ||
318 | } | ||
319 | EXPORT_SYMBOL(strchrnul); | ||
320 | #endif | ||
321 | |||
304 | #ifndef __HAVE_ARCH_STRRCHR | 322 | #ifndef __HAVE_ARCH_STRRCHR |
305 | /** | 323 | /** |
306 | * strrchr - Find the last occurrence of a character in a string | 324 | * strrchr - Find the last occurrence of a character in a string |