diff options
Diffstat (limited to 'drivers/of/platform.c')
-rw-r--r-- | drivers/of/platform.c | 55 |
1 files changed, 18 insertions, 37 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 1ce4c45c4ab2..f489e36af892 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, | |||
210 | EXPORT_SYMBOL(of_platform_device_create); | 210 | EXPORT_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, NULL to use the default, OF_NO_DEEP_PROBE to |
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 | */ |
219 | static int of_platform_bus_create(const struct device_node *bus, | 222 | static 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,7 +243,7 @@ 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, NULL to use the default |
251 | * @parent: parent to hook devices from, NULL for toplevel | 249 | * @parent: parent to hook devices from, NULL for toplevel |
@@ -258,7 +256,6 @@ 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 | if (WARN_ON(!matches || matches == OF_NO_DEEP_PROBE)) |
@@ -277,31 +274,15 @@ int of_platform_bus_probe(struct device_node *root, | |||
277 | * children | 274 | * children |
278 | */ | 275 | */ |
279 | if (of_match_node(matches, root)) { | 276 | if (of_match_node(matches, root)) { |
280 | pr_debug(" root match, create all sub devices\n"); | 277 | rc = of_platform_bus_create(root, matches, parent); |
281 | dev = of_platform_device_create(root, NULL, parent); | 278 | } 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)) | 279 | if (!of_match_node(matches, child)) |
291 | continue; | 280 | continue; |
292 | 281 | rc = of_platform_bus_create(child, matches, parent); | |
293 | pr_debug(" match: %s\n", child->full_name); | 282 | 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; | 283 | break; |
302 | } | ||
303 | } | 284 | } |
304 | bail: | 285 | |
305 | of_node_put(root); | 286 | of_node_put(root); |
306 | return rc; | 287 | return rc; |
307 | } | 288 | } |