diff options
Diffstat (limited to 'arch/powerpc/kernel/ibmebus.c')
-rw-r--r-- | arch/powerpc/kernel/ibmebus.c | 199 |
1 files changed, 6 insertions, 193 deletions
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 2e16ca5778a3..af21306e2ef9 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/kobject.h> | 41 | #include <linux/kobject.h> |
42 | #include <linux/dma-mapping.h> | 42 | #include <linux/dma-mapping.h> |
43 | #include <linux/interrupt.h> | 43 | #include <linux/interrupt.h> |
44 | #include <linux/of_platform.h> | ||
44 | #include <asm/ibmebus.h> | 45 | #include <asm/ibmebus.h> |
45 | #include <asm/abs_addr.h> | 46 | #include <asm/abs_addr.h> |
46 | 47 | ||
@@ -124,183 +125,14 @@ static struct dma_mapping_ops ibmebus_dma_ops = { | |||
124 | .dma_supported = ibmebus_dma_supported, | 125 | .dma_supported = ibmebus_dma_supported, |
125 | }; | 126 | }; |
126 | 127 | ||
127 | static int ibmebus_bus_probe(struct device *dev) | ||
128 | { | ||
129 | struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev); | ||
130 | struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver); | ||
131 | const struct of_device_id *id; | ||
132 | int error = -ENODEV; | ||
133 | |||
134 | if (!ibmebusdrv->probe) | ||
135 | return error; | ||
136 | |||
137 | id = of_match_device(ibmebusdrv->id_table, &ibmebusdev->ofdev); | ||
138 | if (id) { | ||
139 | error = ibmebusdrv->probe(ibmebusdev, id); | ||
140 | } | ||
141 | |||
142 | return error; | ||
143 | } | ||
144 | |||
145 | static int ibmebus_bus_remove(struct device *dev) | ||
146 | { | ||
147 | struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev); | ||
148 | struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver); | ||
149 | |||
150 | if (ibmebusdrv->remove) { | ||
151 | return ibmebusdrv->remove(ibmebusdev); | ||
152 | } | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static void __devinit ibmebus_dev_release(struct device *dev) | ||
158 | { | ||
159 | of_node_put(to_ibmebus_dev(dev)->ofdev.node); | ||
160 | kfree(to_ibmebus_dev(dev)); | ||
161 | } | ||
162 | |||
163 | static int __devinit ibmebus_register_device_common( | ||
164 | struct ibmebus_dev *dev, const char *name) | ||
165 | { | ||
166 | int err = 0; | ||
167 | |||
168 | dev->ofdev.dev.parent = &ibmebus_bus_device; | ||
169 | dev->ofdev.dev.bus = &ibmebus_bus_type; | ||
170 | dev->ofdev.dev.release = ibmebus_dev_release; | ||
171 | |||
172 | dev->ofdev.dev.archdata.of_node = dev->ofdev.node; | ||
173 | dev->ofdev.dev.archdata.dma_ops = &ibmebus_dma_ops; | ||
174 | dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node); | ||
175 | |||
176 | /* An ibmebusdev is based on a of_device. We have to change the | ||
177 | * bus type to use our own DMA mapping operations. | ||
178 | */ | ||
179 | if ((err = of_device_register(&dev->ofdev)) != 0) { | ||
180 | printk(KERN_ERR "%s: failed to register device (%d).\n", | ||
181 | __FUNCTION__, err); | ||
182 | return -ENODEV; | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static struct ibmebus_dev* __devinit ibmebus_register_device_node( | ||
189 | struct device_node *dn) | ||
190 | { | ||
191 | struct ibmebus_dev *dev; | ||
192 | int i, len, bus_len; | ||
193 | |||
194 | dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); | ||
195 | if (!dev) | ||
196 | return ERR_PTR(-ENOMEM); | ||
197 | |||
198 | dev->ofdev.node = of_node_get(dn); | ||
199 | |||
200 | len = strlen(dn->full_name + 1); | ||
201 | bus_len = min(len, BUS_ID_SIZE - 1); | ||
202 | memcpy(dev->ofdev.dev.bus_id, dn->full_name + 1 | ||
203 | + (len - bus_len), bus_len); | ||
204 | for (i = 0; i < bus_len; i++) | ||
205 | if (dev->ofdev.dev.bus_id[i] == '/') | ||
206 | dev->ofdev.dev.bus_id[i] = '_'; | ||
207 | |||
208 | /* Register with generic device framework. */ | ||
209 | if (ibmebus_register_device_common(dev, dn->name) != 0) { | ||
210 | kfree(dev); | ||
211 | return ERR_PTR(-ENODEV); | ||
212 | } | ||
213 | |||
214 | return dev; | ||
215 | } | ||
216 | |||
217 | static void ibmebus_probe_of_nodes(char* name) | ||
218 | { | ||
219 | struct device_node *dn = NULL; | ||
220 | |||
221 | while ((dn = of_find_node_by_name(dn, name))) { | ||
222 | if (IS_ERR(ibmebus_register_device_node(dn))) { | ||
223 | of_node_put(dn); | ||
224 | return; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | of_node_put(dn); | ||
229 | |||
230 | return; | ||
231 | } | ||
232 | |||
233 | static void ibmebus_add_devices_by_id(struct of_device_id *idt) | ||
234 | { | ||
235 | while (strlen(idt->name) > 0) { | ||
236 | ibmebus_probe_of_nodes(idt->name); | ||
237 | idt++; | ||
238 | } | ||
239 | |||
240 | return; | ||
241 | } | ||
242 | |||
243 | static int ibmebus_match_name(struct device *dev, void *data) | ||
244 | { | ||
245 | const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev); | ||
246 | const char *name; | ||
247 | |||
248 | name = of_get_property(ebus_dev->ofdev.node, "name", NULL); | ||
249 | |||
250 | if (name && (strcmp(data, name) == 0)) | ||
251 | return 1; | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int ibmebus_unregister_device(struct device *dev) | ||
257 | { | ||
258 | of_device_unregister(to_of_device(dev)); | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static void ibmebus_remove_devices_by_id(struct of_device_id *idt) | ||
264 | { | ||
265 | struct device *dev; | ||
266 | |||
267 | while (strlen(idt->name) > 0) { | ||
268 | while ((dev = bus_find_device(&ibmebus_bus_type, NULL, | ||
269 | (void*)idt->name, | ||
270 | ibmebus_match_name))) { | ||
271 | ibmebus_unregister_device(dev); | ||
272 | } | ||
273 | idt++; | ||
274 | } | ||
275 | |||
276 | return; | ||
277 | } | ||
278 | |||
279 | int ibmebus_register_driver(struct ibmebus_driver *drv) | 128 | int ibmebus_register_driver(struct ibmebus_driver *drv) |
280 | { | 129 | { |
281 | int err = 0; | ||
282 | |||
283 | drv->driver.name = drv->name; | ||
284 | drv->driver.bus = &ibmebus_bus_type; | ||
285 | drv->driver.probe = ibmebus_bus_probe; | ||
286 | drv->driver.remove = ibmebus_bus_remove; | ||
287 | |||
288 | if ((err = driver_register(&drv->driver) != 0)) | ||
289 | return err; | ||
290 | |||
291 | /* remove all supported devices first, in case someone | ||
292 | * probed them manually before registering the driver */ | ||
293 | ibmebus_remove_devices_by_id(drv->id_table); | ||
294 | ibmebus_add_devices_by_id(drv->id_table); | ||
295 | |||
296 | return 0; | 130 | return 0; |
297 | } | 131 | } |
298 | EXPORT_SYMBOL(ibmebus_register_driver); | 132 | EXPORT_SYMBOL(ibmebus_register_driver); |
299 | 133 | ||
300 | void ibmebus_unregister_driver(struct ibmebus_driver *drv) | 134 | void ibmebus_unregister_driver(struct ibmebus_driver *drv) |
301 | { | 135 | { |
302 | driver_unregister(&drv->driver); | ||
303 | ibmebus_remove_devices_by_id(drv->id_table); | ||
304 | } | 136 | } |
305 | EXPORT_SYMBOL(ibmebus_unregister_driver); | 137 | EXPORT_SYMBOL(ibmebus_unregister_driver); |
306 | 138 | ||
@@ -328,23 +160,6 @@ void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id) | |||
328 | } | 160 | } |
329 | EXPORT_SYMBOL(ibmebus_free_irq); | 161 | EXPORT_SYMBOL(ibmebus_free_irq); |
330 | 162 | ||
331 | static int ibmebus_bus_match(struct device *dev, struct device_driver *drv) | ||
332 | { | ||
333 | const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev); | ||
334 | struct ibmebus_driver *ebus_drv = to_ibmebus_driver(drv); | ||
335 | const struct of_device_id *ids = ebus_drv->id_table; | ||
336 | const struct of_device_id *found_id; | ||
337 | |||
338 | if (!ids) | ||
339 | return 0; | ||
340 | |||
341 | found_id = of_match_device(ids, &ebus_dev->ofdev); | ||
342 | if (found_id) | ||
343 | return 1; | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static ssize_t name_show(struct device *dev, | 163 | static ssize_t name_show(struct device *dev, |
349 | struct device_attribute *attr, char *buf) | 164 | struct device_attribute *attr, char *buf) |
350 | { | 165 | { |
@@ -406,7 +221,7 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus, | |||
406 | } | 221 | } |
407 | 222 | ||
408 | if ((dn = of_find_node_by_path(path))) { | 223 | if ((dn = of_find_node_by_path(path))) { |
409 | dev = ibmebus_register_device_node(dn); | 224 | /* dev = ibmebus_register_device_node(dn); */ |
410 | of_node_put(dn); | 225 | of_node_put(dn); |
411 | rc = IS_ERR(dev) ? PTR_ERR(dev) : count; | 226 | rc = IS_ERR(dev) ? PTR_ERR(dev) : count; |
412 | } else { | 227 | } else { |
@@ -432,7 +247,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus, | |||
432 | 247 | ||
433 | if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, | 248 | if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, |
434 | ibmebus_match_path))) { | 249 | ibmebus_match_path))) { |
435 | ibmebus_unregister_device(dev); | 250 | /* ibmebus_unregister_device(dev); */ |
436 | 251 | ||
437 | kfree(path); | 252 | kfree(path); |
438 | return count; | 253 | return count; |
@@ -452,8 +267,6 @@ static struct bus_attribute ibmebus_bus_attrs[] = { | |||
452 | }; | 267 | }; |
453 | 268 | ||
454 | struct bus_type ibmebus_bus_type = { | 269 | struct bus_type ibmebus_bus_type = { |
455 | .name = "ibmebus", | ||
456 | .match = ibmebus_bus_match, | ||
457 | .dev_attrs = ibmebus_dev_attrs, | 270 | .dev_attrs = ibmebus_dev_attrs, |
458 | .bus_attrs = ibmebus_bus_attrs | 271 | .bus_attrs = ibmebus_bus_attrs |
459 | }; | 272 | }; |
@@ -465,9 +278,9 @@ static int __init ibmebus_bus_init(void) | |||
465 | 278 | ||
466 | printk(KERN_INFO "IBM eBus Device Driver\n"); | 279 | printk(KERN_INFO "IBM eBus Device Driver\n"); |
467 | 280 | ||
468 | err = bus_register(&ibmebus_bus_type); | 281 | err = of_bus_type_init(&ibmebus_bus_type, "ibmebus"); |
469 | if (err) { | 282 | if (err) { |
470 | printk(KERN_ERR ":%s: failed to register IBM eBus.\n", | 283 | printk(KERN_ERR "%s: failed to register IBM eBus.\n", |
471 | __FUNCTION__); | 284 | __FUNCTION__); |
472 | return err; | 285 | return err; |
473 | } | 286 | } |
@@ -483,4 +296,4 @@ static int __init ibmebus_bus_init(void) | |||
483 | 296 | ||
484 | return 0; | 297 | return 0; |
485 | } | 298 | } |
486 | __initcall(ibmebus_bus_init); | 299 | postcore_initcall(ibmebus_bus_init); |