1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. |
4 | * <benh@kernel.crashing.org> |
5 | * and Arnd Bergmann, IBM Corp. |
6 | * Merged from powerpc/kernel/of_platform.c and |
7 | * sparc{,64}/kernel/of_device.c by Stephen Rothwell |
8 | */ |
9 | |
10 | #define pr_fmt(fmt) "OF: " fmt |
11 | |
12 | #include <linux/errno.h> |
13 | #include <linux/module.h> |
14 | #include <linux/amba/bus.h> |
15 | #include <linux/device.h> |
16 | #include <linux/dma-mapping.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/of_address.h> |
19 | #include <linux/of_device.h> |
20 | #include <linux/of_irq.h> |
21 | #include <linux/of_platform.h> |
22 | #include <linux/platform_device.h> |
23 | |
24 | #include "of_private.h" |
25 | |
26 | const struct of_device_id of_default_bus_match_table[] = { |
27 | { .compatible = "simple-bus" , }, |
28 | { .compatible = "simple-mfd" , }, |
29 | { .compatible = "isa" , }, |
30 | #ifdef CONFIG_ARM_AMBA |
31 | { .compatible = "arm,amba-bus" , }, |
32 | #endif /* CONFIG_ARM_AMBA */ |
33 | {} /* Empty terminated list */ |
34 | }; |
35 | |
36 | /** |
37 | * of_find_device_by_node - Find the platform_device associated with a node |
38 | * @np: Pointer to device tree node |
39 | * |
40 | * Takes a reference to the embedded struct device which needs to be dropped |
41 | * after use. |
42 | * |
43 | * Return: platform_device pointer, or NULL if not found |
44 | */ |
45 | struct platform_device *of_find_device_by_node(struct device_node *np) |
46 | { |
47 | struct device *dev; |
48 | |
49 | dev = bus_find_device_by_of_node(bus: &platform_bus_type, np); |
50 | return dev ? to_platform_device(dev) : NULL; |
51 | } |
52 | EXPORT_SYMBOL(of_find_device_by_node); |
53 | |
54 | int of_device_add(struct platform_device *ofdev) |
55 | { |
56 | BUG_ON(ofdev->dev.of_node == NULL); |
57 | |
58 | /* name and id have to be set so that the platform bus doesn't get |
59 | * confused on matching */ |
60 | ofdev->name = dev_name(dev: &ofdev->dev); |
61 | ofdev->id = PLATFORM_DEVID_NONE; |
62 | |
63 | /* |
64 | * If this device has not binding numa node in devicetree, that is |
65 | * of_node_to_nid returns NUMA_NO_NODE. device_add will assume that this |
66 | * device is on the same node as the parent. |
67 | */ |
68 | set_dev_node(dev: &ofdev->dev, node: of_node_to_nid(np: ofdev->dev.of_node)); |
69 | |
70 | return device_add(dev: &ofdev->dev); |
71 | } |
72 | |
73 | int of_device_register(struct platform_device *pdev) |
74 | { |
75 | device_initialize(dev: &pdev->dev); |
76 | return of_device_add(ofdev: pdev); |
77 | } |
78 | EXPORT_SYMBOL(of_device_register); |
79 | |
80 | void of_device_unregister(struct platform_device *ofdev) |
81 | { |
82 | device_unregister(dev: &ofdev->dev); |
83 | } |
84 | EXPORT_SYMBOL(of_device_unregister); |
85 | |
86 | #ifdef CONFIG_OF_ADDRESS |
87 | static const struct of_device_id of_skipped_node_table[] = { |
88 | { .compatible = "operating-points-v2" , }, |
89 | {} /* Empty terminated list */ |
90 | }; |
91 | |
92 | /* |
93 | * The following routines scan a subtree and registers a device for |
94 | * each applicable node. |
95 | * |
96 | * Note: sparc doesn't use these routines because it has a different |
97 | * mechanism for creating devices from device tree nodes. |
98 | */ |
99 | |
100 | /** |
101 | * of_device_make_bus_id - Use the device node data to assign a unique name |
102 | * @dev: pointer to device structure that is linked to a device tree node |
103 | * |
104 | * This routine will first try using the translated bus address to |
105 | * derive a unique name. If it cannot, then it will prepend names from |
106 | * parent nodes until a unique name can be derived. |
107 | */ |
108 | static void of_device_make_bus_id(struct device *dev) |
109 | { |
110 | struct device_node *node = dev->of_node; |
111 | const __be32 *reg; |
112 | u64 addr; |
113 | u32 mask; |
114 | |
115 | /* Construct the name, using parent nodes if necessary to ensure uniqueness */ |
116 | while (node->parent) { |
117 | /* |
118 | * If the address can be translated, then that is as much |
119 | * uniqueness as we need. Make it the first component and return |
120 | */ |
121 | reg = of_get_property(node, name: "reg" , NULL); |
122 | if (reg && (addr = of_translate_address(np: node, addr: reg)) != OF_BAD_ADDR) { |
123 | if (!of_property_read_u32(np: node, propname: "mask" , out_value: &mask)) |
124 | dev_set_name(dev, name: dev_name(dev) ? "%llx.%x.%pOFn:%s" : "%llx.%x.%pOFn" , |
125 | addr, ffs(mask) - 1, node, dev_name(dev)); |
126 | |
127 | else |
128 | dev_set_name(dev, name: dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn" , |
129 | addr, node, dev_name(dev)); |
130 | return; |
131 | } |
132 | |
133 | /* format arguments only used if dev_name() resolves to NULL */ |
134 | dev_set_name(dev, name: dev_name(dev) ? "%s:%s" : "%s" , |
135 | kbasename(path: node->full_name), dev_name(dev)); |
136 | node = node->parent; |
137 | } |
138 | } |
139 | |
140 | /** |
141 | * of_device_alloc - Allocate and initialize an of_device |
142 | * @np: device node to assign to device |
143 | * @bus_id: Name to assign to the device. May be null to use default name. |
144 | * @parent: Parent device. |
145 | */ |
146 | struct platform_device *of_device_alloc(struct device_node *np, |
147 | const char *bus_id, |
148 | struct device *parent) |
149 | { |
150 | struct platform_device *dev; |
151 | int rc, i, num_reg = 0; |
152 | struct resource *res; |
153 | |
154 | dev = platform_device_alloc(name: "" , PLATFORM_DEVID_NONE); |
155 | if (!dev) |
156 | return NULL; |
157 | |
158 | /* count the io resources */ |
159 | num_reg = of_address_count(np); |
160 | |
161 | /* Populate the resource table */ |
162 | if (num_reg) { |
163 | res = kcalloc(n: num_reg, size: sizeof(*res), GFP_KERNEL); |
164 | if (!res) { |
165 | platform_device_put(pdev: dev); |
166 | return NULL; |
167 | } |
168 | |
169 | dev->num_resources = num_reg; |
170 | dev->resource = res; |
171 | for (i = 0; i < num_reg; i++, res++) { |
172 | rc = of_address_to_resource(dev: np, index: i, r: res); |
173 | WARN_ON(rc); |
174 | } |
175 | } |
176 | |
177 | /* setup generic device info */ |
178 | device_set_node(dev: &dev->dev, of_fwnode_handle(of_node_get(np))); |
179 | dev->dev.parent = parent ? : &platform_bus; |
180 | |
181 | if (bus_id) |
182 | dev_set_name(dev: &dev->dev, name: "%s" , bus_id); |
183 | else |
184 | of_device_make_bus_id(dev: &dev->dev); |
185 | |
186 | return dev; |
187 | } |
188 | EXPORT_SYMBOL(of_device_alloc); |
189 | |
190 | /** |
191 | * of_platform_device_create_pdata - Alloc, initialize and register an of_device |
192 | * @np: pointer to node to create device for |
193 | * @bus_id: name to assign device |
194 | * @platform_data: pointer to populate platform_data pointer with |
195 | * @parent: Linux device model parent device. |
196 | * |
197 | * Return: Pointer to created platform device, or NULL if a device was not |
198 | * registered. Unavailable devices will not get registered. |
199 | */ |
200 | static struct platform_device *of_platform_device_create_pdata( |
201 | struct device_node *np, |
202 | const char *bus_id, |
203 | void *platform_data, |
204 | struct device *parent) |
205 | { |
206 | struct platform_device *dev; |
207 | |
208 | if (!of_device_is_available(device: np) || |
209 | of_node_test_and_set_flag(n: np, OF_POPULATED)) |
210 | return NULL; |
211 | |
212 | dev = of_device_alloc(np, bus_id, parent); |
213 | if (!dev) |
214 | goto err_clear_flag; |
215 | |
216 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
217 | if (!dev->dev.dma_mask) |
218 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; |
219 | dev->dev.bus = &platform_bus_type; |
220 | dev->dev.platform_data = platform_data; |
221 | of_msi_configure(dev: &dev->dev, np: dev->dev.of_node); |
222 | |
223 | if (of_device_add(ofdev: dev) != 0) { |
224 | platform_device_put(pdev: dev); |
225 | goto err_clear_flag; |
226 | } |
227 | |
228 | return dev; |
229 | |
230 | err_clear_flag: |
231 | of_node_clear_flag(n: np, OF_POPULATED); |
232 | return NULL; |
233 | } |
234 | |
235 | /** |
236 | * of_platform_device_create - Alloc, initialize and register an of_device |
237 | * @np: pointer to node to create device for |
238 | * @bus_id: name to assign device |
239 | * @parent: Linux device model parent device. |
240 | * |
241 | * Return: Pointer to created platform device, or NULL if a device was not |
242 | * registered. Unavailable devices will not get registered. |
243 | */ |
244 | struct platform_device *of_platform_device_create(struct device_node *np, |
245 | const char *bus_id, |
246 | struct device *parent) |
247 | { |
248 | return of_platform_device_create_pdata(np, bus_id, NULL, parent); |
249 | } |
250 | EXPORT_SYMBOL(of_platform_device_create); |
251 | |
252 | #ifdef CONFIG_ARM_AMBA |
253 | static struct amba_device *of_amba_device_create(struct device_node *node, |
254 | const char *bus_id, |
255 | void *platform_data, |
256 | struct device *parent) |
257 | { |
258 | struct amba_device *dev; |
259 | int ret; |
260 | |
261 | pr_debug("Creating amba device %pOF\n" , node); |
262 | |
263 | if (!of_device_is_available(node) || |
264 | of_node_test_and_set_flag(node, OF_POPULATED)) |
265 | return NULL; |
266 | |
267 | dev = amba_device_alloc(NULL, 0, 0); |
268 | if (!dev) |
269 | goto err_clear_flag; |
270 | |
271 | /* AMBA devices only support a single DMA mask */ |
272 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
273 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; |
274 | |
275 | /* setup generic device info */ |
276 | device_set_node(&dev->dev, of_fwnode_handle(node)); |
277 | dev->dev.parent = parent ? : &platform_bus; |
278 | dev->dev.platform_data = platform_data; |
279 | if (bus_id) |
280 | dev_set_name(&dev->dev, "%s" , bus_id); |
281 | else |
282 | of_device_make_bus_id(&dev->dev); |
283 | |
284 | /* Allow the HW Peripheral ID to be overridden */ |
285 | of_property_read_u32(node, "arm,primecell-periphid" , &dev->periphid); |
286 | |
287 | ret = of_address_to_resource(node, 0, &dev->res); |
288 | if (ret) { |
289 | pr_err("amba: of_address_to_resource() failed (%d) for %pOF\n" , |
290 | ret, node); |
291 | goto err_free; |
292 | } |
293 | |
294 | ret = amba_device_add(dev, &iomem_resource); |
295 | if (ret) { |
296 | pr_err("amba_device_add() failed (%d) for %pOF\n" , |
297 | ret, node); |
298 | goto err_free; |
299 | } |
300 | |
301 | return dev; |
302 | |
303 | err_free: |
304 | amba_device_put(dev); |
305 | err_clear_flag: |
306 | of_node_clear_flag(node, OF_POPULATED); |
307 | return NULL; |
308 | } |
309 | #else /* CONFIG_ARM_AMBA */ |
310 | static struct amba_device *of_amba_device_create(struct device_node *node, |
311 | const char *bus_id, |
312 | void *platform_data, |
313 | struct device *parent) |
314 | { |
315 | return NULL; |
316 | } |
317 | #endif /* CONFIG_ARM_AMBA */ |
318 | |
319 | /* |
320 | * of_dev_lookup() - Given a device node, lookup the preferred Linux name |
321 | */ |
322 | static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup, |
323 | struct device_node *np) |
324 | { |
325 | const struct of_dev_auxdata *auxdata; |
326 | struct resource res; |
327 | int compatible = 0; |
328 | |
329 | if (!lookup) |
330 | return NULL; |
331 | |
332 | auxdata = lookup; |
333 | for (; auxdata->compatible; auxdata++) { |
334 | if (!of_device_is_compatible(device: np, auxdata->compatible)) |
335 | continue; |
336 | compatible++; |
337 | if (!of_address_to_resource(dev: np, index: 0, r: &res)) |
338 | if (res.start != auxdata->phys_addr) |
339 | continue; |
340 | pr_debug("%pOF: devname=%s\n" , np, auxdata->name); |
341 | return auxdata; |
342 | } |
343 | |
344 | if (!compatible) |
345 | return NULL; |
346 | |
347 | /* Try compatible match if no phys_addr and name are specified */ |
348 | auxdata = lookup; |
349 | for (; auxdata->compatible; auxdata++) { |
350 | if (!of_device_is_compatible(device: np, auxdata->compatible)) |
351 | continue; |
352 | if (!auxdata->phys_addr && !auxdata->name) { |
353 | pr_debug("%pOF: compatible match\n" , np); |
354 | return auxdata; |
355 | } |
356 | } |
357 | |
358 | return NULL; |
359 | } |
360 | |
361 | /** |
362 | * of_platform_bus_create() - Create a device for a node and its children. |
363 | * @bus: device node of the bus to instantiate |
364 | * @matches: match table for bus nodes |
365 | * @lookup: auxdata table for matching id and platform_data with device nodes |
366 | * @parent: parent for new device, or NULL for top level. |
367 | * @strict: require compatible property |
368 | * |
369 | * Creates a platform_device for the provided device_node, and optionally |
370 | * recursively create devices for all the child nodes. |
371 | */ |
372 | static int of_platform_bus_create(struct device_node *bus, |
373 | const struct of_device_id *matches, |
374 | const struct of_dev_auxdata *lookup, |
375 | struct device *parent, bool strict) |
376 | { |
377 | const struct of_dev_auxdata *auxdata; |
378 | struct device_node *child; |
379 | struct platform_device *dev; |
380 | const char *bus_id = NULL; |
381 | void *platform_data = NULL; |
382 | int rc = 0; |
383 | |
384 | /* Make sure it has a compatible property */ |
385 | if (strict && (!of_get_property(node: bus, name: "compatible" , NULL))) { |
386 | pr_debug("%s() - skipping %pOF, no compatible prop\n" , |
387 | __func__, bus); |
388 | return 0; |
389 | } |
390 | |
391 | /* Skip nodes for which we don't want to create devices */ |
392 | if (unlikely(of_match_node(of_skipped_node_table, bus))) { |
393 | pr_debug("%s() - skipping %pOF node\n" , __func__, bus); |
394 | return 0; |
395 | } |
396 | |
397 | if (of_node_check_flag(n: bus, OF_POPULATED_BUS)) { |
398 | pr_debug("%s() - skipping %pOF, already populated\n" , |
399 | __func__, bus); |
400 | return 0; |
401 | } |
402 | |
403 | auxdata = of_dev_lookup(lookup, np: bus); |
404 | if (auxdata) { |
405 | bus_id = auxdata->name; |
406 | platform_data = auxdata->platform_data; |
407 | } |
408 | |
409 | if (of_device_is_compatible(device: bus, "arm,primecell" )) { |
410 | /* |
411 | * Don't return an error here to keep compatibility with older |
412 | * device tree files. |
413 | */ |
414 | of_amba_device_create(node: bus, bus_id, platform_data, parent); |
415 | return 0; |
416 | } |
417 | |
418 | dev = of_platform_device_create_pdata(np: bus, bus_id, platform_data, parent); |
419 | if (!dev || !of_match_node(matches, node: bus)) |
420 | return 0; |
421 | |
422 | for_each_child_of_node(bus, child) { |
423 | pr_debug(" create child: %pOF\n" , child); |
424 | rc = of_platform_bus_create(bus: child, matches, lookup, parent: &dev->dev, strict); |
425 | if (rc) { |
426 | of_node_put(node: child); |
427 | break; |
428 | } |
429 | } |
430 | of_node_set_flag(n: bus, OF_POPULATED_BUS); |
431 | return rc; |
432 | } |
433 | |
434 | /** |
435 | * of_platform_bus_probe() - Probe the device-tree for platform buses |
436 | * @root: parent of the first level to probe or NULL for the root of the tree |
437 | * @matches: match table for bus nodes |
438 | * @parent: parent to hook devices from, NULL for toplevel |
439 | * |
440 | * Note that children of the provided root are not instantiated as devices |
441 | * unless the specified root itself matches the bus list and is not NULL. |
442 | */ |
443 | int of_platform_bus_probe(struct device_node *root, |
444 | const struct of_device_id *matches, |
445 | struct device *parent) |
446 | { |
447 | struct device_node *child; |
448 | int rc = 0; |
449 | |
450 | root = root ? of_node_get(node: root) : of_find_node_by_path(path: "/" ); |
451 | if (!root) |
452 | return -EINVAL; |
453 | |
454 | pr_debug("%s()\n" , __func__); |
455 | pr_debug(" starting at: %pOF\n" , root); |
456 | |
457 | /* Do a self check of bus type, if there's a match, create children */ |
458 | if (of_match_node(matches, node: root)) { |
459 | rc = of_platform_bus_create(bus: root, matches, NULL, parent, strict: false); |
460 | } else for_each_child_of_node(root, child) { |
461 | if (!of_match_node(matches, node: child)) |
462 | continue; |
463 | rc = of_platform_bus_create(bus: child, matches, NULL, parent, strict: false); |
464 | if (rc) { |
465 | of_node_put(node: child); |
466 | break; |
467 | } |
468 | } |
469 | |
470 | of_node_put(node: root); |
471 | return rc; |
472 | } |
473 | EXPORT_SYMBOL(of_platform_bus_probe); |
474 | |
475 | /** |
476 | * of_platform_populate() - Populate platform_devices from device tree data |
477 | * @root: parent of the first level to probe or NULL for the root of the tree |
478 | * @matches: match table, NULL to use the default |
479 | * @lookup: auxdata table for matching id and platform_data with device nodes |
480 | * @parent: parent to hook devices from, NULL for toplevel |
481 | * |
482 | * Similar to of_platform_bus_probe(), this function walks the device tree |
483 | * and creates devices from nodes. It differs in that it follows the modern |
484 | * convention of requiring all device nodes to have a 'compatible' property, |
485 | * and it is suitable for creating devices which are children of the root |
486 | * node (of_platform_bus_probe will only create children of the root which |
487 | * are selected by the @matches argument). |
488 | * |
489 | * New board support should be using this function instead of |
490 | * of_platform_bus_probe(). |
491 | * |
492 | * Return: 0 on success, < 0 on failure. |
493 | */ |
494 | int of_platform_populate(struct device_node *root, |
495 | const struct of_device_id *matches, |
496 | const struct of_dev_auxdata *lookup, |
497 | struct device *parent) |
498 | { |
499 | struct device_node *child; |
500 | int rc = 0; |
501 | |
502 | root = root ? of_node_get(node: root) : of_find_node_by_path(path: "/" ); |
503 | if (!root) |
504 | return -EINVAL; |
505 | |
506 | pr_debug("%s()\n" , __func__); |
507 | pr_debug(" starting at: %pOF\n" , root); |
508 | |
509 | device_links_supplier_sync_state_pause(); |
510 | for_each_child_of_node(root, child) { |
511 | rc = of_platform_bus_create(bus: child, matches, lookup, parent, strict: true); |
512 | if (rc) { |
513 | of_node_put(node: child); |
514 | break; |
515 | } |
516 | } |
517 | device_links_supplier_sync_state_resume(); |
518 | |
519 | of_node_set_flag(n: root, OF_POPULATED_BUS); |
520 | |
521 | of_node_put(node: root); |
522 | return rc; |
523 | } |
524 | EXPORT_SYMBOL_GPL(of_platform_populate); |
525 | |
526 | int of_platform_default_populate(struct device_node *root, |
527 | const struct of_dev_auxdata *lookup, |
528 | struct device *parent) |
529 | { |
530 | return of_platform_populate(root, of_default_bus_match_table, lookup, |
531 | parent); |
532 | } |
533 | EXPORT_SYMBOL_GPL(of_platform_default_populate); |
534 | |
535 | static const struct of_device_id reserved_mem_matches[] = { |
536 | { .compatible = "phram" }, |
537 | { .compatible = "qcom,rmtfs-mem" }, |
538 | { .compatible = "qcom,cmd-db" }, |
539 | { .compatible = "qcom,smem" }, |
540 | { .compatible = "ramoops" }, |
541 | { .compatible = "nvmem-rmem" }, |
542 | { .compatible = "google,open-dice" }, |
543 | {} |
544 | }; |
545 | |
546 | static int __init of_platform_default_populate_init(void) |
547 | { |
548 | struct device_node *node; |
549 | |
550 | device_links_supplier_sync_state_pause(); |
551 | |
552 | if (!of_have_populated_dt()) |
553 | return -ENODEV; |
554 | |
555 | if (IS_ENABLED(CONFIG_PPC)) { |
556 | struct device_node *boot_display = NULL; |
557 | struct platform_device *dev; |
558 | int display_number = 0; |
559 | int ret; |
560 | |
561 | /* Check if we have a MacOS display without a node spec */ |
562 | if (of_property_present(np: of_chosen, propname: "linux,bootx-noscreen" )) { |
563 | /* |
564 | * The old code tried to work out which node was the MacOS |
565 | * display based on the address. I'm dropping that since the |
566 | * lack of a node spec only happens with old BootX versions |
567 | * (users can update) and with this code, they'll still get |
568 | * a display (just not the palette hacks). |
569 | */ |
570 | dev = platform_device_alloc(name: "bootx-noscreen" , id: 0); |
571 | if (WARN_ON(!dev)) |
572 | return -ENOMEM; |
573 | ret = platform_device_add(pdev: dev); |
574 | if (WARN_ON(ret)) { |
575 | platform_device_put(pdev: dev); |
576 | return ret; |
577 | } |
578 | } |
579 | |
580 | /* |
581 | * For OF framebuffers, first create the device for the boot display, |
582 | * then for the other framebuffers. Only fail for the boot display; |
583 | * ignore errors for the rest. |
584 | */ |
585 | for_each_node_by_type(node, "display" ) { |
586 | if (!of_get_property(node, name: "linux,opened" , NULL) || |
587 | !of_get_property(node, name: "linux,boot-display" , NULL)) |
588 | continue; |
589 | dev = of_platform_device_create(node, "of-display" , NULL); |
590 | of_node_put(node); |
591 | if (WARN_ON(!dev)) |
592 | return -ENOMEM; |
593 | boot_display = node; |
594 | display_number++; |
595 | break; |
596 | } |
597 | for_each_node_by_type(node, "display" ) { |
598 | char buf[14]; |
599 | const char *of_display_format = "of-display.%d" ; |
600 | |
601 | if (!of_get_property(node, name: "linux,opened" , NULL) || node == boot_display) |
602 | continue; |
603 | ret = snprintf(buf, size: sizeof(buf), fmt: of_display_format, display_number++); |
604 | if (ret < sizeof(buf)) |
605 | of_platform_device_create(node, buf, NULL); |
606 | } |
607 | |
608 | } else { |
609 | /* |
610 | * Handle certain compatibles explicitly, since we don't want to create |
611 | * platform_devices for every node in /reserved-memory with a |
612 | * "compatible", |
613 | */ |
614 | for_each_matching_node(node, reserved_mem_matches) |
615 | of_platform_device_create(node, NULL, NULL); |
616 | |
617 | node = of_find_node_by_path(path: "/firmware" ); |
618 | if (node) { |
619 | of_platform_populate(node, NULL, NULL, NULL); |
620 | of_node_put(node); |
621 | } |
622 | |
623 | node = of_get_compatible_child(parent: of_chosen, compatible: "simple-framebuffer" ); |
624 | of_platform_device_create(node, NULL, NULL); |
625 | of_node_put(node); |
626 | |
627 | /* Populate everything else. */ |
628 | of_platform_default_populate(NULL, NULL, NULL); |
629 | } |
630 | |
631 | return 0; |
632 | } |
633 | arch_initcall_sync(of_platform_default_populate_init); |
634 | |
635 | static int __init of_platform_sync_state_init(void) |
636 | { |
637 | device_links_supplier_sync_state_resume(); |
638 | return 0; |
639 | } |
640 | late_initcall_sync(of_platform_sync_state_init); |
641 | |
642 | int of_platform_device_destroy(struct device *dev, void *data) |
643 | { |
644 | /* Do not touch devices not populated from the device tree */ |
645 | if (!dev->of_node || !of_node_check_flag(n: dev->of_node, OF_POPULATED)) |
646 | return 0; |
647 | |
648 | /* Recurse for any nodes that were treated as busses */ |
649 | if (of_node_check_flag(n: dev->of_node, OF_POPULATED_BUS)) |
650 | device_for_each_child(dev, NULL, fn: of_platform_device_destroy); |
651 | |
652 | of_node_clear_flag(n: dev->of_node, OF_POPULATED); |
653 | of_node_clear_flag(n: dev->of_node, OF_POPULATED_BUS); |
654 | |
655 | if (dev->bus == &platform_bus_type) |
656 | platform_device_unregister(to_platform_device(dev)); |
657 | #ifdef CONFIG_ARM_AMBA |
658 | else if (dev->bus == &amba_bustype) |
659 | amba_device_unregister(to_amba_device(dev)); |
660 | #endif |
661 | |
662 | return 0; |
663 | } |
664 | EXPORT_SYMBOL_GPL(of_platform_device_destroy); |
665 | |
666 | /** |
667 | * of_platform_depopulate() - Remove devices populated from device tree |
668 | * @parent: device which children will be removed |
669 | * |
670 | * Complementary to of_platform_populate(), this function removes children |
671 | * of the given device (and, recurrently, their children) that have been |
672 | * created from their respective device tree nodes (and only those, |
673 | * leaving others - eg. manually created - unharmed). |
674 | */ |
675 | void of_platform_depopulate(struct device *parent) |
676 | { |
677 | if (parent->of_node && of_node_check_flag(n: parent->of_node, OF_POPULATED_BUS)) { |
678 | device_for_each_child_reverse(dev: parent, NULL, fn: of_platform_device_destroy); |
679 | of_node_clear_flag(n: parent->of_node, OF_POPULATED_BUS); |
680 | } |
681 | } |
682 | EXPORT_SYMBOL_GPL(of_platform_depopulate); |
683 | |
684 | static void devm_of_platform_populate_release(struct device *dev, void *res) |
685 | { |
686 | of_platform_depopulate(*(struct device **)res); |
687 | } |
688 | |
689 | /** |
690 | * devm_of_platform_populate() - Populate platform_devices from device tree data |
691 | * @dev: device that requested to populate from device tree data |
692 | * |
693 | * Similar to of_platform_populate(), but will automatically call |
694 | * of_platform_depopulate() when the device is unbound from the bus. |
695 | * |
696 | * Return: 0 on success, < 0 on failure. |
697 | */ |
698 | int devm_of_platform_populate(struct device *dev) |
699 | { |
700 | struct device **ptr; |
701 | int ret; |
702 | |
703 | if (!dev) |
704 | return -EINVAL; |
705 | |
706 | ptr = devres_alloc(devm_of_platform_populate_release, |
707 | sizeof(*ptr), GFP_KERNEL); |
708 | if (!ptr) |
709 | return -ENOMEM; |
710 | |
711 | ret = of_platform_populate(dev->of_node, NULL, NULL, dev); |
712 | if (ret) { |
713 | devres_free(res: ptr); |
714 | } else { |
715 | *ptr = dev; |
716 | devres_add(dev, res: ptr); |
717 | } |
718 | |
719 | return ret; |
720 | } |
721 | EXPORT_SYMBOL_GPL(devm_of_platform_populate); |
722 | |
723 | static int devm_of_platform_match(struct device *dev, void *res, void *data) |
724 | { |
725 | struct device **ptr = res; |
726 | |
727 | if (!ptr) { |
728 | WARN_ON(!ptr); |
729 | return 0; |
730 | } |
731 | |
732 | return *ptr == data; |
733 | } |
734 | |
735 | /** |
736 | * devm_of_platform_depopulate() - Remove devices populated from device tree |
737 | * @dev: device that requested to depopulate from device tree data |
738 | * |
739 | * Complementary to devm_of_platform_populate(), this function removes children |
740 | * of the given device (and, recurrently, their children) that have been |
741 | * created from their respective device tree nodes (and only those, |
742 | * leaving others - eg. manually created - unharmed). |
743 | */ |
744 | void devm_of_platform_depopulate(struct device *dev) |
745 | { |
746 | int ret; |
747 | |
748 | ret = devres_release(dev, release: devm_of_platform_populate_release, |
749 | match: devm_of_platform_match, match_data: dev); |
750 | |
751 | WARN_ON(ret); |
752 | } |
753 | EXPORT_SYMBOL_GPL(devm_of_platform_depopulate); |
754 | |
755 | #ifdef CONFIG_OF_DYNAMIC |
756 | static int of_platform_notify(struct notifier_block *nb, |
757 | unsigned long action, void *arg) |
758 | { |
759 | struct of_reconfig_data *rd = arg; |
760 | struct platform_device *pdev_parent, *pdev; |
761 | bool children_left; |
762 | |
763 | switch (of_reconfig_get_state_change(action, arg: rd)) { |
764 | case OF_RECONFIG_CHANGE_ADD: |
765 | /* verify that the parent is a bus */ |
766 | if (!of_node_check_flag(n: rd->dn->parent, OF_POPULATED_BUS)) |
767 | return NOTIFY_OK; /* not for us */ |
768 | |
769 | /* already populated? (driver using of_populate manually) */ |
770 | if (of_node_check_flag(n: rd->dn, OF_POPULATED)) |
771 | return NOTIFY_OK; |
772 | |
773 | /* |
774 | * Clear the flag before adding the device so that fw_devlink |
775 | * doesn't skip adding consumers to this device. |
776 | */ |
777 | rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; |
778 | /* pdev_parent may be NULL when no bus platform device */ |
779 | pdev_parent = of_find_device_by_node(rd->dn->parent); |
780 | pdev = of_platform_device_create(rd->dn, NULL, |
781 | pdev_parent ? &pdev_parent->dev : NULL); |
782 | platform_device_put(pdev: pdev_parent); |
783 | |
784 | if (pdev == NULL) { |
785 | pr_err("%s: failed to create for '%pOF'\n" , |
786 | __func__, rd->dn); |
787 | /* of_platform_device_create tosses the error code */ |
788 | return notifier_from_errno(err: -EINVAL); |
789 | } |
790 | break; |
791 | |
792 | case OF_RECONFIG_CHANGE_REMOVE: |
793 | |
794 | /* already depopulated? */ |
795 | if (!of_node_check_flag(n: rd->dn, OF_POPULATED)) |
796 | return NOTIFY_OK; |
797 | |
798 | /* find our device by node */ |
799 | pdev = of_find_device_by_node(rd->dn); |
800 | if (pdev == NULL) |
801 | return NOTIFY_OK; /* no? not meant for us */ |
802 | |
803 | /* unregister takes one ref away */ |
804 | of_platform_device_destroy(&pdev->dev, &children_left); |
805 | |
806 | /* and put the reference of the find */ |
807 | platform_device_put(pdev); |
808 | break; |
809 | } |
810 | |
811 | return NOTIFY_OK; |
812 | } |
813 | |
814 | static struct notifier_block platform_of_notifier = { |
815 | .notifier_call = of_platform_notify, |
816 | }; |
817 | |
818 | void of_platform_register_reconfig_notifier(void) |
819 | { |
820 | WARN_ON(of_reconfig_notifier_register(&platform_of_notifier)); |
821 | } |
822 | #endif /* CONFIG_OF_DYNAMIC */ |
823 | |
824 | #endif /* CONFIG_OF_ADDRESS */ |
825 | |