aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/platform.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 7dacc1ebe91e..d9c81e93bdd0 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -14,6 +14,7 @@
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/dma-mapping.h>
17#include <linux/of_device.h> 18#include <linux/of_device.h>
18#include <linux/of_platform.h> 19#include <linux/of_platform.h>
19 20
@@ -396,3 +397,145 @@ void of_unregister_driver(struct of_platform_driver *drv)
396 driver_unregister(&drv->driver); 397 driver_unregister(&drv->driver);
397} 398}
398EXPORT_SYMBOL(of_unregister_driver); 399EXPORT_SYMBOL(of_unregister_driver);
400
401#if !defined(CONFIG_SPARC)
402/*
403 * The following routines scan a subtree and registers a device for
404 * each applicable node.
405 *
406 * Note: sparc doesn't use these routines because it has a different
407 * mechanism for creating devices from device tree nodes.
408 */
409
410/**
411 * of_platform_device_create - Alloc, initialize and register an of_device
412 * @np: pointer to node to create device for
413 * @bus_id: name to assign device
414 * @parent: Linux device model parent device.
415 */
416struct of_device *of_platform_device_create(struct device_node *np,
417 const char *bus_id,
418 struct device *parent)
419{
420 struct of_device *dev;
421
422 dev = of_device_alloc(np, bus_id, parent);
423 if (!dev)
424 return NULL;
425
426 dev->archdata.dma_mask = 0xffffffffUL;
427 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
428 dev->dev.bus = &of_platform_bus_type;
429
430 /* We do not fill the DMA ops for platform devices by default.
431 * This is currently the responsibility of the platform code
432 * to do such, possibly using a device notifier
433 */
434
435 if (of_device_register(dev) != 0) {
436 of_device_free(dev);
437 return NULL;
438 }
439
440 return dev;
441}
442EXPORT_SYMBOL(of_platform_device_create);
443
444/**
445 * of_platform_bus_create - Create an OF device for a bus node and all its
446 * children. Optionally recursively instantiate matching busses.
447 * @bus: device node of the bus to instantiate
448 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
449 * disallow recursive creation of child busses
450 */
451static int of_platform_bus_create(const struct device_node *bus,
452 const struct of_device_id *matches,
453 struct device *parent)
454{
455 struct device_node *child;
456 struct of_device *dev;
457 int rc = 0;
458
459 for_each_child_of_node(bus, child) {
460 pr_debug(" create child: %s\n", child->full_name);
461 dev = of_platform_device_create(child, NULL, parent);
462 if (dev == NULL)
463 rc = -ENOMEM;
464 else if (!of_match_node(matches, child))
465 continue;
466 if (rc == 0) {
467 pr_debug(" and sub busses\n");
468 rc = of_platform_bus_create(child, matches, &dev->dev);
469 }
470 if (rc) {
471 of_node_put(child);
472 break;
473 }
474 }
475 return rc;
476}
477
478/**
479 * of_platform_bus_probe - Probe the device-tree for platform busses
480 * @root: parent of the first level to probe or NULL for the root of the tree
481 * @matches: match table, NULL to use the default
482 * @parent: parent to hook devices from, NULL for toplevel
483 *
484 * Note that children of the provided root are not instantiated as devices
485 * unless the specified root itself matches the bus list and is not NULL.
486 */
487int of_platform_bus_probe(struct device_node *root,
488 const struct of_device_id *matches,
489 struct device *parent)
490{
491 struct device_node *child;
492 struct of_device *dev;
493 int rc = 0;
494
495 if (matches == NULL)
496 matches = of_default_bus_ids;
497 if (matches == OF_NO_DEEP_PROBE)
498 return -EINVAL;
499 if (root == NULL)
500 root = of_find_node_by_path("/");
501 else
502 of_node_get(root);
503
504 pr_debug("of_platform_bus_probe()\n");
505 pr_debug(" starting at: %s\n", root->full_name);
506
507 /* Do a self check of bus type, if there's a match, create
508 * children
509 */
510 if (of_match_node(matches, root)) {
511 pr_debug(" root match, create all sub devices\n");
512 dev = of_platform_device_create(root, NULL, parent);
513 if (dev == NULL) {
514 rc = -ENOMEM;
515 goto bail;
516 }
517 pr_debug(" create all sub busses\n");
518 rc = of_platform_bus_create(root, matches, &dev->dev);
519 goto bail;
520 }
521 for_each_child_of_node(root, child) {
522 if (!of_match_node(matches, child))
523 continue;
524
525 pr_debug(" match: %s\n", child->full_name);
526 dev = of_platform_device_create(child, NULL, parent);
527 if (dev == NULL)
528 rc = -ENOMEM;
529 else
530 rc = of_platform_bus_create(child, matches, &dev->dev);
531 if (rc) {
532 of_node_put(child);
533 break;
534 }
535 }
536 bail:
537 of_node_put(root);
538 return rc;
539}
540EXPORT_SYMBOL(of_platform_bus_probe);
541#endif /* !CONFIG_SPARC */