diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2011-06-21 12:59:34 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-06-21 13:02:29 -0400 |
commit | 29d4f8a4974aacf46b028fa92f9dd3ffdba3e614 (patch) | |
tree | 35641937ac753b8b5d0255ef9ef312024e09a785 /drivers/of/platform.c | |
parent | cbb49c2665eebfd1fa2e491403684d0542662137 (diff) |
dt: add of_platform_populate() for creating device from the device tree
of_platform_populate() is similar to of_platform_bus_probe() except
that it strictly enforces that all device nodes must have a compatible
property, and it can be used to register devices (not buses) which are
children of the root node.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/of/platform.c')
-rw-r--r-- | drivers/of/platform.c | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index bb483ef32e00..1f4a5d3af76e 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -229,19 +229,26 @@ EXPORT_SYMBOL(of_platform_device_create); | |||
229 | */ | 229 | */ |
230 | static int of_platform_bus_create(struct device_node *bus, | 230 | static int of_platform_bus_create(struct device_node *bus, |
231 | const struct of_device_id *matches, | 231 | const struct of_device_id *matches, |
232 | struct device *parent) | 232 | struct device *parent, bool strict) |
233 | { | 233 | { |
234 | struct device_node *child; | 234 | struct device_node *child; |
235 | struct platform_device *dev; | 235 | struct platform_device *dev; |
236 | int rc = 0; | 236 | int rc = 0; |
237 | 237 | ||
238 | /* Make sure it has a compatible property */ | ||
239 | if (strict && (!of_get_property(bus, "compatible", NULL))) { | ||
240 | pr_debug("%s() - skipping %s, no compatible prop\n", | ||
241 | __func__, bus->full_name); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
238 | dev = of_platform_device_create(bus, NULL, parent); | 245 | dev = of_platform_device_create(bus, NULL, parent); |
239 | if (!dev || !of_match_node(matches, bus)) | 246 | if (!dev || !of_match_node(matches, bus)) |
240 | return 0; | 247 | return 0; |
241 | 248 | ||
242 | for_each_child_of_node(bus, child) { | 249 | for_each_child_of_node(bus, child) { |
243 | pr_debug(" create child: %s\n", child->full_name); | 250 | pr_debug(" create child: %s\n", child->full_name); |
244 | rc = of_platform_bus_create(child, matches, &dev->dev); | 251 | rc = of_platform_bus_create(child, matches, &dev->dev, strict); |
245 | if (rc) { | 252 | if (rc) { |
246 | of_node_put(child); | 253 | of_node_put(child); |
247 | break; | 254 | break; |
@@ -275,11 +282,11 @@ int of_platform_bus_probe(struct device_node *root, | |||
275 | 282 | ||
276 | /* Do a self check of bus type, if there's a match, create children */ | 283 | /* Do a self check of bus type, if there's a match, create children */ |
277 | if (of_match_node(matches, root)) { | 284 | if (of_match_node(matches, root)) { |
278 | rc = of_platform_bus_create(root, matches, parent); | 285 | rc = of_platform_bus_create(root, matches, parent, false); |
279 | } else for_each_child_of_node(root, child) { | 286 | } else for_each_child_of_node(root, child) { |
280 | if (!of_match_node(matches, child)) | 287 | if (!of_match_node(matches, child)) |
281 | continue; | 288 | continue; |
282 | rc = of_platform_bus_create(child, matches, parent); | 289 | rc = of_platform_bus_create(child, matches, parent, false); |
283 | if (rc) | 290 | if (rc) |
284 | break; | 291 | break; |
285 | } | 292 | } |
@@ -288,4 +295,43 @@ int of_platform_bus_probe(struct device_node *root, | |||
288 | return rc; | 295 | return rc; |
289 | } | 296 | } |
290 | EXPORT_SYMBOL(of_platform_bus_probe); | 297 | EXPORT_SYMBOL(of_platform_bus_probe); |
298 | |||
299 | /** | ||
300 | * of_platform_populate() - Populate platform_devices from device tree data | ||
301 | * @root: parent of the first level to probe or NULL for the root of the tree | ||
302 | * @matches: match table, NULL to use the default | ||
303 | * @parent: parent to hook devices from, NULL for toplevel | ||
304 | * | ||
305 | * Similar to of_platform_bus_probe(), this function walks the device tree | ||
306 | * and creates devices from nodes. It differs in that it follows the modern | ||
307 | * convention of requiring all device nodes to have a 'compatible' property, | ||
308 | * and it is suitable for creating devices which are children of the root | ||
309 | * node (of_platform_bus_probe will only create children of the root which | ||
310 | * are selected by the @matches argument). | ||
311 | * | ||
312 | * New board support should be using this function instead of | ||
313 | * of_platform_bus_probe(). | ||
314 | * | ||
315 | * Returns 0 on success, < 0 on failure. | ||
316 | */ | ||
317 | int of_platform_populate(struct device_node *root, | ||
318 | const struct of_device_id *matches, | ||
319 | struct device *parent) | ||
320 | { | ||
321 | struct device_node *child; | ||
322 | int rc = 0; | ||
323 | |||
324 | root = root ? of_node_get(root) : of_find_node_by_path("/"); | ||
325 | if (!root) | ||
326 | return -EINVAL; | ||
327 | |||
328 | for_each_child_of_node(root, child) { | ||
329 | rc = of_platform_bus_create(child, matches, parent, true); | ||
330 | if (rc) | ||
331 | break; | ||
332 | } | ||
333 | |||
334 | of_node_put(root); | ||
335 | return rc; | ||
336 | } | ||
291 | #endif /* !CONFIG_SPARC */ | 337 | #endif /* !CONFIG_SPARC */ |