aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-11-11 01:24:59 -0500
committerPaul Mackerras <paulus@samba.org>2006-12-04 00:08:52 -0500
commit7eebde700fe6fd6573e80bd8e5ed82b4ae705575 (patch)
tree552f1fd982372a704f2fdf9e4dc59ca9a7caef2a
parent21fb5a1d9f554970c680b801ba32184bc7c34aa0 (diff)
[POWERPC] Souped-up of_platform_device support
This patch first splits of_device.c and of_platform.c, the later containing the bits relative to of_platform_device's. On the "breaks" side of things, drivers uisng of_platform_device(s) need to include asm/of_platform.h now and of_(un)register_driver is now of_(un)register_platform_driver. In addition to a few utility functions to locate of_platform_device(s), the main new addition is of_platform_bus_probe() which allows the platform code to trigger an automatic creation of of_platform_devices for a whole tree of devices. The function acts based on the type of the various "parent" devices encountered from a provided root, using either a default known list of bus types that can be "probed" or a passed-in list. It will only register devices on busses matching that list, which mean that typically, it will not register PCI devices, as expected (since they will be picked up by the PCI layer). This will be used by Cell platforms using 4xx-type IOs in the Axon bridge and can be used by any embedded-type device as well. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/of_device.c172
-rw-r--r--arch/powerpc/kernel/of_platform.c372
-rw-r--r--arch/powerpc/platforms/powermac/setup.c1
-rw-r--r--drivers/macintosh/smu.c3
-rw-r--r--drivers/macintosh/therm_adt746x.c2
-rw-r--r--drivers/macintosh/therm_pm72.c5
-rw-r--r--drivers/macintosh/therm_windtunnel.c7
-rw-r--r--drivers/video/platinumfb.c5
-rw-r--r--include/asm-powerpc/of_device.h34
-rw-r--r--include/asm-powerpc/of_platform.h60
11 files changed, 476 insertions, 187 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index f34d158b9628..04fdbe568d7b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
23obj-$(CONFIG_PPC_970_NAP) += idle_power4.o 23obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
24obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o 24obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o
25procfs-$(CONFIG_PPC64) := proc_ppc64.o 25procfs-$(CONFIG_PPC64) := proc_ppc64.o
26obj-$(CONFIG_PROC_FS) += $(procfs-y) 26obj-$(CONFIG_PROC_FS) += $(procfs-y)
27rtaspci-$(CONFIG_PPC64) := rtas_pci.o 27rtaspci-$(CONFIG_PPC64) := rtas_pci.o
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 397c83eda20e..5c653986afa4 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -9,30 +9,26 @@
9#include <asm/of_device.h> 9#include <asm/of_device.h>
10 10
11/** 11/**
12 * of_match_device - Tell if an of_device structure has a matching 12 * of_match_node - Tell if an device_node has a matching of_match structure
13 * of_match structure
14 * @ids: array of of device match structures to search in 13 * @ids: array of of device match structures to search in
15 * @dev: the of device structure to match against 14 * @node: the of device structure to match against
16 * 15 *
17 * Used by a driver to check whether an of_device present in the 16 * Low level utility function used by device matching.
18 * system is in its list of supported devices.
19 */ 17 */
20const struct of_device_id *of_match_device(const struct of_device_id *matches, 18const struct of_device_id *of_match_node(const struct of_device_id *matches,
21 const struct of_device *dev) 19 const struct device_node *node)
22{ 20{
23 if (!dev->node)
24 return NULL;
25 while (matches->name[0] || matches->type[0] || matches->compatible[0]) { 21 while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
26 int match = 1; 22 int match = 1;
27 if (matches->name[0]) 23 if (matches->name[0])
28 match &= dev->node->name 24 match &= node->name
29 && !strcmp(matches->name, dev->node->name); 25 && !strcmp(matches->name, node->name);
30 if (matches->type[0]) 26 if (matches->type[0])
31 match &= dev->node->type 27 match &= node->type
32 && !strcmp(matches->type, dev->node->type); 28 && !strcmp(matches->type, node->type);
33 if (matches->compatible[0]) 29 if (matches->compatible[0])
34 match &= device_is_compatible(dev->node, 30 match &= device_is_compatible(node,
35 matches->compatible); 31 matches->compatible);
36 if (match) 32 if (match)
37 return matches; 33 return matches;
38 matches++; 34 matches++;
@@ -40,16 +36,21 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches,
40 return NULL; 36 return NULL;
41} 37}
42 38
43static int of_platform_bus_match(struct device *dev, struct device_driver *drv) 39/**
40 * of_match_device - Tell if an of_device structure has a matching
41 * of_match structure
42 * @ids: array of of device match structures to search in
43 * @dev: the of device structure to match against
44 *
45 * Used by a driver to check whether an of_device present in the
46 * system is in its list of supported devices.
47 */
48const struct of_device_id *of_match_device(const struct of_device_id *matches,
49 const struct of_device *dev)
44{ 50{
45 struct of_device * of_dev = to_of_device(dev); 51 if (!dev->node)
46 struct of_platform_driver * of_drv = to_of_platform_driver(drv); 52 return NULL;
47 const struct of_device_id * matches = of_drv->match_table; 53 return of_match_node(matches, dev->node);
48
49 if (!matches)
50 return 0;
51
52 return of_match_device(matches, of_dev) != NULL;
53} 54}
54 55
55struct of_device *of_dev_get(struct of_device *dev) 56struct of_device *of_dev_get(struct of_device *dev)
@@ -71,96 +72,8 @@ void of_dev_put(struct of_device *dev)
71 put_device(&dev->dev); 72 put_device(&dev->dev);
72} 73}
73 74
74 75static ssize_t dev_show_devspec(struct device *dev,
75static int of_device_probe(struct device *dev) 76 struct device_attribute *attr, char *buf)
76{
77 int error = -ENODEV;
78 struct of_platform_driver *drv;
79 struct of_device *of_dev;
80 const struct of_device_id *match;
81
82 drv = to_of_platform_driver(dev->driver);
83 of_dev = to_of_device(dev);
84
85 if (!drv->probe)
86 return error;
87
88 of_dev_get(of_dev);
89
90 match = of_match_device(drv->match_table, of_dev);
91 if (match)
92 error = drv->probe(of_dev, match);
93 if (error)
94 of_dev_put(of_dev);
95
96 return error;
97}
98
99static int of_device_remove(struct device *dev)
100{
101 struct of_device * of_dev = to_of_device(dev);
102 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
103
104 if (dev->driver && drv->remove)
105 drv->remove(of_dev);
106 return 0;
107}
108
109static int of_device_suspend(struct device *dev, pm_message_t state)
110{
111 struct of_device * of_dev = to_of_device(dev);
112 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
113 int error = 0;
114
115 if (dev->driver && drv->suspend)
116 error = drv->suspend(of_dev, state);
117 return error;
118}
119
120static int of_device_resume(struct device * dev)
121{
122 struct of_device * of_dev = to_of_device(dev);
123 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
124 int error = 0;
125
126 if (dev->driver && drv->resume)
127 error = drv->resume(of_dev);
128 return error;
129}
130
131struct bus_type of_platform_bus_type = {
132 .name = "of_platform",
133 .match = of_platform_bus_match,
134 .probe = of_device_probe,
135 .remove = of_device_remove,
136 .suspend = of_device_suspend,
137 .resume = of_device_resume,
138};
139
140static int __init of_bus_driver_init(void)
141{
142 return bus_register(&of_platform_bus_type);
143}
144
145postcore_initcall(of_bus_driver_init);
146
147int of_register_driver(struct of_platform_driver *drv)
148{
149 /* initialize common driver fields */
150 drv->driver.name = drv->name;
151 drv->driver.bus = &of_platform_bus_type;
152
153 /* register with core */
154 return driver_register(&drv->driver);
155}
156
157void of_unregister_driver(struct of_platform_driver *drv)
158{
159 driver_unregister(&drv->driver);
160}
161
162
163static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
164{ 77{
165 struct of_device *ofdev; 78 struct of_device *ofdev;
166 79
@@ -208,41 +121,10 @@ void of_device_unregister(struct of_device *ofdev)
208 device_unregister(&ofdev->dev); 121 device_unregister(&ofdev->dev);
209} 122}
210 123
211struct of_device* of_platform_device_create(struct device_node *np,
212 const char *bus_id,
213 struct device *parent)
214{
215 struct of_device *dev;
216
217 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
218 if (!dev)
219 return NULL;
220 memset(dev, 0, sizeof(*dev));
221
222 dev->node = of_node_get(np);
223 dev->dma_mask = 0xffffffffUL;
224 dev->dev.dma_mask = &dev->dma_mask;
225 dev->dev.parent = parent;
226 dev->dev.bus = &of_platform_bus_type;
227 dev->dev.release = of_release_dev;
228
229 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
230
231 if (of_device_register(dev) != 0) {
232 kfree(dev);
233 return NULL;
234 }
235
236 return dev;
237}
238 124
239EXPORT_SYMBOL(of_match_device); 125EXPORT_SYMBOL(of_match_device);
240EXPORT_SYMBOL(of_platform_bus_type);
241EXPORT_SYMBOL(of_register_driver);
242EXPORT_SYMBOL(of_unregister_driver);
243EXPORT_SYMBOL(of_device_register); 126EXPORT_SYMBOL(of_device_register);
244EXPORT_SYMBOL(of_device_unregister); 127EXPORT_SYMBOL(of_device_unregister);
245EXPORT_SYMBOL(of_dev_get); 128EXPORT_SYMBOL(of_dev_get);
246EXPORT_SYMBOL(of_dev_put); 129EXPORT_SYMBOL(of_dev_put);
247EXPORT_SYMBOL(of_platform_device_create);
248EXPORT_SYMBOL(of_release_dev); 130EXPORT_SYMBOL(of_release_dev);
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
new file mode 100644
index 000000000000..25850ade8e68
--- /dev/null
+++ b/arch/powerpc/kernel/of_platform.c
@@ -0,0 +1,372 @@
1/*
2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 */
11
12#undef DEBUG
13
14#include <linux/string.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/mod_devicetable.h>
19#include <linux/slab.h>
20
21#include <asm/errno.h>
22#include <asm/dcr.h>
23#include <asm/of_device.h>
24#include <asm/of_platform.h>
25
26
27/*
28 * The list of OF IDs below is used for matching bus types in the
29 * system whose devices are to be exposed as of_platform_devices.
30 *
31 * This is the default list valid for most platforms. This file provides
32 * functions who can take an explicit list if necessary though
33 *
34 * The search is always performed recursively looking for children of
35 * the provided device_node and recursively if such a children matches
36 * a bus type in the list
37 */
38
39static struct of_device_id of_default_bus_ids[] = {
40 { .type = "soc", },
41 { .compatible = "soc", },
42 { .type = "spider", },
43 { .type = "axon", },
44 { .type = "plb5", },
45 { .type = "plb4", },
46 { .type = "opb", },
47 {},
48};
49
50/*
51 *
52 * OF platform device type definition & base infrastructure
53 *
54 */
55
56static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
57{
58 struct of_device * of_dev = to_of_device(dev);
59 struct of_platform_driver * of_drv = to_of_platform_driver(drv);
60 const struct of_device_id * matches = of_drv->match_table;
61
62 if (!matches)
63 return 0;
64
65 return of_match_device(matches, of_dev) != NULL;
66}
67
68static int of_platform_device_probe(struct device *dev)
69{
70 int error = -ENODEV;
71 struct of_platform_driver *drv;
72 struct of_device *of_dev;
73 const struct of_device_id *match;
74
75 drv = to_of_platform_driver(dev->driver);
76 of_dev = to_of_device(dev);
77
78 if (!drv->probe)
79 return error;
80
81 of_dev_get(of_dev);
82
83 match = of_match_device(drv->match_table, of_dev);
84 if (match)
85 error = drv->probe(of_dev, match);
86 if (error)
87 of_dev_put(of_dev);
88
89 return error;
90}
91
92static int of_platform_device_remove(struct device *dev)
93{
94 struct of_device * of_dev = to_of_device(dev);
95 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
96
97 if (dev->driver && drv->remove)
98 drv->remove(of_dev);
99 return 0;
100}
101
102static int of_platform_device_suspend(struct device *dev, pm_message_t state)
103{
104 struct of_device * of_dev = to_of_device(dev);
105 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
106 int error = 0;
107
108 if (dev->driver && drv->suspend)
109 error = drv->suspend(of_dev, state);
110 return error;
111}
112
113static int of_platform_device_resume(struct device * dev)
114{
115 struct of_device * of_dev = to_of_device(dev);
116 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
117 int error = 0;
118
119 if (dev->driver && drv->resume)
120 error = drv->resume(of_dev);
121 return error;
122}
123
124struct bus_type of_platform_bus_type = {
125 .name = "of_platform",
126 .match = of_platform_bus_match,
127 .probe = of_platform_device_probe,
128 .remove = of_platform_device_remove,
129 .suspend = of_platform_device_suspend,
130 .resume = of_platform_device_resume,
131};
132EXPORT_SYMBOL(of_platform_bus_type);
133
134static int __init of_bus_driver_init(void)
135{
136 return bus_register(&of_platform_bus_type);
137}
138
139postcore_initcall(of_bus_driver_init);
140
141int of_register_platform_driver(struct of_platform_driver *drv)
142{
143 /* initialize common driver fields */
144 drv->driver.name = drv->name;
145 drv->driver.bus = &of_platform_bus_type;
146
147 /* register with core */
148 return driver_register(&drv->driver);
149}
150EXPORT_SYMBOL(of_register_platform_driver);
151
152void of_unregister_platform_driver(struct of_platform_driver *drv)
153{
154 driver_unregister(&drv->driver);
155}
156EXPORT_SYMBOL(of_unregister_platform_driver);
157
158static void of_platform_make_bus_id(struct of_device *dev)
159{
160 struct device_node *node = dev->node;
161 char *name = dev->dev.bus_id;
162 const u32 *reg;
163 u64 addr;
164
165 /*
166 * If it's a DCR based device, use 'd' for native DCRs
167 * and 'D' for MMIO DCRs.
168 */
169#ifdef CONFIG_PPC_DCR
170 reg = get_property(node, "dcr-reg", NULL);
171 if (reg) {
172#ifdef CONFIG_PPC_DCR_NATIVE
173 snprintf(name, BUS_ID_SIZE, "d%x.%s",
174 *reg, node->name);
175#else /* CONFIG_PPC_DCR_NATIVE */
176 addr = of_translate_dcr_address(node, *reg, NULL);
177 if (addr != OF_BAD_ADDR) {
178 snprintf(name, BUS_ID_SIZE,
179 "D%llx.%s", (unsigned long long)addr,
180 node->name);
181 return;
182 }
183#endif /* !CONFIG_PPC_DCR_NATIVE */
184 }
185#endif /* CONFIG_PPC_DCR */
186
187 /*
188 * For MMIO, get the physical address
189 */
190 reg = get_property(node, "reg", NULL);
191 if (reg) {
192 addr = of_translate_address(node, reg);
193 if (addr != OF_BAD_ADDR) {
194 snprintf(name, BUS_ID_SIZE,
195 "%llx.%s", (unsigned long long)addr,
196 node->name);
197 return;
198 }
199 }
200
201 /*
202 * No BusID, use the node name and pray
203 */
204 snprintf(name, BUS_ID_SIZE, "%s", node->name);
205}
206
207struct of_device* of_platform_device_create(struct device_node *np,
208 const char *bus_id,
209 struct device *parent)
210{
211 struct of_device *dev;
212
213 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
214 if (!dev)
215 return NULL;
216 memset(dev, 0, sizeof(*dev));
217
218 dev->node = of_node_get(np);
219 dev->dma_mask = 0xffffffffUL;
220 dev->dev.dma_mask = &dev->dma_mask;
221 dev->dev.parent = parent;
222 dev->dev.bus = &of_platform_bus_type;
223 dev->dev.release = of_release_dev;
224
225 if (bus_id)
226 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
227 else
228 of_platform_make_bus_id(dev);
229
230 if (of_device_register(dev) != 0) {
231 kfree(dev);
232 return NULL;
233 }
234
235 return dev;
236}
237EXPORT_SYMBOL(of_platform_device_create);
238
239
240
241/**
242 * of_platform_bus_create - Create an OF device for a bus node and all its
243 * children. Optionally recursively instanciate matching busses.
244 * @bus: device node of the bus to instanciate
245 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
246 * disallow recursive creation of child busses
247 */
248static int of_platform_bus_create(struct device_node *bus,
249 struct of_device_id *matches,
250 struct device *parent)
251{
252 struct device_node *child;
253 struct of_device *dev;
254 int rc = 0;
255
256 for (child = NULL; (child = of_get_next_child(bus, child)); ) {
257 pr_debug(" create child: %s\n", child->full_name);
258 dev = of_platform_device_create(child, NULL, parent);
259 if (dev == NULL)
260 rc = -ENOMEM;
261 else if (!of_match_node(matches, child))
262 continue;
263 if (rc == 0) {
264 pr_debug(" and sub busses\n");
265 rc = of_platform_bus_create(child, matches, &dev->dev);
266 } if (rc) {
267 of_node_put(child);
268 break;
269 }
270 }
271 return rc;
272}
273
274/**
275 * of_platform_bus_probe - Probe the device-tree for platform busses
276 * @root: parent of the first level to probe or NULL for the root of the tree
277 * @matches: match table, NULL to use the default
278 * @parent: parent to hook devices from, NULL for toplevel
279 *
280 * Note that children of the provided root are not instanciated as devices
281 * unless the specified root itself matches the bus list and is not NULL.
282 */
283
284int of_platform_bus_probe(struct device_node *root,
285 struct of_device_id *matches,
286 struct device *parent)
287{
288 struct device_node *child;
289 struct of_device *dev;
290 int rc = 0;
291
292 if (matches == NULL)
293 matches = of_default_bus_ids;
294 if (matches == OF_NO_DEEP_PROBE)
295 return -EINVAL;
296 if (root == NULL)
297 root = of_find_node_by_path("/");
298 else
299 of_node_get(root);
300
301 pr_debug("of_platform_bus_probe()\n");
302 pr_debug(" starting at: %s\n", root->full_name);
303
304 /* Do a self check of bus type, if there's a match, create
305 * children
306 */
307 if (of_match_node(matches, root)) {
308 pr_debug(" root match, create all sub devices\n");
309 dev = of_platform_device_create(root, NULL, parent);
310 if (dev == NULL) {
311 rc = -ENOMEM;
312 goto bail;
313 }
314 pr_debug(" create all sub busses\n");
315 rc = of_platform_bus_create(root, matches, &dev->dev);
316 goto bail;
317 }
318 for (child = NULL; (child = of_get_next_child(root, child)); ) {
319 if (!of_match_node(matches, child))
320 continue;
321
322 pr_debug(" match: %s\n", child->full_name);
323 dev = of_platform_device_create(child, NULL, parent);
324 if (dev == NULL)
325 rc = -ENOMEM;
326 else
327 rc = of_platform_bus_create(child, matches, &dev->dev);
328 if (rc) {
329 of_node_put(child);
330 break;
331 }
332 }
333 bail:
334 of_node_put(root);
335 return rc;
336}
337EXPORT_SYMBOL(of_platform_bus_probe);
338
339static int of_dev_node_match(struct device *dev, void *data)
340{
341 return to_of_device(dev)->node == data;
342}
343
344struct of_device *of_find_device_by_node(struct device_node *np)
345{
346 struct device *dev;
347
348 dev = bus_find_device(&of_platform_bus_type,
349 NULL, np, of_dev_node_match);
350 if (dev)
351 return to_of_device(dev);
352 return NULL;
353}
354EXPORT_SYMBOL(of_find_device_by_node);
355
356static int of_dev_phandle_match(struct device *dev, void *data)
357{
358 phandle *ph = data;
359 return to_of_device(dev)->node->linux_phandle == *ph;
360}
361
362struct of_device *of_find_device_by_phandle(phandle ph)
363{
364 struct device *dev;
365
366 dev = bus_find_device(&of_platform_bus_type,
367 NULL, &ph, of_dev_phandle_match);
368 if (dev)
369 return to_of_device(dev);
370 return NULL;
371}
372EXPORT_SYMBOL(of_find_device_by_phandle);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 805791d76fdf..4ec6a5a65f30 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -70,6 +70,7 @@
70#include <asm/pmac_feature.h> 70#include <asm/pmac_feature.h>
71#include <asm/time.h> 71#include <asm/time.h>
72#include <asm/of_device.h> 72#include <asm/of_device.h>
73#include <asm/of_platform.h>
73#include <asm/mmu_context.h> 74#include <asm/mmu_context.h>
74#include <asm/iommu.h> 75#include <asm/iommu.h>
75#include <asm/smu.h> 76#include <asm/smu.h>
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index ade25b3fbb35..4f724cdd2efa 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -46,6 +46,7 @@
46#include <asm/abs_addr.h> 46#include <asm/abs_addr.h>
47#include <asm/uaccess.h> 47#include <asm/uaccess.h>
48#include <asm/of_device.h> 48#include <asm/of_device.h>
49#include <asm/of_platform.h>
49 50
50#define VERSION "0.7" 51#define VERSION "0.7"
51#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." 52#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp."
@@ -653,7 +654,7 @@ static int __init smu_init_sysfs(void)
653 * I'm a bit too far from figuring out how that works with those 654 * I'm a bit too far from figuring out how that works with those
654 * new chipsets, but that will come back and bite us 655 * new chipsets, but that will come back and bite us
655 */ 656 */
656 of_register_driver(&smu_of_platform_driver); 657 of_register_platform_driver(&smu_of_platform_driver);
657 return 0; 658 return 0;
658} 659}
659 660
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index a0f30d0853ea..13b953ae8ebc 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -30,7 +30,7 @@
30#include <asm/io.h> 30#include <asm/io.h>
31#include <asm/system.h> 31#include <asm/system.h>
32#include <asm/sections.h> 32#include <asm/sections.h>
33#include <asm/of_device.h> 33#include <asm/of_platform.h>
34 34
35#undef DEBUG 35#undef DEBUG
36 36
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index d00c0c37a12e..2e4ad44a8636 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -129,6 +129,7 @@
129#include <asm/sections.h> 129#include <asm/sections.h>
130#include <asm/of_device.h> 130#include <asm/of_device.h>
131#include <asm/macio.h> 131#include <asm/macio.h>
132#include <asm/of_platform.h>
132 133
133#include "therm_pm72.h" 134#include "therm_pm72.h"
134 135
@@ -2236,14 +2237,14 @@ static int __init therm_pm72_init(void)
2236 return -ENODEV; 2237 return -ENODEV;
2237 } 2238 }
2238 2239
2239 of_register_driver(&fcu_of_platform_driver); 2240 of_register_platform_driver(&fcu_of_platform_driver);
2240 2241
2241 return 0; 2242 return 0;
2242} 2243}
2243 2244
2244static void __exit therm_pm72_exit(void) 2245static void __exit therm_pm72_exit(void)
2245{ 2246{
2246 of_unregister_driver(&fcu_of_platform_driver); 2247 of_unregister_platform_driver(&fcu_of_platform_driver);
2247 2248
2248 if (of_dev) 2249 if (of_dev)
2249 of_device_unregister(of_dev); 2250 of_device_unregister(of_dev);
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 738faab1b22c..a1d3a987cb3a 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -36,12 +36,13 @@
36#include <linux/i2c.h> 36#include <linux/i2c.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/init.h> 38#include <linux/init.h>
39
39#include <asm/prom.h> 40#include <asm/prom.h>
40#include <asm/machdep.h> 41#include <asm/machdep.h>
41#include <asm/io.h> 42#include <asm/io.h>
42#include <asm/system.h> 43#include <asm/system.h>
43#include <asm/sections.h> 44#include <asm/sections.h>
44#include <asm/of_device.h> 45#include <asm/of_platform.h>
45#include <asm/macio.h> 46#include <asm/macio.h>
46 47
47#define LOG_TEMP 0 /* continously log temperature */ 48#define LOG_TEMP 0 /* continously log temperature */
@@ -511,14 +512,14 @@ g4fan_init( void )
511 return -ENODEV; 512 return -ENODEV;
512 } 513 }
513 514
514 of_register_driver( &therm_of_driver ); 515 of_register_platform_driver( &therm_of_driver );
515 return 0; 516 return 0;
516} 517}
517 518
518static void __exit 519static void __exit
519g4fan_exit( void ) 520g4fan_exit( void )
520{ 521{
521 of_unregister_driver( &therm_of_driver ); 522 of_unregister_platform_driver( &therm_of_driver );
522 523
523 if( x.of_dev ) 524 if( x.of_dev )
524 of_device_unregister( x.of_dev ); 525 of_device_unregister( x.of_dev );
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index fdb33cd21a27..cb26c6df0583 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -34,6 +34,7 @@
34#include <asm/prom.h> 34#include <asm/prom.h>
35#include <asm/pgtable.h> 35#include <asm/pgtable.h>
36#include <asm/of_device.h> 36#include <asm/of_device.h>
37#include <asm/of_platform.h>
37 38
38#include "macmodes.h" 39#include "macmodes.h"
39#include "platinumfb.h" 40#include "platinumfb.h"
@@ -682,14 +683,14 @@ static int __init platinumfb_init(void)
682 return -ENODEV; 683 return -ENODEV;
683 platinumfb_setup(option); 684 platinumfb_setup(option);
684#endif 685#endif
685 of_register_driver(&platinum_driver); 686 of_register_platform_driver(&platinum_driver);
686 687
687 return 0; 688 return 0;
688} 689}
689 690
690static void __exit platinumfb_exit(void) 691static void __exit platinumfb_exit(void)
691{ 692{
692 of_unregister_driver(&platinum_driver); 693 of_unregister_platform_driver(&platinum_driver);
693} 694}
694 695
695MODULE_LICENSE("GPL"); 696MODULE_LICENSE("GPL");
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index c5c0b0b3cd52..1ef7e9edd1a7 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -6,12 +6,6 @@
6#include <linux/mod_devicetable.h> 6#include <linux/mod_devicetable.h>
7#include <asm/prom.h> 7#include <asm/prom.h>
8 8
9/*
10 * The of_platform_bus_type is a bus type used by drivers that do not
11 * attach to a macio or similar bus but still use OF probing
12 * mechanism
13 */
14extern struct bus_type of_platform_bus_type;
15 9
16/* 10/*
17 * The of_device is a kind of "base class" that is a superset of 11 * The of_device is a kind of "base class" that is a superset of
@@ -26,40 +20,16 @@ struct of_device
26}; 20};
27#define to_of_device(d) container_of(d, struct of_device, dev) 21#define to_of_device(d) container_of(d, struct of_device, dev)
28 22
23extern const struct of_device_id *of_match_node(
24 const struct of_device_id *matches, const struct device_node *node);
29extern const struct of_device_id *of_match_device( 25extern const struct of_device_id *of_match_device(
30 const struct of_device_id *matches, const struct of_device *dev); 26 const struct of_device_id *matches, const struct of_device *dev);
31 27
32extern struct of_device *of_dev_get(struct of_device *dev); 28extern struct of_device *of_dev_get(struct of_device *dev);
33extern void of_dev_put(struct of_device *dev); 29extern void of_dev_put(struct of_device *dev);
34 30
35/*
36 * An of_platform_driver driver is attached to a basic of_device on
37 * the "platform bus" (of_platform_bus_type)
38 */
39struct of_platform_driver
40{
41 char *name;
42 struct of_device_id *match_table;
43 struct module *owner;
44
45 int (*probe)(struct of_device* dev, const struct of_device_id *match);
46 int (*remove)(struct of_device* dev);
47
48 int (*suspend)(struct of_device* dev, pm_message_t state);
49 int (*resume)(struct of_device* dev);
50 int (*shutdown)(struct of_device* dev);
51
52 struct device_driver driver;
53};
54#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
55
56extern int of_register_driver(struct of_platform_driver *drv);
57extern void of_unregister_driver(struct of_platform_driver *drv);
58extern int of_device_register(struct of_device *ofdev); 31extern int of_device_register(struct of_device *ofdev);
59extern void of_device_unregister(struct of_device *ofdev); 32extern void of_device_unregister(struct of_device *ofdev);
60extern struct of_device *of_platform_device_create(struct device_node *np,
61 const char *bus_id,
62 struct device *parent);
63extern void of_release_dev(struct device *dev); 33extern void of_release_dev(struct device *dev);
64 34
65#endif /* __KERNEL__ */ 35#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/of_platform.h b/include/asm-powerpc/of_platform.h
new file mode 100644
index 000000000000..217eafb167e9
--- /dev/null
+++ b/include/asm-powerpc/of_platform.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 */
11
12#include <asm/of_device.h>
13
14/*
15 * The of_platform_bus_type is a bus type used by drivers that do not
16 * attach to a macio or similar bus but still use OF probing
17 * mechanism
18 */
19extern struct bus_type of_platform_bus_type;
20
21/*
22 * An of_platform_driver driver is attached to a basic of_device on
23 * the "platform bus" (of_platform_bus_type)
24 */
25struct of_platform_driver
26{
27 char *name;
28 struct of_device_id *match_table;
29 struct module *owner;
30
31 int (*probe)(struct of_device* dev,
32 const struct of_device_id *match);
33 int (*remove)(struct of_device* dev);
34
35 int (*suspend)(struct of_device* dev, pm_message_t state);
36 int (*resume)(struct of_device* dev);
37 int (*shutdown)(struct of_device* dev);
38
39 struct device_driver driver;
40};
41#define to_of_platform_driver(drv) \
42 container_of(drv,struct of_platform_driver, driver)
43
44/* Platform drivers register/unregister */
45extern int of_register_platform_driver(struct of_platform_driver *drv);
46extern void of_unregister_platform_driver(struct of_platform_driver *drv);
47
48/* Platform devices and busses creation */
49extern struct of_device *of_platform_device_create(struct device_node *np,
50 const char *bus_id,
51 struct device *parent);
52/* pseudo "matches" value to not do deep probe */
53#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
54
55extern int of_platform_bus_probe(struct device_node *root,
56 struct of_device_id *matches,
57 struct device *parent);
58
59extern struct of_device *of_find_device_by_node(struct device_node *np);
60extern struct of_device *of_find_device_by_phandle(phandle ph);