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 | |
| 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>
| -rw-r--r-- | drivers/of/platform.c | 54 | ||||
| -rw-r--r-- | include/linux/of_platform.h | 3 |
2 files changed, 53 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 */ |
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 8f023f889a8a..839023351176 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h | |||
| @@ -57,6 +57,9 @@ extern struct platform_device *of_platform_device_create(struct device_node *np, | |||
| 57 | extern int of_platform_bus_probe(struct device_node *root, | 57 | extern int of_platform_bus_probe(struct device_node *root, |
| 58 | const struct of_device_id *matches, | 58 | const struct of_device_id *matches, |
| 59 | struct device *parent); | 59 | struct device *parent); |
| 60 | extern int of_platform_populate(struct device_node *root, | ||
| 61 | const struct of_device_id *matches, | ||
| 62 | struct device *parent); | ||
| 60 | #endif /* !CONFIG_SPARC */ | 63 | #endif /* !CONFIG_SPARC */ |
| 61 | 64 | ||
| 62 | #endif /* CONFIG_OF_DEVICE */ | 65 | #endif /* CONFIG_OF_DEVICE */ |
