diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/platform.c | 6 | ||||
-rw-r--r-- | drivers/of/device.c | 5 | ||||
-rw-r--r-- | drivers/of/platform.c | 67 |
3 files changed, 75 insertions, 3 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index fac3633c7223..f699fabf403b 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -636,6 +636,12 @@ static struct device_attribute platform_dev_attrs[] = { | |||
636 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | 636 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) |
637 | { | 637 | { |
638 | struct platform_device *pdev = to_platform_device(dev); | 638 | struct platform_device *pdev = to_platform_device(dev); |
639 | int rc; | ||
640 | |||
641 | /* Some devices have extra OF data and an OF-style MODALIAS */ | ||
642 | rc = of_device_uevent(dev,env); | ||
643 | if (rc != -ENODEV) | ||
644 | return rc; | ||
639 | 645 | ||
640 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, | 646 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, |
641 | (pdev->id_entry) ? pdev->id_entry->name : pdev->name); | 647 | (pdev->id_entry) ? pdev->id_entry->name : pdev->name); |
diff --git a/drivers/of/device.c b/drivers/of/device.c index 5282a202f5a9..12a44b493511 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
@@ -104,6 +104,11 @@ int of_device_register(struct of_device *ofdev) | |||
104 | 104 | ||
105 | device_initialize(&ofdev->dev); | 105 | device_initialize(&ofdev->dev); |
106 | 106 | ||
107 | /* name and id have to be set so that the platform bus doesn't get | ||
108 | * confused on matching */ | ||
109 | ofdev->name = dev_name(&ofdev->dev); | ||
110 | ofdev->id = -1; | ||
111 | |||
107 | /* device_add will assume that this device is on the same node as | 112 | /* device_add will assume that this device is on the same node as |
108 | * the parent. If there is no parent defined, set the node | 113 | * the parent. If there is no parent defined, set the node |
109 | * explicitly */ | 114 | * explicitly */ |
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9d3d932bcb6f..712dfd866df0 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -20,6 +20,54 @@ | |||
20 | #include <linux/of_device.h> | 20 | #include <linux/of_device.h> |
21 | #include <linux/of_irq.h> | 21 | #include <linux/of_irq.h> |
22 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
23 | #include <linux/platform_device.h> | ||
24 | |||
25 | static int platform_driver_probe_shim(struct platform_device *pdev) | ||
26 | { | ||
27 | struct platform_driver *pdrv; | ||
28 | struct of_platform_driver *ofpdrv; | ||
29 | const struct of_device_id *match; | ||
30 | |||
31 | pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); | ||
32 | ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); | ||
33 | match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); | ||
34 | return ofpdrv->probe(pdev, match); | ||
35 | } | ||
36 | |||
37 | static void platform_driver_shutdown_shim(struct platform_device *pdev) | ||
38 | { | ||
39 | struct platform_driver *pdrv; | ||
40 | struct of_platform_driver *ofpdrv; | ||
41 | |||
42 | pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); | ||
43 | ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); | ||
44 | ofpdrv->shutdown(pdev); | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * of_register_platform_driver | ||
49 | */ | ||
50 | int of_register_platform_driver(struct of_platform_driver *drv) | ||
51 | { | ||
52 | /* setup of_platform_driver to platform_driver adaptors */ | ||
53 | drv->platform_driver.driver = drv->driver; | ||
54 | if (drv->probe) | ||
55 | drv->platform_driver.probe = platform_driver_probe_shim; | ||
56 | drv->platform_driver.remove = drv->remove; | ||
57 | if (drv->shutdown) | ||
58 | drv->platform_driver.shutdown = platform_driver_shutdown_shim; | ||
59 | drv->platform_driver.suspend = drv->suspend; | ||
60 | drv->platform_driver.resume = drv->resume; | ||
61 | |||
62 | return platform_driver_register(&drv->platform_driver); | ||
63 | } | ||
64 | EXPORT_SYMBOL(of_register_platform_driver); | ||
65 | |||
66 | void of_unregister_platform_driver(struct of_platform_driver *drv) | ||
67 | { | ||
68 | platform_driver_unregister(&drv->platform_driver); | ||
69 | } | ||
70 | EXPORT_SYMBOL(of_unregister_platform_driver); | ||
23 | 71 | ||
24 | #if defined(CONFIG_PPC_DCR) | 72 | #if defined(CONFIG_PPC_DCR) |
25 | #include <asm/dcr.h> | 73 | #include <asm/dcr.h> |
@@ -392,16 +440,29 @@ int of_bus_type_init(struct bus_type *bus, const char *name) | |||
392 | 440 | ||
393 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | 441 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) |
394 | { | 442 | { |
395 | drv->driver.bus = bus; | 443 | /* |
444 | * Temporary: of_platform_bus used to be distinct from the platform | ||
445 | * bus. It isn't anymore, and so drivers on the platform bus need | ||
446 | * to be registered in a special way. | ||
447 | * | ||
448 | * After all of_platform_bus_type drivers are converted to | ||
449 | * platform_drivers, this exception can be removed. | ||
450 | */ | ||
451 | if (bus == &platform_bus_type) | ||
452 | return of_register_platform_driver(drv); | ||
396 | 453 | ||
397 | /* register with core */ | 454 | /* register with core */ |
455 | drv->driver.bus = bus; | ||
398 | return driver_register(&drv->driver); | 456 | return driver_register(&drv->driver); |
399 | } | 457 | } |
400 | EXPORT_SYMBOL(of_register_driver); | 458 | EXPORT_SYMBOL(of_register_driver); |
401 | 459 | ||
402 | void of_unregister_driver(struct of_platform_driver *drv) | 460 | void of_unregister_driver(struct of_platform_driver *drv) |
403 | { | 461 | { |
404 | driver_unregister(&drv->driver); | 462 | if (drv->driver.bus == &platform_bus_type) |
463 | of_unregister_platform_driver(drv); | ||
464 | else | ||
465 | driver_unregister(&drv->driver); | ||
405 | } | 466 | } |
406 | EXPORT_SYMBOL(of_unregister_driver); | 467 | EXPORT_SYMBOL(of_unregister_driver); |
407 | 468 | ||
@@ -548,7 +609,7 @@ struct of_device *of_platform_device_create(struct device_node *np, | |||
548 | dev->archdata.dma_mask = 0xffffffffUL; | 609 | dev->archdata.dma_mask = 0xffffffffUL; |
549 | #endif | 610 | #endif |
550 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | 611 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
551 | dev->dev.bus = &of_platform_bus_type; | 612 | dev->dev.bus = &platform_bus_type; |
552 | 613 | ||
553 | /* We do not fill the DMA ops for platform devices by default. | 614 | /* We do not fill the DMA ops for platform devices by default. |
554 | * This is currently the responsibility of the platform code | 615 | * This is currently the responsibility of the platform code |