of_platform.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
  3. * <benh@kernel.crashing.org>
  4. * and Arnd Bergmann, IBM Corp.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. *
  11. */
  12. #undef DEBUG
  13. #include <linux/string.h>
  14. #include <linux/kernel.h>
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. #include <linux/mod_devicetable.h>
  18. #include <linux/pci.h>
  19. #include <linux/of.h>
  20. #include <linux/of_device.h>
  21. #include <linux/of_platform.h>
  22. #include <linux/errno.h>
  23. #include <linux/topology.h>
  24. #include <asm/atomic.h>
  25. struct bus_type of_platform_bus_type = {
  26. .uevent = of_device_uevent,
  27. };
  28. EXPORT_SYMBOL(of_platform_bus_type);
  29. static int __init of_bus_driver_init(void)
  30. {
  31. return of_bus_type_init(&of_platform_bus_type, "of_platform");
  32. }
  33. postcore_initcall(of_bus_driver_init);
  34. struct of_device *of_platform_device_create(struct device_node *np,
  35. const char *bus_id,
  36. struct device *parent)
  37. {
  38. struct of_device *dev;
  39. dev = of_device_alloc(np, bus_id, parent);
  40. if (!dev)
  41. return NULL;
  42. dev->dma_mask = 0xffffffffUL;
  43. dev->dev.bus = &of_platform_bus_type;
  44. /* We do not fill the DMA ops for platform devices by default.
  45. * This is currently the responsibility of the platform code
  46. * to do such, possibly using a device notifier
  47. */
  48. if (of_device_register(dev) != 0) {
  49. of_device_free(dev);
  50. return NULL;
  51. }
  52. return dev;
  53. }
  54. EXPORT_SYMBOL(of_platform_device_create);
  55. /**
  56. * of_platform_bus_create - Create an OF device for a bus node and all its
  57. * children. Optionally recursively instanciate matching busses.
  58. * @bus: device node of the bus to instanciate
  59. * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
  60. * disallow recursive creation of child busses
  61. */
  62. static int of_platform_bus_create(const struct device_node *bus,
  63. const struct of_device_id *matches,
  64. struct device *parent)
  65. {
  66. struct device_node *child;
  67. struct of_device *dev;
  68. int rc = 0;
  69. for_each_child_of_node(bus, child) {
  70. pr_debug(" create child: %s\n", child->full_name);
  71. dev = of_platform_device_create(child, NULL, parent);
  72. if (dev == NULL)
  73. rc = -ENOMEM;
  74. else if (!of_match_node(matches, child))
  75. continue;
  76. if (rc == 0) {
  77. pr_debug(" and sub busses\n");
  78. rc = of_platform_bus_create(child, matches, &dev->dev);
  79. }
  80. if (rc) {
  81. of_node_put(child);
  82. break;
  83. }
  84. }
  85. return rc;
  86. }
  87. /**
  88. * of_platform_bus_probe - Probe the device-tree for platform busses
  89. * @root: parent of the first level to probe or NULL for the root of the tree
  90. * @matches: match table, NULL to use the default
  91. * @parent: parent to hook devices from, NULL for toplevel
  92. *
  93. * Note that children of the provided root are not instanciated as devices
  94. * unless the specified root itself matches the bus list and is not NULL.
  95. */
  96. int of_platform_bus_probe(struct device_node *root,
  97. const struct of_device_id *matches,
  98. struct device *parent)
  99. {
  100. struct device_node *child;
  101. struct of_device *dev;
  102. int rc = 0;
  103. if (matches == NULL)
  104. matches = of_default_bus_ids;
  105. if (matches == OF_NO_DEEP_PROBE)
  106. return -EINVAL;
  107. if (root == NULL)
  108. root = of_find_node_by_path("/");
  109. else
  110. of_node_get(root);
  111. pr_debug("of_platform_bus_probe()\n");
  112. pr_debug(" starting at: %s\n", root->full_name);
  113. /* Do a self check of bus type, if there's a match, create
  114. * children
  115. */
  116. if (of_match_node(matches, root)) {
  117. pr_debug(" root match, create all sub devices\n");
  118. dev = of_platform_device_create(root, NULL, parent);
  119. if (dev == NULL) {
  120. rc = -ENOMEM;
  121. goto bail;
  122. }
  123. pr_debug(" create all sub busses\n");
  124. rc = of_platform_bus_create(root, matches, &dev->dev);
  125. goto bail;
  126. }
  127. for_each_child_of_node(root, child) {
  128. if (!of_match_node(matches, child))
  129. continue;
  130. pr_debug(" match: %s\n", child->full_name);
  131. dev = of_platform_device_create(child, NULL, parent);
  132. if (dev == NULL)
  133. rc = -ENOMEM;
  134. else
  135. rc = of_platform_bus_create(child, matches, &dev->dev);
  136. if (rc) {
  137. of_node_put(child);
  138. break;
  139. }
  140. }
  141. bail:
  142. of_node_put(root);
  143. return rc;
  144. }
  145. EXPORT_SYMBOL(of_platform_bus_probe);
  146. static int of_dev_node_match(struct device *dev, void *data)
  147. {
  148. return to_of_device(dev)->node == data;
  149. }
  150. struct of_device *of_find_device_by_node(struct device_node *np)
  151. {
  152. struct device *dev;
  153. dev = bus_find_device(&of_platform_bus_type,
  154. NULL, np, of_dev_node_match);
  155. if (dev)
  156. return to_of_device(dev);
  157. return NULL;
  158. }
  159. EXPORT_SYMBOL(of_find_device_by_node);
  160. static int of_dev_phandle_match(struct device *dev, void *data)
  161. {
  162. phandle *ph = data;
  163. return to_of_device(dev)->node->phandle == *ph;
  164. }
  165. struct of_device *of_find_device_by_phandle(phandle ph)
  166. {
  167. struct device *dev;
  168. dev = bus_find_device(&of_platform_bus_type,
  169. NULL, &ph, of_dev_phandle_match);
  170. if (dev)
  171. return to_of_device(dev);
  172. return NULL;
  173. }
  174. EXPORT_SYMBOL(of_find_device_by_phandle);