aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/platform.c')
-rw-r--r--drivers/of/platform.c72
1 files changed, 23 insertions, 49 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 1ce4c45c4ab2..63d3cb73bdb9 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -210,13 +210,16 @@ struct platform_device *of_platform_device_create(struct device_node *np,
210EXPORT_SYMBOL(of_platform_device_create); 210EXPORT_SYMBOL(of_platform_device_create);
211 211
212/** 212/**
213 * of_platform_bus_create - Create an OF device for a bus node and all its 213 * of_platform_bus_create() - Create a device for a node and its children.
214 * children. Optionally recursively instantiate matching busses.
215 * @bus: device node of the bus to instantiate 214 * @bus: device node of the bus to instantiate
216 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to 215 * @matches: match table for bus nodes
217 * disallow recursive creation of child busses 216 * disallow recursive creation of child buses
217 * @parent: parent for new device, or NULL for top level.
218 *
219 * Creates a platform_device for the provided device_node, and optionally
220 * recursively create devices for all the child nodes.
218 */ 221 */
219static int of_platform_bus_create(const struct device_node *bus, 222static int of_platform_bus_create(struct device_node *bus,
220 const struct of_device_id *matches, 223 const struct of_device_id *matches,
221 struct device *parent) 224 struct device *parent)
222{ 225{
@@ -224,18 +227,13 @@ static int of_platform_bus_create(const struct device_node *bus,
224 struct platform_device *dev; 227 struct platform_device *dev;
225 int rc = 0; 228 int rc = 0;
226 229
230 dev = of_platform_device_create(bus, NULL, parent);
231 if (!dev || !of_match_node(matches, bus))
232 return 0;
233
227 for_each_child_of_node(bus, child) { 234 for_each_child_of_node(bus, child) {
228 pr_debug(" create child: %s\n", child->full_name); 235 pr_debug(" create child: %s\n", child->full_name);
229 dev = of_platform_device_create(child, NULL, parent); 236 rc = of_platform_bus_create(child, matches, &dev->dev);
230 if (dev == NULL)
231 continue;
232
233 if (!of_match_node(matches, child))
234 continue;
235 if (rc == 0) {
236 pr_debug(" and sub busses\n");
237 rc = of_platform_bus_create(child, matches, &dev->dev);
238 }
239 if (rc) { 237 if (rc) {
240 of_node_put(child); 238 of_node_put(child);
241 break; 239 break;
@@ -245,9 +243,9 @@ static int of_platform_bus_create(const struct device_node *bus,
245} 243}
246 244
247/** 245/**
248 * of_platform_bus_probe - Probe the device-tree for platform busses 246 * of_platform_bus_probe() - Probe the device-tree for platform buses
249 * @root: parent of the first level to probe or NULL for the root of the tree 247 * @root: parent of the first level to probe or NULL for the root of the tree
250 * @matches: match table, NULL to use the default 248 * @matches: match table for bus nodes
251 * @parent: parent to hook devices from, NULL for toplevel 249 * @parent: parent to hook devices from, NULL for toplevel
252 * 250 *
253 * Note that children of the provided root are not instantiated as devices 251 * Note that children of the provided root are not instantiated as devices
@@ -258,50 +256,26 @@ int of_platform_bus_probe(struct device_node *root,
258 struct device *parent) 256 struct device *parent)
259{ 257{
260 struct device_node *child; 258 struct device_node *child;
261 struct platform_device *dev;
262 int rc = 0; 259 int rc = 0;
263 260
264 if (WARN_ON(!matches || matches == OF_NO_DEEP_PROBE)) 261 root = root ? of_node_get(root) : of_find_node_by_path("/");
265 return -EINVAL; 262 if (!root)
266 if (root == NULL)
267 root = of_find_node_by_path("/");
268 else
269 of_node_get(root);
270 if (root == NULL)
271 return -EINVAL; 263 return -EINVAL;
272 264
273 pr_debug("of_platform_bus_probe()\n"); 265 pr_debug("of_platform_bus_probe()\n");
274 pr_debug(" starting at: %s\n", root->full_name); 266 pr_debug(" starting at: %s\n", root->full_name);
275 267
276 /* Do a self check of bus type, if there's a match, create 268 /* Do a self check of bus type, if there's a match, create children */
277 * children
278 */
279 if (of_match_node(matches, root)) { 269 if (of_match_node(matches, root)) {
280 pr_debug(" root match, create all sub devices\n"); 270 rc = of_platform_bus_create(root, matches, parent);
281 dev = of_platform_device_create(root, NULL, parent); 271 } else for_each_child_of_node(root, child) {
282 if (dev == NULL)
283 goto bail;
284
285 pr_debug(" create all sub busses\n");
286 rc = of_platform_bus_create(root, matches, &dev->dev);
287 goto bail;
288 }
289 for_each_child_of_node(root, child) {
290 if (!of_match_node(matches, child)) 272 if (!of_match_node(matches, child))
291 continue; 273 continue;
292 274 rc = of_platform_bus_create(child, matches, parent);
293 pr_debug(" match: %s\n", child->full_name); 275 if (rc)
294 dev = of_platform_device_create(child, NULL, parent);
295 if (dev == NULL)
296 continue;
297
298 rc = of_platform_bus_create(child, matches, &dev->dev);
299 if (rc) {
300 of_node_put(child);
301 break; 276 break;
302 }
303 } 277 }
304 bail: 278
305 of_node_put(root); 279 of_node_put(root);
306 return rc; 280 return rc;
307} 281}