diff options
| author | David S. Miller <davem@davemloft.net> | 2006-06-29 17:34:50 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-29 19:37:12 -0400 |
| commit | cf44bbc26cf1361b692ab68c884f6a0df7da2fdb (patch) | |
| tree | e16c980a25df8a31445a005d75da2c37f30a7b67 | |
| parent | 3ae9a3489a4e2ba665a344a9250c2af05b7b0c59 (diff) | |
[SPARC]: Beginnings of generic of_device framework.
The idea is to fully construct the device register and
interrupt values into these of_device objects, and convert
all of SBUS, EBUS, ISA drivers to use this new stuff.
Much ideas and code taken from Ben H.'s powerpc work.
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | arch/sparc/kernel/of_device.c | 422 | ||||
| -rw-r--r-- | arch/sparc64/kernel/of_device.c | 490 | ||||
| -rw-r--r-- | include/asm-sparc/of_device.h | 14 | ||||
| -rw-r--r-- | include/asm-sparc/prom.h | 2 | ||||
| -rw-r--r-- | include/asm-sparc64/of_device.h | 14 | ||||
| -rw-r--r-- | include/asm-sparc64/prom.h | 2 |
6 files changed, 936 insertions, 8 deletions
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 80a809478781..13a70bd87817 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c | |||
| @@ -153,10 +153,424 @@ struct bus_type sbus_bus_type = { | |||
| 153 | EXPORT_SYMBOL(sbus_bus_type); | 153 | EXPORT_SYMBOL(sbus_bus_type); |
| 154 | #endif | 154 | #endif |
| 155 | 155 | ||
| 156 | struct bus_type of_bus_type = { | ||
| 157 | .name = "of", | ||
| 158 | .match = of_platform_bus_match, | ||
| 159 | .probe = of_device_probe, | ||
| 160 | .remove = of_device_remove, | ||
| 161 | .suspend = of_device_suspend, | ||
| 162 | .resume = of_device_resume, | ||
| 163 | }; | ||
| 164 | EXPORT_SYMBOL(of_bus_type); | ||
| 165 | |||
| 166 | static inline u64 of_read_addr(u32 *cell, int size) | ||
| 167 | { | ||
| 168 | u64 r = 0; | ||
| 169 | while (size--) | ||
| 170 | r = (r << 32) | *(cell++); | ||
| 171 | return r; | ||
| 172 | } | ||
| 173 | |||
| 174 | static void __init get_cells(struct device_node *dp, | ||
| 175 | int *addrc, int *sizec) | ||
| 176 | { | ||
| 177 | if (addrc) | ||
| 178 | *addrc = of_n_addr_cells(dp); | ||
| 179 | if (sizec) | ||
| 180 | *sizec = of_n_size_cells(dp); | ||
| 181 | } | ||
| 182 | |||
| 183 | /* Max address size we deal with */ | ||
| 184 | #define OF_MAX_ADDR_CELLS 4 | ||
| 185 | |||
| 186 | struct of_bus { | ||
| 187 | const char *name; | ||
| 188 | const char *addr_prop_name; | ||
| 189 | int (*match)(struct device_node *parent); | ||
| 190 | void (*count_cells)(struct device_node *child, | ||
| 191 | int *addrc, int *sizec); | ||
| 192 | u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); | ||
| 193 | int (*translate)(u32 *addr, u64 offset, int na); | ||
| 194 | unsigned int (*get_flags)(u32 *addr); | ||
| 195 | }; | ||
| 196 | |||
| 197 | /* | ||
| 198 | * Default translator (generic bus) | ||
| 199 | */ | ||
| 200 | |||
| 201 | static void of_bus_default_count_cells(struct device_node *dev, | ||
| 202 | int *addrc, int *sizec) | ||
| 203 | { | ||
| 204 | get_cells(dev, addrc, sizec); | ||
| 205 | } | ||
| 206 | |||
| 207 | static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
| 208 | { | ||
| 209 | u64 cp, s, da; | ||
| 210 | |||
| 211 | cp = of_read_addr(range, na); | ||
| 212 | s = of_read_addr(range + na + pna, ns); | ||
| 213 | da = of_read_addr(addr, na); | ||
| 214 | |||
| 215 | if (da < cp || da >= (cp + s)) | ||
| 216 | return OF_BAD_ADDR; | ||
| 217 | return da - cp; | ||
| 218 | } | ||
| 219 | |||
| 220 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | ||
| 221 | { | ||
| 222 | u64 a = of_read_addr(addr, na); | ||
| 223 | memset(addr, 0, na * 4); | ||
| 224 | a += offset; | ||
| 225 | if (na > 1) | ||
| 226 | addr[na - 2] = a >> 32; | ||
| 227 | addr[na - 1] = a & 0xffffffffu; | ||
| 228 | |||
| 229 | return 0; | ||
| 230 | } | ||
| 231 | |||
| 232 | static unsigned int of_bus_default_get_flags(u32 *addr) | ||
| 233 | { | ||
| 234 | return IORESOURCE_MEM; | ||
| 235 | } | ||
| 236 | |||
| 237 | |||
| 238 | /* | ||
| 239 | * PCI bus specific translator | ||
| 240 | */ | ||
| 241 | |||
| 242 | static int of_bus_pci_match(struct device_node *np) | ||
| 243 | { | ||
| 244 | return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex"); | ||
| 245 | } | ||
| 246 | |||
| 247 | static void of_bus_pci_count_cells(struct device_node *np, | ||
| 248 | int *addrc, int *sizec) | ||
| 249 | { | ||
| 250 | if (addrc) | ||
| 251 | *addrc = 3; | ||
| 252 | if (sizec) | ||
| 253 | *sizec = 2; | ||
| 254 | } | ||
| 255 | |||
| 256 | static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
| 257 | { | ||
| 258 | u64 cp, s, da; | ||
| 259 | |||
| 260 | /* Check address type match */ | ||
| 261 | if ((addr[0] ^ range[0]) & 0x03000000) | ||
| 262 | return OF_BAD_ADDR; | ||
| 263 | |||
| 264 | /* Read address values, skipping high cell */ | ||
| 265 | cp = of_read_addr(range + 1, na - 1); | ||
| 266 | s = of_read_addr(range + na + pna, ns); | ||
| 267 | da = of_read_addr(addr + 1, na - 1); | ||
| 268 | |||
| 269 | if (da < cp || da >= (cp + s)) | ||
| 270 | return OF_BAD_ADDR; | ||
| 271 | return da - cp; | ||
| 272 | } | ||
| 273 | |||
| 274 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | ||
| 275 | { | ||
| 276 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
| 277 | } | ||
| 278 | |||
| 279 | static unsigned int of_bus_pci_get_flags(u32 *addr) | ||
| 280 | { | ||
| 281 | unsigned int flags = 0; | ||
| 282 | u32 w = addr[0]; | ||
| 283 | |||
| 284 | switch((w >> 24) & 0x03) { | ||
| 285 | case 0x01: | ||
| 286 | flags |= IORESOURCE_IO; | ||
| 287 | case 0x02: /* 32 bits */ | ||
| 288 | case 0x03: /* 64 bits */ | ||
| 289 | flags |= IORESOURCE_MEM; | ||
| 290 | } | ||
| 291 | if (w & 0x40000000) | ||
| 292 | flags |= IORESOURCE_PREFETCH; | ||
| 293 | return flags; | ||
| 294 | } | ||
| 295 | |||
| 296 | /* | ||
| 297 | * SBUS bus specific translator | ||
| 298 | */ | ||
| 299 | |||
| 300 | static int of_bus_sbus_match(struct device_node *np) | ||
| 301 | { | ||
| 302 | return !strcmp(np->name, "sbus") || | ||
| 303 | !strcmp(np->name, "sbi"); | ||
| 304 | } | ||
| 305 | |||
| 306 | static void of_bus_sbus_count_cells(struct device_node *child, | ||
| 307 | int *addrc, int *sizec) | ||
| 308 | { | ||
| 309 | if (addrc) | ||
| 310 | *addrc = 2; | ||
| 311 | if (sizec) | ||
| 312 | *sizec = 1; | ||
| 313 | } | ||
| 314 | |||
| 315 | static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
| 316 | { | ||
| 317 | return of_bus_default_map(addr, range, na, ns, pna); | ||
| 318 | } | ||
| 319 | |||
| 320 | static int of_bus_sbus_translate(u32 *addr, u64 offset, int na) | ||
| 321 | { | ||
| 322 | return of_bus_default_translate(addr, offset, na); | ||
| 323 | } | ||
| 324 | |||
| 325 | static unsigned int of_bus_sbus_get_flags(u32 *addr) | ||
| 326 | { | ||
| 327 | return IORESOURCE_MEM; | ||
| 328 | } | ||
| 329 | |||
| 330 | |||
| 331 | /* | ||
| 332 | * Array of bus specific translators | ||
| 333 | */ | ||
| 334 | |||
| 335 | static struct of_bus of_busses[] = { | ||
| 336 | /* PCI */ | ||
| 337 | { | ||
| 338 | .name = "pci", | ||
| 339 | .addr_prop_name = "assigned-addresses", | ||
| 340 | .match = of_bus_pci_match, | ||
| 341 | .count_cells = of_bus_pci_count_cells, | ||
| 342 | .map = of_bus_pci_map, | ||
| 343 | .translate = of_bus_pci_translate, | ||
| 344 | .get_flags = of_bus_pci_get_flags, | ||
| 345 | }, | ||
| 346 | /* SBUS */ | ||
| 347 | { | ||
| 348 | .name = "sbus", | ||
| 349 | .addr_prop_name = "reg", | ||
| 350 | .match = of_bus_sbus_match, | ||
| 351 | .count_cells = of_bus_sbus_count_cells, | ||
| 352 | .map = of_bus_sbus_map, | ||
| 353 | .translate = of_bus_sbus_translate, | ||
| 354 | .get_flags = of_bus_sbus_get_flags, | ||
| 355 | }, | ||
| 356 | /* Default */ | ||
| 357 | { | ||
| 358 | .name = "default", | ||
| 359 | .addr_prop_name = "reg", | ||
| 360 | .match = NULL, | ||
| 361 | .count_cells = of_bus_default_count_cells, | ||
| 362 | .map = of_bus_default_map, | ||
| 363 | .translate = of_bus_default_translate, | ||
| 364 | .get_flags = of_bus_default_get_flags, | ||
| 365 | }, | ||
| 366 | }; | ||
| 367 | |||
| 368 | static struct of_bus *of_match_bus(struct device_node *np) | ||
| 369 | { | ||
| 370 | int i; | ||
| 371 | |||
| 372 | for (i = 0; i < ARRAY_SIZE(of_busses); i ++) | ||
| 373 | if (!of_busses[i].match || of_busses[i].match(np)) | ||
| 374 | return &of_busses[i]; | ||
| 375 | BUG(); | ||
| 376 | return NULL; | ||
| 377 | } | ||
| 378 | |||
| 379 | static int __init build_one_resource(struct device_node *parent, | ||
| 380 | struct of_bus *bus, | ||
| 381 | struct of_bus *pbus, | ||
| 382 | u32 *addr, | ||
| 383 | int na, int ns, int pna) | ||
| 384 | { | ||
| 385 | u32 *ranges; | ||
| 386 | unsigned int rlen; | ||
| 387 | int rone; | ||
| 388 | u64 offset = OF_BAD_ADDR; | ||
| 389 | |||
| 390 | ranges = of_get_property(parent, "ranges", &rlen); | ||
| 391 | if (ranges == NULL || rlen == 0) { | ||
| 392 | offset = of_read_addr(addr, na); | ||
| 393 | memset(addr, 0, pna * 4); | ||
| 394 | goto finish; | ||
| 395 | } | ||
| 396 | |||
| 397 | /* Now walk through the ranges */ | ||
| 398 | rlen /= 4; | ||
| 399 | rone = na + pna + ns; | ||
| 400 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | ||
| 401 | offset = bus->map(addr, ranges, na, ns, pna); | ||
| 402 | if (offset != OF_BAD_ADDR) | ||
| 403 | break; | ||
| 404 | } | ||
| 405 | if (offset == OF_BAD_ADDR) | ||
| 406 | return 1; | ||
| 407 | |||
| 408 | memcpy(addr, ranges + na, 4 * pna); | ||
| 409 | |||
| 410 | finish: | ||
| 411 | /* Translate it into parent bus space */ | ||
| 412 | return pbus->translate(addr, offset, pna); | ||
| 413 | } | ||
| 414 | |||
| 415 | static void __init build_device_resources(struct of_device *op, | ||
| 416 | struct device *parent) | ||
| 417 | { | ||
| 418 | struct of_device *p_op; | ||
| 419 | struct of_bus *bus; | ||
| 420 | int na, ns; | ||
| 421 | int index, num_reg; | ||
| 422 | void *preg; | ||
| 423 | |||
| 424 | if (!parent) | ||
| 425 | return; | ||
| 426 | |||
| 427 | p_op = to_of_device(parent); | ||
| 428 | bus = of_match_bus(p_op->node); | ||
| 429 | bus->count_cells(op->node, &na, &ns); | ||
| 430 | |||
| 431 | preg = of_get_property(op->node, bus->addr_prop_name, &num_reg); | ||
| 432 | if (!preg || num_reg == 0) | ||
| 433 | return; | ||
| 434 | |||
| 435 | /* Convert to num-cells. */ | ||
| 436 | num_reg /= 4; | ||
| 437 | |||
| 438 | /* Conver to num-entries. */ | ||
| 439 | num_reg /= na + ns; | ||
| 440 | |||
| 441 | for (index = 0; index < num_reg; index++) { | ||
| 442 | struct resource *r = &op->resource[index]; | ||
| 443 | u32 addr[OF_MAX_ADDR_CELLS]; | ||
| 444 | u32 *reg = (preg + (index * ((na + ns) * 4))); | ||
| 445 | struct device_node *dp = op->node; | ||
| 446 | struct device_node *pp = p_op->node; | ||
| 447 | struct of_bus *pbus; | ||
| 448 | u64 size, result = OF_BAD_ADDR; | ||
| 449 | unsigned long flags; | ||
| 450 | int dna, dns; | ||
| 451 | int pna, pns; | ||
| 452 | |||
| 453 | size = of_read_addr(reg + na, ns); | ||
| 454 | flags = bus->get_flags(reg); | ||
| 455 | |||
| 456 | memcpy(addr, reg, na * 4); | ||
| 457 | |||
| 458 | /* If the immediate parent has no ranges property to apply, | ||
| 459 | * just use a 1<->1 mapping. | ||
| 460 | */ | ||
| 461 | if (of_find_property(pp, "ranges", NULL) == NULL) { | ||
| 462 | result = of_read_addr(addr, na); | ||
| 463 | goto build_res; | ||
| 464 | } | ||
| 465 | |||
| 466 | dna = na; | ||
| 467 | dns = ns; | ||
| 468 | |||
| 469 | while (1) { | ||
| 470 | dp = pp; | ||
| 471 | pp = dp->parent; | ||
| 472 | if (!pp) { | ||
| 473 | result = of_read_addr(addr, dna); | ||
| 474 | break; | ||
| 475 | } | ||
| 476 | |||
| 477 | pbus = of_match_bus(pp); | ||
| 478 | pbus->count_cells(dp, &pna, &pns); | ||
| 479 | |||
| 480 | if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna)) | ||
| 481 | break; | ||
| 482 | |||
| 483 | dna = pna; | ||
| 484 | dns = pns; | ||
| 485 | bus = pbus; | ||
| 486 | } | ||
| 487 | |||
| 488 | build_res: | ||
| 489 | memset(r, 0, sizeof(*r)); | ||
| 490 | if (result != OF_BAD_ADDR) { | ||
| 491 | r->start = result; | ||
| 492 | r->end = result + size - 1; | ||
| 493 | r->flags = flags; | ||
| 494 | } else { | ||
| 495 | r->start = ~0UL; | ||
| 496 | r->end = ~0UL; | ||
| 497 | } | ||
| 498 | r->name = op->node->name; | ||
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 502 | static struct of_device * __init scan_one_device(struct device_node *dp, | ||
| 503 | struct device *parent) | ||
| 504 | { | ||
| 505 | struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); | ||
| 506 | unsigned int *irq; | ||
| 507 | int len; | ||
| 508 | |||
| 509 | if (!op) | ||
| 510 | return NULL; | ||
| 511 | |||
| 512 | op->node = dp; | ||
| 513 | |||
| 514 | op->clock_freq = of_getintprop_default(dp, "clock-frequency", | ||
| 515 | (25*1000*1000)); | ||
| 516 | op->portid = of_getintprop_default(dp, "upa-portid", -1); | ||
| 517 | if (op->portid == -1) | ||
| 518 | op->portid = of_getintprop_default(dp, "portid", -1); | ||
| 519 | |||
| 520 | irq = of_get_property(dp, "interrupts", &len); | ||
| 521 | if (irq) | ||
| 522 | op->irq = *irq; | ||
| 523 | else | ||
| 524 | op->irq = 0xffffffff; | ||
| 525 | |||
| 526 | build_device_resources(op, parent); | ||
| 527 | |||
| 528 | op->dev.parent = parent; | ||
| 529 | op->dev.bus = &of_bus_type; | ||
| 530 | if (!parent) | ||
| 531 | strcpy(op->dev.bus_id, "root"); | ||
| 532 | else | ||
| 533 | strcpy(op->dev.bus_id, dp->path_component_name); | ||
| 534 | |||
| 535 | if (of_device_register(op)) { | ||
| 536 | printk("%s: Could not register of device.\n", | ||
| 537 | dp->full_name); | ||
| 538 | kfree(op); | ||
| 539 | op = NULL; | ||
| 540 | } | ||
| 541 | |||
| 542 | return op; | ||
| 543 | } | ||
| 544 | |||
| 545 | static void __init scan_tree(struct device_node *dp, struct device *parent) | ||
| 546 | { | ||
| 547 | while (dp) { | ||
| 548 | struct of_device *op = scan_one_device(dp, parent); | ||
| 549 | |||
| 550 | if (op) | ||
| 551 | scan_tree(dp->child, &op->dev); | ||
| 552 | |||
| 553 | dp = dp->sibling; | ||
| 554 | } | ||
| 555 | } | ||
| 556 | |||
| 557 | static void __init scan_of_devices(void) | ||
| 558 | { | ||
| 559 | struct device_node *root = of_find_node_by_path("/"); | ||
| 560 | struct of_device *parent; | ||
| 561 | |||
| 562 | parent = scan_one_device(root, NULL); | ||
| 563 | if (!parent) | ||
| 564 | return; | ||
| 565 | |||
| 566 | scan_tree(root->child, &parent->dev); | ||
| 567 | } | ||
| 568 | |||
| 156 | static int __init of_bus_driver_init(void) | 569 | static int __init of_bus_driver_init(void) |
| 157 | { | 570 | { |
| 158 | int err = 0; | 571 | int err; |
| 159 | 572 | ||
| 573 | err = bus_register(&of_bus_type); | ||
| 160 | #ifdef CONFIG_PCI | 574 | #ifdef CONFIG_PCI |
| 161 | if (!err) | 575 | if (!err) |
| 162 | err = bus_register(&ebus_bus_type); | 576 | err = bus_register(&ebus_bus_type); |
| @@ -165,7 +579,11 @@ static int __init of_bus_driver_init(void) | |||
| 165 | if (!err) | 579 | if (!err) |
| 166 | err = bus_register(&sbus_bus_type); | 580 | err = bus_register(&sbus_bus_type); |
| 167 | #endif | 581 | #endif |
| 168 | return 0; | 582 | |
| 583 | if (!err) | ||
| 584 | scan_of_devices(); | ||
| 585 | |||
| 586 | return err; | ||
| 169 | } | 587 | } |
| 170 | 588 | ||
| 171 | postcore_initcall(of_bus_driver_init); | 589 | postcore_initcall(of_bus_driver_init); |
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 768475bbce82..00502dc280ef 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
| @@ -163,10 +163,492 @@ struct bus_type sbus_bus_type = { | |||
| 163 | EXPORT_SYMBOL(sbus_bus_type); | 163 | EXPORT_SYMBOL(sbus_bus_type); |
| 164 | #endif | 164 | #endif |
| 165 | 165 | ||
| 166 | struct bus_type of_bus_type = { | ||
| 167 | .name = "of", | ||
| 168 | .match = of_platform_bus_match, | ||
| 169 | .probe = of_device_probe, | ||
| 170 | .remove = of_device_remove, | ||
| 171 | .suspend = of_device_suspend, | ||
| 172 | .resume = of_device_resume, | ||
| 173 | }; | ||
| 174 | EXPORT_SYMBOL(of_bus_type); | ||
| 175 | |||
| 176 | static inline u64 of_read_addr(u32 *cell, int size) | ||
| 177 | { | ||
| 178 | u64 r = 0; | ||
| 179 | while (size--) | ||
| 180 | r = (r << 32) | *(cell++); | ||
| 181 | return r; | ||
| 182 | } | ||
| 183 | |||
| 184 | static void __init get_cells(struct device_node *dp, | ||
| 185 | int *addrc, int *sizec) | ||
| 186 | { | ||
| 187 | if (addrc) | ||
| 188 | *addrc = of_n_addr_cells(dp); | ||
| 189 | if (sizec) | ||
| 190 | *sizec = of_n_size_cells(dp); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* Max address size we deal with */ | ||
| 194 | #define OF_MAX_ADDR_CELLS 4 | ||
| 195 | |||
| 196 | struct of_bus { | ||
| 197 | const char *name; | ||
| 198 | const char *addr_prop_name; | ||
| 199 | int (*match)(struct device_node *parent); | ||
| 200 | void (*count_cells)(struct device_node *child, | ||
| 201 | int *addrc, int *sizec); | ||
| 202 | u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); | ||
| 203 | int (*translate)(u32 *addr, u64 offset, int na); | ||
| 204 | unsigned int (*get_flags)(u32 *addr); | ||
| 205 | }; | ||
| 206 | |||
| 207 | /* | ||
| 208 | * Default translator (generic bus) | ||
| 209 | */ | ||
| 210 | |||
| 211 | static void of_bus_default_count_cells(struct device_node *dev, | ||
| 212 | int *addrc, int *sizec) | ||
| 213 | { | ||
| 214 | get_cells(dev, addrc, sizec); | ||
| 215 | } | ||
| 216 | |||
| 217 | static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
| 218 | { | ||
| 219 | u64 cp, s, da; | ||
| 220 | |||
| 221 | cp = of_read_addr(range, na); | ||
| 222 | s = of_read_addr(range + na + pna, ns); | ||
| 223 | da = of_read_addr(addr, na); | ||
| 224 | |||
| 225 | if (da < cp || da >= (cp + s)) | ||
| 226 | return OF_BAD_ADDR; | ||
| 227 | return da - cp; | ||
| 228 | } | ||
| 229 | |||
| 230 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | ||
| 231 | { | ||
| 232 | u64 a = of_read_addr(addr, na); | ||
| 233 | memset(addr, 0, na * 4); | ||
| 234 | a += offset; | ||
| 235 | if (na > 1) | ||
| 236 | addr[na - 2] = a >> 32; | ||
| 237 | addr[na - 1] = a & 0xffffffffu; | ||
| 238 | |||
| 239 | return 0; | ||
| 240 | } | ||
| 241 | |||
| 242 | static unsigned int of_bus_default_get_flags(u32 *addr) | ||
| 243 | { | ||
| 244 | return IORESOURCE_MEM; | ||
| 245 | } | ||
| 246 | |||
| 247 | |||
| 248 | /* | ||
| 249 | * PCI bus specific translator | ||
| 250 | */ | ||
| 251 | |||
| 252 | static int of_bus_pci_match(struct device_node *np) | ||
| 253 | { | ||
| 254 | return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex"); | ||
| 255 | } | ||
| 256 | |||
| 257 | static void of_bus_pci_count_cells(struct device_node *np, | ||
| 258 | int *addrc, int *sizec) | ||
| 259 | { | ||
| 260 | if (addrc) | ||
| 261 | *addrc = 3; | ||
| 262 | if (sizec) | ||
| 263 | *sizec = 2; | ||
| 264 | } | ||
| 265 | |||
| 266 | static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
| 267 | { | ||
| 268 | u64 cp, s, da; | ||
| 269 | |||
| 270 | /* Check address type match */ | ||
| 271 | if ((addr[0] ^ range[0]) & 0x03000000) | ||
| 272 | return OF_BAD_ADDR; | ||
| 273 | |||
| 274 | /* Read address values, skipping high cell */ | ||
| 275 | cp = of_read_addr(range + 1, na - 1); | ||
| 276 | s = of_read_addr(range + na + pna, ns); | ||
| 277 | da = of_read_addr(addr + 1, na - 1); | ||
| 278 | |||
| 279 | if (da < cp || da >= (cp + s)) | ||
| 280 | return OF_BAD_ADDR; | ||
| 281 | return da - cp; | ||
| 282 | } | ||
| 283 | |||
| 284 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | ||
| 285 | { | ||
| 286 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
| 287 | } | ||
| 288 | |||
| 289 | static unsigned int of_bus_pci_get_flags(u32 *addr) | ||
| 290 | { | ||
| 291 | unsigned int flags = 0; | ||
| 292 | u32 w = addr[0]; | ||
| 293 | |||
| 294 | switch((w >> 24) & 0x03) { | ||
| 295 | case 0x01: | ||
| 296 | flags |= IORESOURCE_IO; | ||
| 297 | case 0x02: /* 32 bits */ | ||
| 298 | case 0x03: /* 64 bits */ | ||
| 299 | flags |= IORESOURCE_MEM; | ||
| 300 | } | ||
| 301 | if (w & 0x40000000) | ||
| 302 | flags |= IORESOURCE_PREFETCH; | ||
| 303 | return flags; | ||
| 304 | } | ||
| 305 | |||
| 306 | /* | ||
| 307 | * ISA bus specific translator | ||
| 308 | */ | ||
| 309 | |||
| 310 | static int of_bus_isa_match(struct device_node *np) | ||
| 311 | { | ||
| 312 | return !strcmp(np->name, "isa"); | ||
| 313 | } | ||
| 314 | |||
| 315 | static void of_bus_isa_count_cells(struct device_node *child, | ||
| 316 | int *addrc, int *sizec) | ||
| 317 | { | ||
| 318 | if (addrc) | ||
| 319 | *addrc = 2; | ||
| 320 | if (sizec) | ||
| 321 | *sizec = 1; | ||
| 322 | } | ||
| 323 | |||
| 324 | static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
| 325 | { | ||
| 326 | u64 cp, s, da; | ||
| 327 | |||
| 328 | /* Check address type match */ | ||
| 329 | if ((addr[0] ^ range[0]) & 0x00000001) | ||
| 330 | return OF_BAD_ADDR; | ||
| 331 | |||
| 332 | /* Read address values, skipping high cell */ | ||
| 333 | cp = of_read_addr(range + 1, na - 1); | ||
| 334 | s = of_read_addr(range + na + pna, ns); | ||
| 335 | da = of_read_addr(addr + 1, na - 1); | ||
| 336 | |||
| 337 | if (da < cp || da >= (cp + s)) | ||
| 338 | return OF_BAD_ADDR; | ||
| 339 | return da - cp; | ||
| 340 | } | ||
| 341 | |||
| 342 | static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | ||
| 343 | { | ||
| 344 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
| 345 | } | ||
| 346 | |||
| 347 | static unsigned int of_bus_isa_get_flags(u32 *addr) | ||
| 348 | { | ||
| 349 | unsigned int flags = 0; | ||
| 350 | u32 w = addr[0]; | ||
| 351 | |||
| 352 | if (w & 1) | ||
| 353 | flags |= IORESOURCE_IO; | ||
| 354 | else | ||
| 355 | flags |= IORESOURCE_MEM; | ||
| 356 | return flags; | ||
| 357 | } | ||
| 358 | |||
| 359 | /* | ||
| 360 | * SBUS bus specific translator | ||
| 361 | */ | ||
| 362 | |||
| 363 | static int of_bus_sbus_match(struct device_node *np) | ||
| 364 | { | ||
| 365 | return !strcmp(np->name, "sbus") || | ||
| 366 | !strcmp(np->name, "sbi"); | ||
| 367 | } | ||
| 368 | |||
| 369 | static void of_bus_sbus_count_cells(struct device_node *child, | ||
| 370 | int *addrc, int *sizec) | ||
| 371 | { | ||
| 372 | if (addrc) | ||
| 373 | *addrc = 2; | ||
| 374 | if (sizec) | ||
| 375 | *sizec = 1; | ||
| 376 | } | ||
| 377 | |||
| 378 | static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
| 379 | { | ||
| 380 | return of_bus_default_map(addr, range, na, ns, pna); | ||
| 381 | } | ||
| 382 | |||
| 383 | static int of_bus_sbus_translate(u32 *addr, u64 offset, int na) | ||
| 384 | { | ||
| 385 | return of_bus_default_translate(addr, offset, na); | ||
| 386 | } | ||
| 387 | |||
| 388 | static unsigned int of_bus_sbus_get_flags(u32 *addr) | ||
| 389 | { | ||
| 390 | return IORESOURCE_MEM; | ||
| 391 | } | ||
| 392 | |||
| 393 | |||
| 394 | /* | ||
| 395 | * Array of bus specific translators | ||
| 396 | */ | ||
| 397 | |||
| 398 | static struct of_bus of_busses[] = { | ||
| 399 | /* PCI */ | ||
| 400 | { | ||
| 401 | .name = "pci", | ||
| 402 | .addr_prop_name = "assigned-addresses", | ||
| 403 | .match = of_bus_pci_match, | ||
| 404 | .count_cells = of_bus_pci_count_cells, | ||
| 405 | .map = of_bus_pci_map, | ||
| 406 | .translate = of_bus_pci_translate, | ||
| 407 | .get_flags = of_bus_pci_get_flags, | ||
| 408 | }, | ||
| 409 | /* ISA */ | ||
| 410 | { | ||
| 411 | .name = "isa", | ||
| 412 | .addr_prop_name = "reg", | ||
| 413 | .match = of_bus_isa_match, | ||
| 414 | .count_cells = of_bus_isa_count_cells, | ||
| 415 | .map = of_bus_isa_map, | ||
| 416 | .translate = of_bus_isa_translate, | ||
| 417 | .get_flags = of_bus_isa_get_flags, | ||
| 418 | }, | ||
| 419 | /* SBUS */ | ||
| 420 | { | ||
| 421 | .name = "sbus", | ||
| 422 | .addr_prop_name = "reg", | ||
| 423 | .match = of_bus_sbus_match, | ||
| 424 | .count_cells = of_bus_sbus_count_cells, | ||
| 425 | .map = of_bus_sbus_map, | ||
| 426 | .translate = of_bus_sbus_translate, | ||
| 427 | .get_flags = of_bus_sbus_get_flags, | ||
| 428 | }, | ||
| 429 | /* Default */ | ||
| 430 | { | ||
| 431 | .name = "default", | ||
| 432 | .addr_prop_name = "reg", | ||
| 433 | .match = NULL, | ||
| 434 | .count_cells = of_bus_default_count_cells, | ||
| 435 | .map = of_bus_default_map, | ||
| 436 | .translate = of_bus_default_translate, | ||
| 437 | .get_flags = of_bus_default_get_flags, | ||
| 438 | }, | ||
| 439 | }; | ||
| 440 | |||
| 441 | static struct of_bus *of_match_bus(struct device_node *np) | ||
| 442 | { | ||
| 443 | int i; | ||
| 444 | |||
| 445 | for (i = 0; i < ARRAY_SIZE(of_busses); i ++) | ||
| 446 | if (!of_busses[i].match || of_busses[i].match(np)) | ||
| 447 | return &of_busses[i]; | ||
| 448 | BUG(); | ||
| 449 | return NULL; | ||
| 450 | } | ||
| 451 | |||
| 452 | static int __init build_one_resource(struct device_node *parent, | ||
| 453 | struct of_bus *bus, | ||
| 454 | struct of_bus *pbus, | ||
| 455 | u32 *addr, | ||
| 456 | int na, int ns, int pna) | ||
| 457 | { | ||
| 458 | u32 *ranges; | ||
| 459 | unsigned int rlen; | ||
| 460 | int rone; | ||
| 461 | u64 offset = OF_BAD_ADDR; | ||
| 462 | |||
| 463 | ranges = of_get_property(parent, "ranges", &rlen); | ||
| 464 | if (ranges == NULL || rlen == 0) { | ||
| 465 | offset = of_read_addr(addr, na); | ||
| 466 | memset(addr, 0, pna * 4); | ||
| 467 | goto finish; | ||
| 468 | } | ||
| 469 | |||
| 470 | /* Now walk through the ranges */ | ||
| 471 | rlen /= 4; | ||
| 472 | rone = na + pna + ns; | ||
| 473 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | ||
| 474 | offset = bus->map(addr, ranges, na, ns, pna); | ||
| 475 | if (offset != OF_BAD_ADDR) | ||
| 476 | break; | ||
| 477 | } | ||
| 478 | if (offset == OF_BAD_ADDR) | ||
| 479 | return 1; | ||
| 480 | |||
| 481 | memcpy(addr, ranges + na, 4 * pna); | ||
| 482 | |||
| 483 | finish: | ||
| 484 | /* Translate it into parent bus space */ | ||
| 485 | return pbus->translate(addr, offset, pna); | ||
| 486 | } | ||
| 487 | |||
| 488 | static void __init build_device_resources(struct of_device *op, | ||
| 489 | struct device *parent) | ||
| 490 | { | ||
| 491 | struct of_device *p_op; | ||
| 492 | struct of_bus *bus; | ||
| 493 | int na, ns; | ||
| 494 | int index, num_reg; | ||
| 495 | void *preg; | ||
| 496 | |||
| 497 | if (!parent) | ||
| 498 | return; | ||
| 499 | |||
| 500 | p_op = to_of_device(parent); | ||
| 501 | bus = of_match_bus(p_op->node); | ||
| 502 | bus->count_cells(op->node, &na, &ns); | ||
| 503 | |||
| 504 | preg = of_get_property(op->node, bus->addr_prop_name, &num_reg); | ||
| 505 | if (!preg || num_reg == 0) | ||
| 506 | return; | ||
| 507 | |||
| 508 | /* Convert to num-cells. */ | ||
| 509 | num_reg /= 4; | ||
| 510 | |||
| 511 | /* Conver to num-entries. */ | ||
| 512 | num_reg /= na + ns; | ||
| 513 | |||
| 514 | for (index = 0; index < num_reg; index++) { | ||
| 515 | struct resource *r = &op->resource[index]; | ||
| 516 | u32 addr[OF_MAX_ADDR_CELLS]; | ||
| 517 | u32 *reg = (preg + (index * ((na + ns) * 4))); | ||
| 518 | struct device_node *dp = op->node; | ||
| 519 | struct device_node *pp = p_op->node; | ||
| 520 | struct of_bus *pbus; | ||
| 521 | u64 size, result = OF_BAD_ADDR; | ||
| 522 | unsigned long flags; | ||
| 523 | int dna, dns; | ||
| 524 | int pna, pns; | ||
| 525 | |||
| 526 | size = of_read_addr(reg + na, ns); | ||
| 527 | flags = bus->get_flags(reg); | ||
| 528 | |||
| 529 | memcpy(addr, reg, na * 4); | ||
| 530 | |||
| 531 | /* If the immediate parent has no ranges property to apply, | ||
| 532 | * just use a 1<->1 mapping. Unless it is the 'dma' child | ||
| 533 | * of an isa bus, which must be passed up towards the root. | ||
| 534 | * | ||
| 535 | * Also, don't try to translate PMU bus device registers. | ||
| 536 | */ | ||
| 537 | if ((of_find_property(pp, "ranges", NULL) == NULL && | ||
| 538 | strcmp(pp->name, "dma") != 0) || | ||
| 539 | !strcmp(pp->name, "pmu")) { | ||
| 540 | result = of_read_addr(addr, na); | ||
| 541 | goto build_res; | ||
| 542 | } | ||
| 543 | |||
| 544 | dna = na; | ||
| 545 | dns = ns; | ||
| 546 | |||
| 547 | while (1) { | ||
| 548 | dp = pp; | ||
| 549 | pp = dp->parent; | ||
| 550 | if (!pp) { | ||
| 551 | result = of_read_addr(addr, dna); | ||
| 552 | break; | ||
| 553 | } | ||
| 554 | |||
| 555 | pbus = of_match_bus(pp); | ||
| 556 | pbus->count_cells(dp, &pna, &pns); | ||
| 557 | |||
| 558 | if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna)) | ||
| 559 | break; | ||
| 560 | |||
| 561 | dna = pna; | ||
| 562 | dns = pns; | ||
| 563 | bus = pbus; | ||
| 564 | } | ||
| 565 | |||
| 566 | build_res: | ||
| 567 | memset(r, 0, sizeof(*r)); | ||
| 568 | if (result != OF_BAD_ADDR) { | ||
| 569 | r->start = result; | ||
| 570 | r->end = result + size - 1; | ||
| 571 | r->flags = flags; | ||
| 572 | } else { | ||
| 573 | r->start = ~0UL; | ||
| 574 | r->end = ~0UL; | ||
| 575 | } | ||
| 576 | r->name = op->node->name; | ||
| 577 | } | ||
| 578 | } | ||
| 579 | |||
| 580 | static struct of_device * __init scan_one_device(struct device_node *dp, | ||
| 581 | struct device *parent) | ||
| 582 | { | ||
| 583 | struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); | ||
| 584 | unsigned int *irq; | ||
| 585 | int len; | ||
| 586 | |||
| 587 | if (!op) | ||
| 588 | return NULL; | ||
| 589 | |||
| 590 | op->node = dp; | ||
| 591 | |||
| 592 | op->clock_freq = of_getintprop_default(dp, "clock-frequency", | ||
| 593 | (25*1000*1000)); | ||
| 594 | op->portid = of_getintprop_default(dp, "upa-portid", -1); | ||
| 595 | if (op->portid == -1) | ||
| 596 | op->portid = of_getintprop_default(dp, "portid", -1); | ||
| 597 | |||
| 598 | irq = of_get_property(dp, "interrupts", &len); | ||
| 599 | if (irq) | ||
| 600 | op->irq = *irq; | ||
| 601 | else | ||
| 602 | op->irq = 0xffffffff; | ||
| 603 | |||
| 604 | build_device_resources(op, parent); | ||
| 605 | |||
| 606 | op->dev.parent = parent; | ||
| 607 | op->dev.bus = &of_bus_type; | ||
| 608 | if (!parent) | ||
| 609 | strcpy(op->dev.bus_id, "root"); | ||
| 610 | else | ||
| 611 | strcpy(op->dev.bus_id, dp->path_component_name); | ||
| 612 | |||
| 613 | if (of_device_register(op)) { | ||
| 614 | printk("%s: Could not register of device.\n", | ||
| 615 | dp->full_name); | ||
| 616 | kfree(op); | ||
| 617 | op = NULL; | ||
| 618 | } | ||
| 619 | |||
| 620 | return op; | ||
| 621 | } | ||
| 622 | |||
| 623 | static void __init scan_tree(struct device_node *dp, struct device *parent) | ||
| 624 | { | ||
| 625 | while (dp) { | ||
| 626 | struct of_device *op = scan_one_device(dp, parent); | ||
| 627 | |||
| 628 | if (op) | ||
| 629 | scan_tree(dp->child, &op->dev); | ||
| 630 | |||
| 631 | dp = dp->sibling; | ||
| 632 | } | ||
| 633 | } | ||
| 634 | |||
| 635 | static void __init scan_of_devices(void) | ||
| 636 | { | ||
| 637 | struct device_node *root = of_find_node_by_path("/"); | ||
| 638 | struct of_device *parent; | ||
| 639 | |||
| 640 | parent = scan_one_device(root, NULL); | ||
| 641 | if (!parent) | ||
| 642 | return; | ||
| 643 | |||
| 644 | scan_tree(root->child, &parent->dev); | ||
| 645 | } | ||
| 646 | |||
| 166 | static int __init of_bus_driver_init(void) | 647 | static int __init of_bus_driver_init(void) |
| 167 | { | 648 | { |
| 168 | int err = 0; | 649 | int err; |
| 169 | 650 | ||
| 651 | err = bus_register(&of_bus_type); | ||
| 170 | #ifdef CONFIG_PCI | 652 | #ifdef CONFIG_PCI |
| 171 | if (!err) | 653 | if (!err) |
| 172 | err = bus_register(&isa_bus_type); | 654 | err = bus_register(&isa_bus_type); |
| @@ -177,7 +659,11 @@ static int __init of_bus_driver_init(void) | |||
| 177 | if (!err) | 659 | if (!err) |
| 178 | err = bus_register(&sbus_bus_type); | 660 | err = bus_register(&sbus_bus_type); |
| 179 | #endif | 661 | #endif |
| 180 | return 0; | 662 | |
| 663 | if (!err) | ||
| 664 | scan_of_devices(); | ||
| 665 | |||
| 666 | return err; | ||
| 181 | } | 667 | } |
| 182 | 668 | ||
| 183 | postcore_initcall(of_bus_driver_init); | 669 | postcore_initcall(of_bus_driver_init); |
diff --git a/include/asm-sparc/of_device.h b/include/asm-sparc/of_device.h index 4816d102f918..1b43ee5eb5e7 100644 --- a/include/asm-sparc/of_device.h +++ b/include/asm-sparc/of_device.h | |||
| @@ -4,10 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #include <linux/device.h> | 5 | #include <linux/device.h> |
| 6 | #include <linux/mod_devicetable.h> | 6 | #include <linux/mod_devicetable.h> |
| 7 | #include <asm/openprom.h> | ||
| 7 | #include <asm/prom.h> | 8 | #include <asm/prom.h> |
| 8 | 9 | ||
| 9 | extern struct bus_type ebus_bus_type; | 10 | extern struct bus_type ebus_bus_type; |
| 10 | extern struct bus_type sbus_bus_type; | 11 | extern struct bus_type sbus_bus_type; |
| 12 | extern struct bus_type of_bus_type; | ||
| 11 | 13 | ||
| 12 | /* | 14 | /* |
| 13 | * The of_device is a kind of "base class" that is a superset of | 15 | * The of_device is a kind of "base class" that is a superset of |
| @@ -16,8 +18,16 @@ extern struct bus_type sbus_bus_type; | |||
| 16 | */ | 18 | */ |
| 17 | struct of_device | 19 | struct of_device |
| 18 | { | 20 | { |
| 19 | struct device_node *node; /* OF device node */ | 21 | struct device_node *node; |
| 20 | struct device dev; /* Generic device interface */ | 22 | struct device dev; |
| 23 | struct resource resource[PROMREG_MAX]; | ||
| 24 | unsigned int irq; | ||
| 25 | |||
| 26 | void *sysdata; | ||
| 27 | |||
| 28 | int slot; | ||
| 29 | int portid; | ||
| 30 | int clock_freq; | ||
| 21 | }; | 31 | }; |
| 22 | #define to_of_device(d) container_of(d, struct of_device, dev) | 32 | #define to_of_device(d) container_of(d, struct of_device, dev) |
| 23 | 33 | ||
diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h index 7032d02d3197..b4a061c5241d 100644 --- a/include/asm-sparc/prom.h +++ b/include/asm-sparc/prom.h | |||
| @@ -69,6 +69,8 @@ struct device_node { | |||
| 69 | #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) | 69 | #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) |
| 70 | #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) | 70 | #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) |
| 71 | 71 | ||
| 72 | #define OF_BAD_ADDR ((u64)-1) | ||
| 73 | |||
| 72 | static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) | 74 | static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) |
| 73 | { | 75 | { |
| 74 | dn->pde = de; | 76 | dn->pde = de; |
diff --git a/include/asm-sparc64/of_device.h b/include/asm-sparc64/of_device.h index 024088ef9d27..27bc08671d68 100644 --- a/include/asm-sparc64/of_device.h +++ b/include/asm-sparc64/of_device.h | |||
| @@ -4,11 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | #include <linux/device.h> | 5 | #include <linux/device.h> |
| 6 | #include <linux/mod_devicetable.h> | 6 | #include <linux/mod_devicetable.h> |
| 7 | #include <asm/openprom.h> | ||
| 7 | #include <asm/prom.h> | 8 | #include <asm/prom.h> |
| 8 | 9 | ||
| 9 | extern struct bus_type isa_bus_type; | 10 | extern struct bus_type isa_bus_type; |
| 10 | extern struct bus_type ebus_bus_type; | 11 | extern struct bus_type ebus_bus_type; |
| 11 | extern struct bus_type sbus_bus_type; | 12 | extern struct bus_type sbus_bus_type; |
| 13 | extern struct bus_type of_bus_type; | ||
| 12 | 14 | ||
| 13 | /* | 15 | /* |
| 14 | * The of_device is a kind of "base class" that is a superset of | 16 | * The of_device is a kind of "base class" that is a superset of |
| @@ -17,8 +19,16 @@ extern struct bus_type sbus_bus_type; | |||
| 17 | */ | 19 | */ |
| 18 | struct of_device | 20 | struct of_device |
| 19 | { | 21 | { |
| 20 | struct device_node *node; /* OF device node */ | 22 | struct device_node *node; |
| 21 | struct device dev; /* Generic device interface */ | 23 | struct device dev; |
| 24 | struct resource resource[PROMREG_MAX]; | ||
| 25 | unsigned int irq; | ||
| 26 | |||
| 27 | void *sysdata; | ||
| 28 | |||
| 29 | int slot; | ||
| 30 | int portid; | ||
| 31 | int clock_freq; | ||
| 22 | }; | 32 | }; |
| 23 | #define to_of_device(d) container_of(d, struct of_device, dev) | 33 | #define to_of_device(d) container_of(d, struct of_device, dev) |
| 24 | 34 | ||
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h index 4cecfe6d135d..d2849312dea1 100644 --- a/include/asm-sparc64/prom.h +++ b/include/asm-sparc64/prom.h | |||
| @@ -69,6 +69,8 @@ struct device_node { | |||
| 69 | #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) | 69 | #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) |
| 70 | #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) | 70 | #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) |
| 71 | 71 | ||
| 72 | #define OF_BAD_ADDR ((u64)-1) | ||
| 73 | |||
| 72 | static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) | 74 | static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) |
| 73 | { | 75 | { |
| 74 | dn->pde = de; | 76 | dn->pde = de; |
