diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-06-08 09:48:13 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-07-05 18:14:28 -0400 |
commit | 5fd200f3b351183b5489cef69961c60af9cead2f (patch) | |
tree | 322780d69cfefd88dd959e2b60aa23ce28cc8d2c /arch | |
parent | 34a1c1e8c700f7cd849deb21193718a172722f8d (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
Diffstat (limited to 'arch')
-rw-r--r-- | arch/microblaze/include/asm/of_platform.h | 33 | ||||
-rw-r--r-- | arch/microblaze/kernel/of_platform.c | 141 | ||||
-rw-r--r-- | arch/powerpc/include/asm/of_platform.h | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/of_platform.c | 131 |
4 files changed, 19 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 | |||
29 | static 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 */ | ||
40 | extern 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 | |||
46 | extern int of_platform_bus_probe(struct device_node *root, | ||
47 | const struct of_device_id *matches, | ||
48 | struct device *parent); | ||
49 | |||
50 | extern struct of_device *of_find_device_by_phandle(phandle ph); | 17 | extern struct of_device *of_find_device_by_phandle(phandle ph); |
51 | 18 | ||
52 | extern void of_instantiate_rtc(void); | 19 | extern 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 | } |
38 | postcore_initcall(of_bus_driver_init); | 38 | postcore_initcall(of_bus_driver_init); |
39 | 39 | ||
40 | struct 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 | } | ||
65 | EXPORT_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 | */ | ||
74 | static 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 | ||
112 | int of_platform_bus_probe(struct device_node *root, | 52 | const 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 | } | ||
165 | EXPORT_SYMBOL(of_platform_bus_probe); | ||
166 | 61 | ||
167 | static int of_dev_node_match(struct device *dev, void *data) | 62 | static 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 */ | ||
15 | extern 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 | |||
21 | extern int of_platform_bus_probe(struct device_node *root, | ||
22 | const struct of_device_id *matches, | ||
23 | struct device *parent); | ||
24 | |||
25 | extern struct of_device *of_find_device_by_phandle(phandle ph); | 14 | extern struct of_device *of_find_device_by_phandle(phandle ph); |
26 | 15 | ||
27 | extern void of_instantiate_rtc(void); | 16 | extern 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 | ||
43 | static const struct of_device_id of_default_bus_ids[] = { | 43 | const 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 | ||
65 | postcore_initcall(of_bus_driver_init); | 65 | postcore_initcall(of_bus_driver_init); |
66 | 66 | ||
67 | struct 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 | } | ||
94 | EXPORT_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 | */ | ||
105 | static 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 | |||
141 | int 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 | } | ||
194 | EXPORT_SYMBOL(of_platform_bus_probe); | ||
195 | |||
196 | static int of_dev_node_match(struct device *dev, void *data) | 67 | static 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; |