diff options
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/platform.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index d9c81e93bdd0..ea87a3cf7860 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -408,6 +408,93 @@ EXPORT_SYMBOL(of_unregister_driver); | |||
408 | */ | 408 | */ |
409 | 409 | ||
410 | /** | 410 | /** |
411 | * of_device_make_bus_id - Use the device node data to assign a unique name | ||
412 | * @dev: pointer to device structure that is linked to a device tree node | ||
413 | * | ||
414 | * This routine will first try using either the dcr-reg or the reg property | ||
415 | * value to derive a unique name. As a last resort it will use the node | ||
416 | * name followed by a unique number. | ||
417 | */ | ||
418 | static void of_device_make_bus_id(struct device *dev) | ||
419 | { | ||
420 | static atomic_t bus_no_reg_magic; | ||
421 | struct device_node *node = dev->of_node; | ||
422 | const u32 *reg; | ||
423 | u64 addr; | ||
424 | int magic; | ||
425 | |||
426 | #ifdef CONFIG_PPC_DCR | ||
427 | /* | ||
428 | * If it's a DCR based device, use 'd' for native DCRs | ||
429 | * and 'D' for MMIO DCRs. | ||
430 | */ | ||
431 | reg = of_get_property(node, "dcr-reg", NULL); | ||
432 | if (reg) { | ||
433 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
434 | dev_set_name(dev, "d%x.%s", *reg, node->name); | ||
435 | #else /* CONFIG_PPC_DCR_NATIVE */ | ||
436 | u64 addr = of_translate_dcr_address(node, *reg, NULL); | ||
437 | if (addr != OF_BAD_ADDR) { | ||
438 | dev_set_name(dev, "D%llx.%s", | ||
439 | (unsigned long long)addr, node->name); | ||
440 | return; | ||
441 | } | ||
442 | #endif /* !CONFIG_PPC_DCR_NATIVE */ | ||
443 | } | ||
444 | #endif /* CONFIG_PPC_DCR */ | ||
445 | |||
446 | /* | ||
447 | * For MMIO, get the physical address | ||
448 | */ | ||
449 | reg = of_get_property(node, "reg", NULL); | ||
450 | if (reg) { | ||
451 | addr = of_translate_address(node, reg); | ||
452 | if (addr != OF_BAD_ADDR) { | ||
453 | dev_set_name(dev, "%llx.%s", | ||
454 | (unsigned long long)addr, node->name); | ||
455 | return; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * No BusID, use the node name and add a globally incremented | ||
461 | * counter (and pray...) | ||
462 | */ | ||
463 | magic = atomic_add_return(1, &bus_no_reg_magic); | ||
464 | dev_set_name(dev, "%s.%d", node->name, magic - 1); | ||
465 | } | ||
466 | |||
467 | /** | ||
468 | * of_device_alloc - Allocate and initialize an of_device | ||
469 | * @np: device node to assign to device | ||
470 | * @bus_id: Name to assign to the device. May be null to use default name. | ||
471 | * @parent: Parent device. | ||
472 | */ | ||
473 | struct of_device *of_device_alloc(struct device_node *np, | ||
474 | const char *bus_id, | ||
475 | struct device *parent) | ||
476 | { | ||
477 | struct of_device *dev; | ||
478 | |||
479 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
480 | if (!dev) | ||
481 | return NULL; | ||
482 | |||
483 | dev->dev.of_node = of_node_get(np); | ||
484 | dev->dev.dma_mask = &dev->archdata.dma_mask; | ||
485 | dev->dev.parent = parent; | ||
486 | dev->dev.release = of_release_dev; | ||
487 | |||
488 | if (bus_id) | ||
489 | dev_set_name(&dev->dev, "%s", bus_id); | ||
490 | else | ||
491 | of_device_make_bus_id(&dev->dev); | ||
492 | |||
493 | return dev; | ||
494 | } | ||
495 | EXPORT_SYMBOL(of_device_alloc); | ||
496 | |||
497 | /** | ||
411 | * of_platform_device_create - Alloc, initialize and register an of_device | 498 | * of_platform_device_create - Alloc, initialize and register an of_device |
412 | * @np: pointer to node to create device for | 499 | * @np: pointer to node to create device for |
413 | * @bus_id: name to assign device | 500 | * @bus_id: name to assign device |