.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Procedures for creating, accessing and interpreting the device tree. |
---|
3 | 4 | * |
---|
.. | .. |
---|
8 | 9 | * {engebret|bergner}@us.ibm.com |
---|
9 | 10 | * |
---|
10 | 11 | * Adapted for sparc64 by David S. Miller davem@davemloft.net |
---|
11 | | - * |
---|
12 | | - * This program is free software; you can redistribute it and/or |
---|
13 | | - * modify it under the terms of the GNU General Public License |
---|
14 | | - * as published by the Free Software Foundation; either version |
---|
15 | | - * 2 of the License, or (at your option) any later version. |
---|
16 | 12 | */ |
---|
17 | 13 | |
---|
18 | 14 | #include <linux/memblock.h> |
---|
.. | .. |
---|
34 | 30 | |
---|
35 | 31 | void * __init prom_early_alloc(unsigned long size) |
---|
36 | 32 | { |
---|
37 | | - unsigned long paddr = memblock_alloc(size, SMP_CACHE_BYTES); |
---|
38 | | - void *ret; |
---|
| 33 | + void *ret = memblock_alloc(size, SMP_CACHE_BYTES); |
---|
39 | 34 | |
---|
40 | | - if (!paddr) { |
---|
| 35 | + if (!ret) { |
---|
41 | 36 | prom_printf("prom_early_alloc(%lu) failed\n", size); |
---|
42 | 37 | prom_halt(); |
---|
43 | 38 | } |
---|
44 | 39 | |
---|
45 | | - ret = __va(paddr); |
---|
46 | | - memset(ret, 0, size); |
---|
47 | 40 | prom_early_allocated += size; |
---|
48 | 41 | |
---|
49 | 42 | return ret; |
---|
.. | .. |
---|
72 | 65 | */ |
---|
73 | 66 | static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf) |
---|
74 | 67 | { |
---|
| 68 | + const char *name = of_get_property(dp, "name", NULL); |
---|
75 | 69 | struct linux_prom64_registers *regs; |
---|
76 | 70 | struct property *rprop; |
---|
77 | 71 | u32 high_bits, low_bits, type; |
---|
.. | .. |
---|
83 | 77 | regs = rprop->value; |
---|
84 | 78 | if (!of_node_is_root(dp->parent)) { |
---|
85 | 79 | sprintf(tmp_buf, "%s@%x,%x", |
---|
86 | | - dp->name, |
---|
| 80 | + name, |
---|
87 | 81 | (unsigned int) (regs->phys_addr >> 32UL), |
---|
88 | 82 | (unsigned int) (regs->phys_addr & 0xffffffffUL)); |
---|
89 | 83 | return; |
---|
.. | .. |
---|
98 | 92 | |
---|
99 | 93 | if (low_bits) |
---|
100 | 94 | sprintf(tmp_buf, "%s@%s%x,%x", |
---|
101 | | - dp->name, prefix, |
---|
| 95 | + name, prefix, |
---|
102 | 96 | high_bits, low_bits); |
---|
103 | 97 | else |
---|
104 | 98 | sprintf(tmp_buf, "%s@%s%x", |
---|
105 | | - dp->name, |
---|
| 99 | + name, |
---|
106 | 100 | prefix, |
---|
107 | 101 | high_bits); |
---|
108 | 102 | } else if (type == 12) { |
---|
109 | 103 | sprintf(tmp_buf, "%s@%x", |
---|
110 | | - dp->name, high_bits); |
---|
| 104 | + name, high_bits); |
---|
111 | 105 | } |
---|
112 | 106 | } |
---|
113 | 107 | |
---|
114 | 108 | static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf) |
---|
115 | 109 | { |
---|
| 110 | + const char *name = of_get_property(dp, "name", NULL); |
---|
116 | 111 | struct linux_prom64_registers *regs; |
---|
117 | 112 | struct property *prop; |
---|
118 | 113 | |
---|
.. | .. |
---|
123 | 118 | regs = prop->value; |
---|
124 | 119 | if (!of_node_is_root(dp->parent)) { |
---|
125 | 120 | sprintf(tmp_buf, "%s@%x,%x", |
---|
126 | | - dp->name, |
---|
| 121 | + name, |
---|
127 | 122 | (unsigned int) (regs->phys_addr >> 32UL), |
---|
128 | 123 | (unsigned int) (regs->phys_addr & 0xffffffffUL)); |
---|
129 | 124 | return; |
---|
.. | .. |
---|
139 | 134 | mask = 0x7fffff; |
---|
140 | 135 | |
---|
141 | 136 | sprintf(tmp_buf, "%s@%x,%x", |
---|
142 | | - dp->name, |
---|
| 137 | + name, |
---|
143 | 138 | *(u32 *)prop->value, |
---|
144 | 139 | (unsigned int) (regs->phys_addr & mask)); |
---|
145 | 140 | } |
---|
.. | .. |
---|
148 | 143 | /* "name@slot,offset" */ |
---|
149 | 144 | static void __init sbus_path_component(struct device_node *dp, char *tmp_buf) |
---|
150 | 145 | { |
---|
| 146 | + const char *name = of_get_property(dp, "name", NULL); |
---|
151 | 147 | struct linux_prom_registers *regs; |
---|
152 | 148 | struct property *prop; |
---|
153 | 149 | |
---|
.. | .. |
---|
157 | 153 | |
---|
158 | 154 | regs = prop->value; |
---|
159 | 155 | sprintf(tmp_buf, "%s@%x,%x", |
---|
160 | | - dp->name, |
---|
| 156 | + name, |
---|
161 | 157 | regs->which_io, |
---|
162 | 158 | regs->phys_addr); |
---|
163 | 159 | } |
---|
.. | .. |
---|
165 | 161 | /* "name@devnum[,func]" */ |
---|
166 | 162 | static void __init pci_path_component(struct device_node *dp, char *tmp_buf) |
---|
167 | 163 | { |
---|
| 164 | + const char *name = of_get_property(dp, "name", NULL); |
---|
168 | 165 | struct linux_prom_pci_registers *regs; |
---|
169 | 166 | struct property *prop; |
---|
170 | 167 | unsigned int devfn; |
---|
.. | .. |
---|
177 | 174 | devfn = (regs->phys_hi >> 8) & 0xff; |
---|
178 | 175 | if (devfn & 0x07) { |
---|
179 | 176 | sprintf(tmp_buf, "%s@%x,%x", |
---|
180 | | - dp->name, |
---|
| 177 | + name, |
---|
181 | 178 | devfn >> 3, |
---|
182 | 179 | devfn & 0x07); |
---|
183 | 180 | } else { |
---|
184 | 181 | sprintf(tmp_buf, "%s@%x", |
---|
185 | | - dp->name, |
---|
| 182 | + name, |
---|
186 | 183 | devfn >> 3); |
---|
187 | 184 | } |
---|
188 | 185 | } |
---|
.. | .. |
---|
190 | 187 | /* "name@UPA_PORTID,offset" */ |
---|
191 | 188 | static void __init upa_path_component(struct device_node *dp, char *tmp_buf) |
---|
192 | 189 | { |
---|
| 190 | + const char *name = of_get_property(dp, "name", NULL); |
---|
193 | 191 | struct linux_prom64_registers *regs; |
---|
194 | 192 | struct property *prop; |
---|
195 | 193 | |
---|
.. | .. |
---|
204 | 202 | return; |
---|
205 | 203 | |
---|
206 | 204 | sprintf(tmp_buf, "%s@%x,%x", |
---|
207 | | - dp->name, |
---|
| 205 | + name, |
---|
208 | 206 | *(u32 *) prop->value, |
---|
209 | 207 | (unsigned int) (regs->phys_addr & 0xffffffffUL)); |
---|
210 | 208 | } |
---|
.. | .. |
---|
212 | 210 | /* "name@reg" */ |
---|
213 | 211 | static void __init vdev_path_component(struct device_node *dp, char *tmp_buf) |
---|
214 | 212 | { |
---|
| 213 | + const char *name = of_get_property(dp, "name", NULL); |
---|
215 | 214 | struct property *prop; |
---|
216 | 215 | u32 *regs; |
---|
217 | 216 | |
---|
.. | .. |
---|
221 | 220 | |
---|
222 | 221 | regs = prop->value; |
---|
223 | 222 | |
---|
224 | | - sprintf(tmp_buf, "%s@%x", dp->name, *regs); |
---|
| 223 | + sprintf(tmp_buf, "%s@%x", name, *regs); |
---|
225 | 224 | } |
---|
226 | 225 | |
---|
227 | 226 | /* "name@addrhi,addrlo" */ |
---|
228 | 227 | static void __init ebus_path_component(struct device_node *dp, char *tmp_buf) |
---|
229 | 228 | { |
---|
| 229 | + const char *name = of_get_property(dp, "name", NULL); |
---|
230 | 230 | struct linux_prom64_registers *regs; |
---|
231 | 231 | struct property *prop; |
---|
232 | 232 | |
---|
.. | .. |
---|
237 | 237 | regs = prop->value; |
---|
238 | 238 | |
---|
239 | 239 | sprintf(tmp_buf, "%s@%x,%x", |
---|
240 | | - dp->name, |
---|
| 240 | + name, |
---|
241 | 241 | (unsigned int) (regs->phys_addr >> 32UL), |
---|
242 | 242 | (unsigned int) (regs->phys_addr & 0xffffffffUL)); |
---|
243 | 243 | } |
---|
.. | .. |
---|
245 | 245 | /* "name@bus,addr" */ |
---|
246 | 246 | static void __init i2c_path_component(struct device_node *dp, char *tmp_buf) |
---|
247 | 247 | { |
---|
| 248 | + const char *name = of_get_property(dp, "name", NULL); |
---|
248 | 249 | struct property *prop; |
---|
249 | 250 | u32 *regs; |
---|
250 | 251 | |
---|
.. | .. |
---|
258 | 259 | * property of the i2c bus node etc. etc. |
---|
259 | 260 | */ |
---|
260 | 261 | sprintf(tmp_buf, "%s@%x,%x", |
---|
261 | | - dp->name, regs[0], regs[1]); |
---|
| 262 | + name, regs[0], regs[1]); |
---|
262 | 263 | } |
---|
263 | 264 | |
---|
264 | 265 | /* "name@reg0[,reg1]" */ |
---|
265 | 266 | static void __init usb_path_component(struct device_node *dp, char *tmp_buf) |
---|
266 | 267 | { |
---|
| 268 | + const char *name = of_get_property(dp, "name", NULL); |
---|
267 | 269 | struct property *prop; |
---|
268 | 270 | u32 *regs; |
---|
269 | 271 | |
---|
.. | .. |
---|
275 | 277 | |
---|
276 | 278 | if (prop->length == sizeof(u32) || regs[1] == 1) { |
---|
277 | 279 | sprintf(tmp_buf, "%s@%x", |
---|
278 | | - dp->name, regs[0]); |
---|
| 280 | + name, regs[0]); |
---|
279 | 281 | } else { |
---|
280 | 282 | sprintf(tmp_buf, "%s@%x,%x", |
---|
281 | | - dp->name, regs[0], regs[1]); |
---|
| 283 | + name, regs[0], regs[1]); |
---|
282 | 284 | } |
---|
283 | 285 | } |
---|
284 | 286 | |
---|
285 | 287 | /* "name@reg0reg1[,reg2reg3]" */ |
---|
286 | 288 | static void __init ieee1394_path_component(struct device_node *dp, char *tmp_buf) |
---|
287 | 289 | { |
---|
| 290 | + const char *name = of_get_property(dp, "name", NULL); |
---|
288 | 291 | struct property *prop; |
---|
289 | 292 | u32 *regs; |
---|
290 | 293 | |
---|
.. | .. |
---|
296 | 299 | |
---|
297 | 300 | if (regs[2] || regs[3]) { |
---|
298 | 301 | sprintf(tmp_buf, "%s@%08x%08x,%04x%08x", |
---|
299 | | - dp->name, regs[0], regs[1], regs[2], regs[3]); |
---|
| 302 | + name, regs[0], regs[1], regs[2], regs[3]); |
---|
300 | 303 | } else { |
---|
301 | 304 | sprintf(tmp_buf, "%s@%08x%08x", |
---|
302 | | - dp->name, regs[0], regs[1]); |
---|
| 305 | + name, regs[0], regs[1]); |
---|
303 | 306 | } |
---|
304 | 307 | } |
---|
305 | 308 | |
---|
.. | .. |
---|
308 | 311 | struct device_node *parent = dp->parent; |
---|
309 | 312 | |
---|
310 | 313 | if (parent != NULL) { |
---|
311 | | - if (!strcmp(parent->type, "pci") || |
---|
312 | | - !strcmp(parent->type, "pciex")) { |
---|
| 314 | + if (of_node_is_type(parent, "pci") || |
---|
| 315 | + of_node_is_type(parent, "pciex")) { |
---|
313 | 316 | pci_path_component(dp, tmp_buf); |
---|
314 | 317 | return; |
---|
315 | 318 | } |
---|
316 | | - if (!strcmp(parent->type, "sbus")) { |
---|
| 319 | + if (of_node_is_type(parent, "sbus")) { |
---|
317 | 320 | sbus_path_component(dp, tmp_buf); |
---|
318 | 321 | return; |
---|
319 | 322 | } |
---|
320 | | - if (!strcmp(parent->type, "upa")) { |
---|
| 323 | + if (of_node_is_type(parent, "upa")) { |
---|
321 | 324 | upa_path_component(dp, tmp_buf); |
---|
322 | 325 | return; |
---|
323 | 326 | } |
---|
324 | | - if (!strcmp(parent->type, "ebus")) { |
---|
| 327 | + if (of_node_is_type(parent, "ebus")) { |
---|
325 | 328 | ebus_path_component(dp, tmp_buf); |
---|
326 | 329 | return; |
---|
327 | 330 | } |
---|
328 | | - if (!strcmp(parent->name, "usb") || |
---|
329 | | - !strcmp(parent->name, "hub")) { |
---|
| 331 | + if (of_node_name_eq(parent, "usb") || |
---|
| 332 | + of_node_name_eq(parent, "hub")) { |
---|
330 | 333 | usb_path_component(dp, tmp_buf); |
---|
331 | 334 | return; |
---|
332 | 335 | } |
---|
333 | | - if (!strcmp(parent->type, "i2c")) { |
---|
| 336 | + if (of_node_is_type(parent, "i2c")) { |
---|
334 | 337 | i2c_path_component(dp, tmp_buf); |
---|
335 | 338 | return; |
---|
336 | 339 | } |
---|
337 | | - if (!strcmp(parent->type, "firewire")) { |
---|
| 340 | + if (of_node_is_type(parent, "firewire")) { |
---|
338 | 341 | ieee1394_path_component(dp, tmp_buf); |
---|
339 | 342 | return; |
---|
340 | 343 | } |
---|
341 | | - if (!strcmp(parent->type, "virtual-devices")) { |
---|
| 344 | + if (of_node_is_type(parent, "virtual-devices")) { |
---|
342 | 345 | vdev_path_component(dp, tmp_buf); |
---|
343 | 346 | return; |
---|
344 | 347 | } |
---|
.. | .. |
---|
356 | 359 | |
---|
357 | 360 | char * __init build_path_component(struct device_node *dp) |
---|
358 | 361 | { |
---|
| 362 | + const char *name = of_get_property(dp, "name", NULL); |
---|
359 | 363 | char tmp_buf[64], *n; |
---|
360 | 364 | |
---|
361 | 365 | tmp_buf[0] = '\0'; |
---|
362 | 366 | __build_path_component(dp, tmp_buf); |
---|
363 | 367 | if (tmp_buf[0] == '\0') |
---|
364 | | - strcpy(tmp_buf, dp->name); |
---|
| 368 | + strcpy(tmp_buf, name); |
---|
365 | 369 | |
---|
366 | 370 | n = prom_early_alloc(strlen(tmp_buf) + 1); |
---|
367 | 371 | strcpy(n, tmp_buf); |
---|
.. | .. |
---|
594 | 598 | { |
---|
595 | 599 | char *msg = "OF stdout device is: %s\n"; |
---|
596 | 600 | struct device_node *dp; |
---|
597 | | - const char *type; |
---|
598 | 601 | phandle node; |
---|
599 | 602 | |
---|
600 | 603 | of_console_path = prom_early_alloc(256); |
---|
.. | .. |
---|
617 | 620 | } |
---|
618 | 621 | |
---|
619 | 622 | dp = of_find_node_by_phandle(node); |
---|
620 | | - type = of_get_property(dp, "device_type", NULL); |
---|
621 | | - if (!type) { |
---|
622 | | - prom_printf("Console stdout lacks device_type property.\n"); |
---|
623 | | - prom_halt(); |
---|
624 | | - } |
---|
625 | 623 | |
---|
626 | | - if (strcmp(type, "display") && strcmp(type, "serial")) { |
---|
| 624 | + if (!of_node_is_type(dp, "display") && !of_node_is_type(dp, "serial")) { |
---|
627 | 625 | prom_printf("Console device_type is neither display " |
---|
628 | 626 | "nor serial.\n"); |
---|
629 | 627 | prom_halt(); |
---|