diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index da79edf454208340a615a466fcb36cc9eceaad84..fb28661043311fcdaf5f9a838af1b902922082f6 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -26,17 +26,6 @@ #include #include -struct bus_type of_platform_bus_type = { - .uevent = of_device_uevent, -}; -EXPORT_SYMBOL(of_platform_bus_type); - -static int __init of_bus_driver_init(void) -{ - return of_bus_type_init(&of_platform_bus_type, "of_platform"); -} -postcore_initcall(of_bus_driver_init); - /* * The list of OF IDs below is used for matching bus types in the * system whose devices are to be exposed as of_platform_devices. diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 17c98dbcec888f698e2c038eee317ddef7e1f7da..f5f768842354201266bf0dce0e7209484f49a4fa 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -213,15 +213,9 @@ static struct notifier_block dflt_plat_bus_notifier = { .priority = INT_MAX, }; -static struct notifier_block dflt_of_bus_notifier = { - .notifier_call = dflt_bus_notify, - .priority = INT_MAX, -}; - static int __init setup_bus_notifier(void) { bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier); - bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier); return 0; } diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 02f724f367533ee60f6512a7453cb0f0e3024fbc..4295e0b94b2db31238f008c49756955fd4922702 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -82,17 +82,9 @@ static struct notifier_block ppc_swiotlb_plat_bus_notifier = { .priority = 0, }; -static struct notifier_block ppc_swiotlb_of_bus_notifier = { - .notifier_call = ppc_swiotlb_bus_notify, - .priority = 0, -}; - int __init swiotlb_setup_bus_notifier(void) { bus_register_notifier(&platform_bus_type, &ppc_swiotlb_plat_bus_notifier); - bus_register_notifier(&of_platform_bus_type, - &ppc_swiotlb_of_bus_notifier); - return 0; } diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 4e0a2f7c1dd37b6791ca682be4d4b02b21a4ac8b..d3497cd81e8a86bb79c9230c3cd5cab693c79c07 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -52,18 +52,6 @@ const struct of_device_id of_default_bus_ids[] = { {}, }; -struct bus_type of_platform_bus_type = { - .uevent = of_device_uevent, -}; -EXPORT_SYMBOL(of_platform_bus_type); - -static int __init of_bus_driver_init(void) -{ - return of_bus_type_init(&of_platform_bus_type, "of_platform"); -} - -postcore_initcall(of_bus_driver_init); - static int of_dev_node_match(struct device *dev, void *data) { return to_of_device(dev)->dev.of_node == data; diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index b7e6c7e193ae9141cc0aa6b1c7beb3394240c937..d1a5304b3dddad851478c2c03c2528bd844ff175 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -701,16 +701,9 @@ static struct notifier_block ppc_dflt_plat_bus_notifier = { .priority = INT_MAX, }; -static struct notifier_block ppc_dflt_of_bus_notifier = { - .notifier_call = ppc_dflt_bus_notify, - .priority = INT_MAX, -}; - static int __init setup_bus_notifier(void) { bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); - bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier); - return 0; } diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c index 39d361c5c6d2e73d4ca9f37d1c415b871ca30610..beec405eb6f8d47142959427e6ef97f9f08bc88c 100644 --- a/arch/powerpc/platforms/cell/beat_iommu.c +++ b/arch/powerpc/platforms/cell/beat_iommu.c @@ -108,7 +108,7 @@ static int __init celleb_init_iommu(void) celleb_init_direct_mapping(); set_pci_dma_ops(&dma_direct_ops); ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; - bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier); + bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier); return 0; } diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 3712900471ba2e9033419ab31d620ab8d2a983b2..58b13ce3847ec3c92453ef70d5ec4e653d6d886a 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -1204,7 +1204,7 @@ static int __init cell_iommu_init(void) /* Register callbacks on OF platform device addition/removal * to handle linking them to the right DMA operations */ - bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier); + bus_register_notifier(&platform_bus_type, &cell_of_bus_notifier); return 0; } diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 31acd3b1718b8f09be498fd2a15d82aa72464ca5..1398bc454999b2b10fae54972e5e92c69689b3eb 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -20,12 +20,7 @@ #include -/* - * These functions provide the necessary setup for the mv64x60 drivers. - * These drivers are unusual in that they work on both the MIPS and PowerPC - * architectures. Because of that, the drivers do not support the normal - * PowerPC of_platform_bus_type. They support platform_bus_type instead. - */ +/* These functions provide the necessary setup for the mv64x60 drivers. */ static struct of_device_id __initdata of_mv64x60_devices[] = { { .compatible = "marvell,mv64306-devctrl", }, diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 331de91ad2bcb290c542ade8f1dd495e458279cf..75fc9d5cd7e61069d73e198a86ee570cb399cf4a 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -424,7 +424,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, build_device_resources(op, parent); op->dev.parent = parent; - op->dev.bus = &of_platform_bus_type; + op->dev.bus = &platform_bus_type; if (!parent) dev_set_name(&op->dev, "root"); else @@ -452,30 +452,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent) } } -static void __init scan_of_devices(void) +static int __init scan_of_devices(void) { struct device_node *root = of_find_node_by_path("/"); struct of_device *parent; parent = scan_one_device(root, NULL); if (!parent) - return; + return 0; scan_tree(root->child, &parent->dev); + return 0; } - -static int __init of_bus_driver_init(void) -{ - int err; - - err = of_bus_type_init(&of_platform_bus_type, "of"); - if (!err) - scan_of_devices(); - - return err; -} - -postcore_initcall(of_bus_driver_init); +postcore_initcall(scan_of_devices); static int __init of_debug(char *str) { diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 5e8cbb942d3dc0b4bf6c1c7d118b4d8226c65f53..9743d1d9fa03fc06d89c33f86bf5d06c40ed404d 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -667,7 +667,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, op->archdata.irqs[i] = build_one_device_irq(op, parent, op->archdata.irqs[i]); op->dev.parent = parent; - op->dev.bus = &of_platform_bus_type; + op->dev.bus = &platform_bus_type; if (!parent) dev_set_name(&op->dev, "root"); else @@ -695,30 +695,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent) } } -static void __init scan_of_devices(void) +static int __init scan_of_devices(void) { struct device_node *root = of_find_node_by_path("/"); struct of_device *parent; parent = scan_one_device(root, NULL); if (!parent) - return; + return 0; scan_tree(root->child, &parent->dev); + return 0; } - -static int __init of_bus_driver_init(void) -{ - int err; - - err = of_bus_type_init(&of_platform_bus_type, "of"); - if (!err) - scan_of_devices(); - - return err; -} - -postcore_initcall(of_bus_driver_init); +postcore_initcall(scan_of_devices); static int __init of_debug(char *str) { diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index 016c947d4cae69786332432ce9735f374a4c2f50..01f380c7995cdaefcb93c7572d9d4787a432e7b4 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -64,9 +64,6 @@ void of_propagate_archdata(struct of_device *bus) } } -struct bus_type of_platform_bus_type; -EXPORT_SYMBOL(of_platform_bus_type); - static void get_cells(struct device_node *dp, int *addrc, int *sizec) { if (addrc) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index fac3633c72235837fa2ab694967523d3ced5e76c..f699fabf403bedd931fd457a2c200faef58ad7ea 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -636,6 +636,12 @@ static struct device_attribute platform_dev_attrs[] = { static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) { struct platform_device *pdev = to_platform_device(dev); + int rc; + + /* Some devices have extra OF data and an OF-style MODALIAS */ + rc = of_device_uevent(dev,env); + if (rc != -ENODEV) + return rc; add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, (pdev->id_entry) ? pdev->id_entry->name : pdev->name); diff --git a/drivers/of/device.c b/drivers/of/device.c index 5282a202f5a95533cca53e1ab0e227700979b6cd..12a44b493511e5a3599f0fe1c80a14d755aea3aa 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -104,6 +104,11 @@ int of_device_register(struct of_device *ofdev) device_initialize(&ofdev->dev); + /* name and id have to be set so that the platform bus doesn't get + * confused on matching */ + ofdev->name = dev_name(&ofdev->dev); + ofdev->id = -1; + /* device_add will assume that this device is on the same node as * the parent. If there is no parent defined, set the node * explicitly */ diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9d3d932bcb6fa50759c0eb3f4dbd8414a6dbe886..712dfd866df09e0bc73aecfddab1410a886ea387 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -20,6 +20,54 @@ #include #include #include +#include + +static int platform_driver_probe_shim(struct platform_device *pdev) +{ + struct platform_driver *pdrv; + struct of_platform_driver *ofpdrv; + const struct of_device_id *match; + + pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); + ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); + match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); + return ofpdrv->probe(pdev, match); +} + +static void platform_driver_shutdown_shim(struct platform_device *pdev) +{ + struct platform_driver *pdrv; + struct of_platform_driver *ofpdrv; + + pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); + ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); + ofpdrv->shutdown(pdev); +} + +/** + * of_register_platform_driver + */ +int of_register_platform_driver(struct of_platform_driver *drv) +{ + /* setup of_platform_driver to platform_driver adaptors */ + drv->platform_driver.driver = drv->driver; + if (drv->probe) + drv->platform_driver.probe = platform_driver_probe_shim; + drv->platform_driver.remove = drv->remove; + if (drv->shutdown) + drv->platform_driver.shutdown = platform_driver_shutdown_shim; + drv->platform_driver.suspend = drv->suspend; + drv->platform_driver.resume = drv->resume; + + return platform_driver_register(&drv->platform_driver); +} +EXPORT_SYMBOL(of_register_platform_driver); + +void of_unregister_platform_driver(struct of_platform_driver *drv) +{ + platform_driver_unregister(&drv->platform_driver); +} +EXPORT_SYMBOL(of_unregister_platform_driver); #if defined(CONFIG_PPC_DCR) #include @@ -392,16 +440,29 @@ int of_bus_type_init(struct bus_type *bus, const char *name) int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) { - drv->driver.bus = bus; + /* + * Temporary: of_platform_bus used to be distinct from the platform + * bus. It isn't anymore, and so drivers on the platform bus need + * to be registered in a special way. + * + * After all of_platform_bus_type drivers are converted to + * platform_drivers, this exception can be removed. + */ + if (bus == &platform_bus_type) + return of_register_platform_driver(drv); /* register with core */ + drv->driver.bus = bus; return driver_register(&drv->driver); } EXPORT_SYMBOL(of_register_driver); void of_unregister_driver(struct of_platform_driver *drv) { - driver_unregister(&drv->driver); + if (drv->driver.bus == &platform_bus_type) + of_unregister_platform_driver(drv); + else + driver_unregister(&drv->driver); } EXPORT_SYMBOL(of_unregister_driver); @@ -548,7 +609,7 @@ struct of_device *of_platform_device_create(struct device_node *np, dev->archdata.dma_mask = 0xffffffffUL; #endif dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - dev->dev.bus = &of_platform_bus_type; + dev->dev.bus = &platform_bus_type; /* We do not fill the DMA ops for platform devices by default. * This is currently the responsibility of the platform code diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 7d27f5a878f604c850fd5f323f321cf289c88129..8cd1fe7864e33bbfad9ad374aa1df2baefa94fc9 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -65,6 +65,12 @@ static inline int of_driver_match_device(struct device *dev, return 0; } +static inline int of_device_uevent(struct device *dev, + struct kobj_uevent_env *env) +{ + return -ENODEV; +} + #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */ diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index a51fd30176aaba3e8bd2c751615a23ff17fd5c3e..133ecf31a60f3dac79f8f93ce8659e94dc9705d7 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -17,19 +17,19 @@ #include #include #include +#include /* - * The of_platform_bus_type is a bus type used by drivers that do not - * attach to a macio or similar bus but still use OF probing - * mechanism + * of_platform_bus_type isn't it's own bus anymore. It's now just an alias + * for the platform bus. */ -extern struct bus_type of_platform_bus_type; +#define of_platform_bus_type platform_bus_type extern const struct of_device_id of_default_bus_ids[]; /* * An of_platform_driver driver is attached to a basic of_device on - * the "platform bus" (of_platform_bus_type). + * the "platform bus" (platform_bus_type). */ struct of_platform_driver { @@ -42,6 +42,7 @@ struct of_platform_driver int (*shutdown)(struct of_device* dev); struct device_driver driver; + struct platform_driver platform_driver; }; #define to_of_platform_driver(drv) \ container_of(drv,struct of_platform_driver, driver) @@ -51,14 +52,8 @@ extern int of_register_driver(struct of_platform_driver *drv, extern void of_unregister_driver(struct of_platform_driver *drv); /* Platform drivers register/unregister */ -static inline int of_register_platform_driver(struct of_platform_driver *drv) -{ - return of_register_driver(drv, &of_platform_bus_type); -} -static inline void of_unregister_platform_driver(struct of_platform_driver *drv) -{ - of_unregister_driver(drv); -} +extern int of_register_platform_driver(struct of_platform_driver *drv); +extern void of_unregister_platform_driver(struct of_platform_driver *drv); extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id,