aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-06-08 09:48:13 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-07-05 18:14:28 -0400
commit5fd200f3b351183b5489cef69961c60af9cead2f (patch)
tree322780d69cfefd88dd959e2b60aa23ce28cc8d2c
parent34a1c1e8c700f7cd849deb21193718a172722f8d (diff)
of/device: Merge of_platform_bus_probe()
Merge common code between PowerPC and microblaze. This patch merges the code that scans the tree and registers devices. The functions merged are of_platform_bus_probe(), of_platform_bus_create(), and of_platform_device_create(). This patch also move the of_default_bus_ids[] table out of a Microblaze header file and makes it non-static. The device ids table isn't merged because powerpc and microblaze use different default data. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> CC: Michal Simek <monstr@monstr.eu> CC: Grant Likely <grant.likely@secretlab.ca> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org> CC: Stephen Rothwell <sfr@canb.auug.org.au> CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org
-rw-r--r--arch/microblaze/include/asm/of_platform.h33
-rw-r--r--arch/microblaze/kernel/of_platform.c141
-rw-r--r--arch/powerpc/include/asm/of_platform.h11
-rw-r--r--arch/powerpc/kernel/of_platform.c131
-rw-r--r--drivers/of/platform.c143
-rw-r--r--include/linux/of_platform.h17
6 files changed, 179 insertions, 297 deletions
diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h
index 37491276c6ca..625003f70888 100644
--- a/arch/microblaze/include/asm/of_platform.h
+++ b/arch/microblaze/include/asm/of_platform.h
@@ -14,39 +14,6 @@
14/* This is just here during the transition */ 14/* This is just here during the transition */
15#include <linux/of_platform.h> 15#include <linux/of_platform.h>
16 16
17/*
18 * The list of OF IDs below is used for matching bus types in the
19 * system whose devices are to be exposed as of_platform_devices.
20 *
21 * This is the default list valid for most platforms. This file provides
22 * functions who can take an explicit list if necessary though
23 *
24 * The search is always performed recursively looking for children of
25 * the provided device_node and recursively if such a children matches
26 * a bus type in the list
27 */
28
29static const struct of_device_id of_default_bus_ids[] = {
30 { .type = "soc", },
31 { .compatible = "soc", },
32 { .type = "plb5", },
33 { .type = "plb4", },
34 { .type = "opb", },
35 { .type = "simple", },
36 {},
37};
38
39/* Platform devices and busses creation */
40extern struct of_device *of_platform_device_create(struct device_node *np,
41 const char *bus_id,
42 struct device *parent);
43/* pseudo "matches" value to not do deep probe */
44#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
45
46extern int of_platform_bus_probe(struct device_node *root,
47 const struct of_device_id *matches,
48 struct device *parent);
49
50extern struct of_device *of_find_device_by_phandle(phandle ph); 17extern struct of_device *of_find_device_by_phandle(phandle ph);
51 18
52extern void of_instantiate_rtc(void); 19extern void of_instantiate_rtc(void);
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c
index ccf6f4257f4b..a07abdd6859b 100644
--- a/arch/microblaze/kernel/of_platform.c
+++ b/arch/microblaze/kernel/of_platform.c
@@ -37,132 +37,27 @@ static int __init of_bus_driver_init(void)
37} 37}
38postcore_initcall(of_bus_driver_init); 38postcore_initcall(of_bus_driver_init);
39 39
40struct of_device *of_platform_device_create(struct device_node *np, 40/*
41 const char *bus_id, 41 * The list of OF IDs below is used for matching bus types in the
42 struct device *parent) 42 * system whose devices are to be exposed as of_platform_devices.
43{
44 struct of_device *dev;
45
46 dev = of_device_alloc(np, bus_id, parent);
47 if (!dev)
48 return NULL;
49
50 dev->archdata.dma_mask = 0xffffffffUL;
51 dev->dev.bus = &of_platform_bus_type;
52
53 /* We do not fill the DMA ops for platform devices by default.
54 * This is currently the responsibility of the platform code
55 * to do such, possibly using a device notifier
56 */
57
58 if (of_device_register(dev) != 0) {
59 of_device_free(dev);
60 return NULL;
61 }
62
63 return dev;
64}
65EXPORT_SYMBOL(of_platform_device_create);
66
67/**
68 * of_platform_bus_create - Create an OF device for a bus node and all its
69 * children. Optionally recursively instanciate matching busses.
70 * @bus: device node of the bus to instanciate
71 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
72 * disallow recursive creation of child busses
73 */
74static int of_platform_bus_create(const struct device_node *bus,
75 const struct of_device_id *matches,
76 struct device *parent)
77{
78 struct device_node *child;
79 struct of_device *dev;
80 int rc = 0;
81
82 for_each_child_of_node(bus, child) {
83 pr_debug(" create child: %s\n", child->full_name);
84 dev = of_platform_device_create(child, NULL, parent);
85 if (dev == NULL)
86 rc = -ENOMEM;
87 else if (!of_match_node(matches, child))
88 continue;
89 if (rc == 0) {
90 pr_debug(" and sub busses\n");
91 rc = of_platform_bus_create(child, matches, &dev->dev);
92 }
93 if (rc) {
94 of_node_put(child);
95 break;
96 }
97 }
98 return rc;
99}
100
101
102/**
103 * of_platform_bus_probe - Probe the device-tree for platform busses
104 * @root: parent of the first level to probe or NULL for the root of the tree
105 * @matches: match table, NULL to use the default
106 * @parent: parent to hook devices from, NULL for toplevel
107 * 43 *
108 * Note that children of the provided root are not instanciated as devices 44 * This is the default list valid for most platforms. This file provides
109 * unless the specified root itself matches the bus list and is not NULL. 45 * functions who can take an explicit list if necessary though
46 *
47 * The search is always performed recursively looking for children of
48 * the provided device_node and recursively if such a children matches
49 * a bus type in the list
110 */ 50 */
111 51
112int of_platform_bus_probe(struct device_node *root, 52const struct of_device_id of_default_bus_ids[] = {
113 const struct of_device_id *matches, 53 { .type = "soc", },
114 struct device *parent) 54 { .compatible = "soc", },
115{ 55 { .type = "plb5", },
116 struct device_node *child; 56 { .type = "plb4", },
117 struct of_device *dev; 57 { .type = "opb", },
118 int rc = 0; 58 { .type = "simple", },
119 59 {},
120 if (matches == NULL) 60};
121 matches = of_default_bus_ids;
122 if (matches == OF_NO_DEEP_PROBE)
123 return -EINVAL;
124 if (root == NULL)
125 root = of_find_node_by_path("/");
126 else
127 of_node_get(root);
128
129 pr_debug("of_platform_bus_probe()\n");
130 pr_debug(" starting at: %s\n", root->full_name);
131
132 /* Do a self check of bus type, if there's a match, create
133 * children
134 */
135 if (of_match_node(matches, root)) {
136 pr_debug(" root match, create all sub devices\n");
137 dev = of_platform_device_create(root, NULL, parent);
138 if (dev == NULL) {
139 rc = -ENOMEM;
140 goto bail;
141 }
142 pr_debug(" create all sub busses\n");
143 rc = of_platform_bus_create(root, matches, &dev->dev);
144 goto bail;
145 }
146 for_each_child_of_node(root, child) {
147 if (!of_match_node(matches, child))
148 continue;
149
150 pr_debug(" match: %s\n", child->full_name);
151 dev = of_platform_device_create(child, NULL, parent);
152 if (dev == NULL)
153 rc = -ENOMEM;
154 else
155 rc = of_platform_bus_create(child, matches, &dev->dev);
156 if (rc) {
157 of_node_put(child);
158 break;
159 }
160 }
161 bail:
162 of_node_put(root);
163 return rc;
164}
165EXPORT_SYMBOL(of_platform_bus_probe);
166 61
167static int of_dev_node_match(struct device *dev, void *data) 62static int of_dev_node_match(struct device *dev, void *data)
168{ 63{
diff --git a/arch/powerpc/include/asm/of_platform.h b/arch/powerpc/include/asm/of_platform.h
index d4aaa3489440..b37d2dcddb97 100644
--- a/arch/powerpc/include/asm/of_platform.h
+++ b/arch/powerpc/include/asm/of_platform.h
@@ -11,17 +11,6 @@
11 * 11 *
12 */ 12 */
13 13
14/* Platform devices and busses creation */
15extern struct of_device *of_platform_device_create(struct device_node *np,
16 const char *bus_id,
17 struct device *parent);
18/* pseudo "matches" value to not do deep probe */
19#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
20
21extern int of_platform_bus_probe(struct device_node *root,
22 const struct of_device_id *matches,
23 struct device *parent);
24
25extern struct of_device *of_find_device_by_phandle(phandle ph); 14extern struct of_device *of_find_device_by_phandle(phandle ph);
26 15
27extern void of_instantiate_rtc(void); 16extern void of_instantiate_rtc(void);
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 487a98851ba6..0b5cc6d892a7 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -40,7 +40,7 @@
40 * a bus type in the list 40 * a bus type in the list
41 */ 41 */
42 42
43static const struct of_device_id of_default_bus_ids[] = { 43const struct of_device_id of_default_bus_ids[] = {
44 { .type = "soc", }, 44 { .type = "soc", },
45 { .compatible = "soc", }, 45 { .compatible = "soc", },
46 { .type = "spider", }, 46 { .type = "spider", },
@@ -64,135 +64,6 @@ static int __init of_bus_driver_init(void)
64 64
65postcore_initcall(of_bus_driver_init); 65postcore_initcall(of_bus_driver_init);
66 66
67struct of_device* of_platform_device_create(struct device_node *np,
68 const char *bus_id,
69 struct device *parent)
70{
71 struct of_device *dev;
72
73 dev = of_device_alloc(np, bus_id, parent);
74 if (!dev)
75 return NULL;
76
77 dev->archdata.dma_mask = 0xffffffffUL;
78 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
79
80 dev->dev.bus = &of_platform_bus_type;
81
82 /* We do not fill the DMA ops for platform devices by default.
83 * This is currently the responsibility of the platform code
84 * to do such, possibly using a device notifier
85 */
86
87 if (of_device_register(dev) != 0) {
88 of_device_free(dev);
89 return NULL;
90 }
91
92 return dev;
93}
94EXPORT_SYMBOL(of_platform_device_create);
95
96
97
98/**
99 * of_platform_bus_create - Create an OF device for a bus node and all its
100 * children. Optionally recursively instanciate matching busses.
101 * @bus: device node of the bus to instanciate
102 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
103 * disallow recursive creation of child busses
104 */
105static int of_platform_bus_create(const struct device_node *bus,
106 const struct of_device_id *matches,
107 struct device *parent)
108{
109 struct device_node *child;
110 struct of_device *dev;
111 int rc = 0;
112
113 for_each_child_of_node(bus, child) {
114 pr_debug(" create child: %s\n", child->full_name);
115 dev = of_platform_device_create(child, NULL, parent);
116 if (dev == NULL)
117 rc = -ENOMEM;
118 else if (!of_match_node(matches, child))
119 continue;
120 if (rc == 0) {
121 pr_debug(" and sub busses\n");
122 rc = of_platform_bus_create(child, matches, &dev->dev);
123 } if (rc) {
124 of_node_put(child);
125 break;
126 }
127 }
128 return rc;
129}
130
131/**
132 * of_platform_bus_probe - Probe the device-tree for platform busses
133 * @root: parent of the first level to probe or NULL for the root of the tree
134 * @matches: match table, NULL to use the default
135 * @parent: parent to hook devices from, NULL for toplevel
136 *
137 * Note that children of the provided root are not instanciated as devices
138 * unless the specified root itself matches the bus list and is not NULL.
139 */
140
141int of_platform_bus_probe(struct device_node *root,
142 const struct of_device_id *matches,
143 struct device *parent)
144{
145 struct device_node *child;
146 struct of_device *dev;
147 int rc = 0;
148
149 if (matches == NULL)
150 matches = of_default_bus_ids;
151 if (matches == OF_NO_DEEP_PROBE)
152 return -EINVAL;
153 if (root == NULL)
154 root = of_find_node_by_path("/");
155 else
156 of_node_get(root);
157
158 pr_debug("of_platform_bus_probe()\n");
159 pr_debug(" starting at: %s\n", root->full_name);
160
161 /* Do a self check of bus type, if there's a match, create
162 * children
163 */
164 if (of_match_node(matches, root)) {
165 pr_debug(" root match, create all sub devices\n");
166 dev = of_platform_device_create(root, NULL, parent);
167 if (dev == NULL) {
168 rc = -ENOMEM;
169 goto bail;
170 }
171 pr_debug(" create all sub busses\n");
172 rc = of_platform_bus_create(root, matches, &dev->dev);
173 goto bail;
174 }
175 for_each_child_of_node(root, child) {
176 if (!of_match_node(matches, child))
177 continue;
178
179 pr_debug(" match: %s\n", child->full_name);
180 dev = of_platform_device_create(child, NULL, parent);
181 if (dev == NULL)
182 rc = -ENOMEM;
183 else
184 rc = of_platform_bus_create(child, matches, &dev->dev);
185 if (rc) {
186 of_node_put(child);
187 break;
188 }
189 }
190 bail:
191 of_node_put(root);
192 return rc;
193}
194EXPORT_SYMBOL(of_platform_bus_probe);
195
196static int of_dev_node_match(struct device *dev, void *data) 67static int of_dev_node_match(struct device *dev, void *data)
197{ 68{
198 return to_of_device(dev)->dev.of_node == data; 69 return to_of_device(dev)->dev.of_node == data;
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 7dacc1ebe91e..d9c81e93bdd0 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -14,6 +14,7 @@
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/dma-mapping.h>
17#include <linux/of_device.h> 18#include <linux/of_device.h>
18#include <linux/of_platform.h> 19#include <linux/of_platform.h>
19 20
@@ -396,3 +397,145 @@ void of_unregister_driver(struct of_platform_driver *drv)
396 driver_unregister(&drv->driver); 397 driver_unregister(&drv->driver);
397} 398}
398EXPORT_SYMBOL(of_unregister_driver); 399EXPORT_SYMBOL(of_unregister_driver);
400
401#if !defined(CONFIG_SPARC)
402/*
403 * The following routines scan a subtree and registers a device for
404 * each applicable node.
405 *
406 * Note: sparc doesn't use these routines because it has a different
407 * mechanism for creating devices from device tree nodes.
408 */
409
410/**
411 * of_platform_device_create - Alloc, initialize and register an of_device
412 * @np: pointer to node to create device for
413 * @bus_id: name to assign device
414 * @parent: Linux device model parent device.
415 */
416struct of_device *of_platform_device_create(struct device_node *np,
417 const char *bus_id,
418 struct device *parent)
419{
420 struct of_device *dev;
421
422 dev = of_device_alloc(np, bus_id, parent);
423 if (!dev)
424 return NULL;
425
426 dev->archdata.dma_mask = 0xffffffffUL;
427 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
428 dev->dev.bus = &of_platform_bus_type;
429
430 /* We do not fill the DMA ops for platform devices by default.
431 * This is currently the responsibility of the platform code
432 * to do such, possibly using a device notifier
433 */
434
435 if (of_device_register(dev) != 0) {
436 of_device_free(dev);
437 return NULL;
438 }
439
440 return dev;
441}
442EXPORT_SYMBOL(of_platform_device_create);
443
444/**
445 * of_platform_bus_create - Create an OF device for a bus node and all its
446 * children. Optionally recursively instantiate matching busses.
447 * @bus: device node of the bus to instantiate
448 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
449 * disallow recursive creation of child busses
450 */
451static int of_platform_bus_create(const struct device_node *bus,
452 const struct of_device_id *matches,
453 struct device *parent)
454{
455 struct device_node *child;
456 struct of_device *dev;
457 int rc = 0;
458
459 for_each_child_of_node(bus, child) {
460 pr_debug(" create child: %s\n", child->full_name);
461 dev = of_platform_device_create(child, NULL, parent);
462 if (dev == NULL)
463 rc = -ENOMEM;
464 else if (!of_match_node(matches, child))
465 continue;
466 if (rc == 0) {
467 pr_debug(" and sub busses\n");
468 rc = of_platform_bus_create(child, matches, &dev->dev);
469 }
470 if (rc) {
471 of_node_put(child);
472 break;
473 }
474 }
475 return rc;
476}
477
478/**
479 * of_platform_bus_probe - Probe the device-tree for platform busses
480 * @root: parent of the first level to probe or NULL for the root of the tree
481 * @matches: match table, NULL to use the default
482 * @parent: parent to hook devices from, NULL for toplevel
483 *
484 * Note that children of the provided root are not instantiated as devices
485 * unless the specified root itself matches the bus list and is not NULL.
486 */
487int of_platform_bus_probe(struct device_node *root,
488 const struct of_device_id *matches,
489 struct device *parent)
490{
491 struct device_node *child;
492 struct of_device *dev;
493 int rc = 0;
494
495 if (matches == NULL)
496 matches = of_default_bus_ids;
497 if (matches == OF_NO_DEEP_PROBE)
498 return -EINVAL;
499 if (root == NULL)
500 root = of_find_node_by_path("/");
501 else
502 of_node_get(root);
503
504 pr_debug("of_platform_bus_probe()\n");
505 pr_debug(" starting at: %s\n", root->full_name);
506
507 /* Do a self check of bus type, if there's a match, create
508 * children
509 */
510 if (of_match_node(matches, root)) {
511 pr_debug(" root match, create all sub devices\n");
512 dev = of_platform_device_create(root, NULL, parent);
513 if (dev == NULL) {
514 rc = -ENOMEM;
515 goto bail;
516 }
517 pr_debug(" create all sub busses\n");
518 rc = of_platform_bus_create(root, matches, &dev->dev);
519 goto bail;
520 }
521 for_each_child_of_node(root, child) {
522 if (!of_match_node(matches, child))
523 continue;
524
525 pr_debug(" match: %s\n", child->full_name);
526 dev = of_platform_device_create(child, NULL, parent);
527 if (dev == NULL)
528 rc = -ENOMEM;
529 else
530 rc = of_platform_bus_create(child, matches, &dev->dev);
531 if (rc) {
532 of_node_put(child);
533 break;
534 }
535 }
536 bail:
537 of_node_put(root);
538 return rc;
539}
540EXPORT_SYMBOL(of_platform_bus_probe);
541#endif /* !CONFIG_SPARC */
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 1643d3761eb4..4bbba41396ef 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -25,6 +25,8 @@
25 */ 25 */
26extern struct bus_type of_platform_bus_type; 26extern struct bus_type of_platform_bus_type;
27 27
28extern const struct of_device_id of_default_bus_ids[];
29
28/* 30/*
29 * An of_platform_driver driver is attached to a basic of_device on 31 * An of_platform_driver driver is attached to a basic of_device on
30 * the "platform bus" (of_platform_bus_type). 32 * the "platform bus" (of_platform_bus_type).
@@ -63,6 +65,21 @@ static inline void of_unregister_platform_driver(struct of_platform_driver *drv)
63extern struct of_device *of_find_device_by_node(struct device_node *np); 65extern struct of_device *of_find_device_by_node(struct device_node *np);
64 66
65extern int of_bus_type_init(struct bus_type *bus, const char *name); 67extern int of_bus_type_init(struct bus_type *bus, const char *name);
68
69#if !defined(CONFIG_SPARC) /* SPARC has its own device registration method */
70/* Platform devices and busses creation */
71extern struct of_device *of_platform_device_create(struct device_node *np,
72 const char *bus_id,
73 struct device *parent);
74
75/* pseudo "matches" value to not do deep probe */
76#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
77
78extern int of_platform_bus_probe(struct device_node *root,
79 const struct of_device_id *matches,
80 struct device *parent);
81#endif /* !CONFIG_SPARC */
82
66#endif /* CONFIG_OF_DEVICE */ 83#endif /* CONFIG_OF_DEVICE */
67 84
68#endif /* _LINUX_OF_PLATFORM_H */ 85#endif /* _LINUX_OF_PLATFORM_H */