| .. | .. |
|---|
| 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(); |
|---|