Commit eca39301 authored by Grant Likely's avatar Grant Likely

of: Merge of_platform_bus_type with platform_bus_type

of_platform_bus was being used in the same manner as the platform_bus.
The only difference being that of_platform_bus devices are generated
from data in the device tree, and platform_bus devices are usually
statically allocated in platform code.  Having them separate causes
the problem of device drivers having to be registered twice if it
was possible for the same device to appear on either bus.

This patch removes of_platform_bus_type and registers all of_platform
bus devices and drivers on the platform bus instead.  A previous patch
made the of_device structure an alias for the platform_device structure,
and a shim is used to adapt of_platform_drivers to the platform bus.

After all of of_platform_bus drivers are converted to be normal platform
drivers, the shim code can be removed.
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 05212157
...@@ -26,17 +26,6 @@ ...@@ -26,17 +26,6 @@
#include <linux/topology.h> #include <linux/topology.h>
#include <asm/atomic.h> #include <asm/atomic.h>
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 * 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. * system whose devices are to be exposed as of_platform_devices.
......
...@@ -213,15 +213,9 @@ static struct notifier_block dflt_plat_bus_notifier = { ...@@ -213,15 +213,9 @@ static struct notifier_block dflt_plat_bus_notifier = {
.priority = INT_MAX, .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) static int __init setup_bus_notifier(void)
{ {
bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier); bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier);
bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier);
return 0; return 0;
} }
......
...@@ -82,17 +82,9 @@ static struct notifier_block ppc_swiotlb_plat_bus_notifier = { ...@@ -82,17 +82,9 @@ static struct notifier_block ppc_swiotlb_plat_bus_notifier = {
.priority = 0, .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) int __init swiotlb_setup_bus_notifier(void)
{ {
bus_register_notifier(&platform_bus_type, bus_register_notifier(&platform_bus_type,
&ppc_swiotlb_plat_bus_notifier); &ppc_swiotlb_plat_bus_notifier);
bus_register_notifier(&of_platform_bus_type,
&ppc_swiotlb_of_bus_notifier);
return 0; return 0;
} }
...@@ -52,18 +52,6 @@ const struct of_device_id of_default_bus_ids[] = { ...@@ -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) static int of_dev_node_match(struct device *dev, void *data)
{ {
return to_of_device(dev)->dev.of_node == data; return to_of_device(dev)->dev.of_node == data;
......
...@@ -701,16 +701,9 @@ static struct notifier_block ppc_dflt_plat_bus_notifier = { ...@@ -701,16 +701,9 @@ static struct notifier_block ppc_dflt_plat_bus_notifier = {
.priority = INT_MAX, .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) static int __init setup_bus_notifier(void)
{ {
bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); 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; return 0;
} }
......
...@@ -108,7 +108,7 @@ static int __init celleb_init_iommu(void) ...@@ -108,7 +108,7 @@ static int __init celleb_init_iommu(void)
celleb_init_direct_mapping(); celleb_init_direct_mapping();
set_pci_dma_ops(&dma_direct_ops); set_pci_dma_ops(&dma_direct_ops);
ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; 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; return 0;
} }
......
...@@ -1204,7 +1204,7 @@ static int __init cell_iommu_init(void) ...@@ -1204,7 +1204,7 @@ static int __init cell_iommu_init(void)
/* Register callbacks on OF platform device addition/removal /* Register callbacks on OF platform device addition/removal
* to handle linking them to the right DMA operations * 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; return 0;
} }
......
...@@ -20,12 +20,7 @@ ...@@ -20,12 +20,7 @@
#include <asm/prom.h> #include <asm/prom.h>
/* /* These functions provide the necessary setup for the mv64x60 drivers. */
* 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.
*/
static struct of_device_id __initdata of_mv64x60_devices[] = { static struct of_device_id __initdata of_mv64x60_devices[] = {
{ .compatible = "marvell,mv64306-devctrl", }, { .compatible = "marvell,mv64306-devctrl", },
......
...@@ -424,7 +424,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, ...@@ -424,7 +424,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
build_device_resources(op, parent); build_device_resources(op, parent);
op->dev.parent = parent; op->dev.parent = parent;
op->dev.bus = &of_platform_bus_type; op->dev.bus = &platform_bus_type;
if (!parent) if (!parent)
dev_set_name(&op->dev, "root"); dev_set_name(&op->dev, "root");
else else
...@@ -452,30 +452,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent) ...@@ -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 device_node *root = of_find_node_by_path("/");
struct of_device *parent; struct of_device *parent;
parent = scan_one_device(root, NULL); parent = scan_one_device(root, NULL);
if (!parent) if (!parent)
return; return 0;
scan_tree(root->child, &parent->dev); scan_tree(root->child, &parent->dev);
return 0;
} }
postcore_initcall(scan_of_devices);
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);
static int __init of_debug(char *str) static int __init of_debug(char *str)
{ {
......
...@@ -667,7 +667,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, ...@@ -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->archdata.irqs[i] = build_one_device_irq(op, parent, op->archdata.irqs[i]);
op->dev.parent = parent; op->dev.parent = parent;
op->dev.bus = &of_platform_bus_type; op->dev.bus = &platform_bus_type;
if (!parent) if (!parent)
dev_set_name(&op->dev, "root"); dev_set_name(&op->dev, "root");
else else
...@@ -695,30 +695,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent) ...@@ -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 device_node *root = of_find_node_by_path("/");
struct of_device *parent; struct of_device *parent;
parent = scan_one_device(root, NULL); parent = scan_one_device(root, NULL);
if (!parent) if (!parent)
return; return 0;
scan_tree(root->child, &parent->dev); scan_tree(root->child, &parent->dev);
return 0;
} }
postcore_initcall(scan_of_devices);
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);
static int __init of_debug(char *str) static int __init of_debug(char *str)
{ {
......
...@@ -64,9 +64,6 @@ void of_propagate_archdata(struct of_device *bus) ...@@ -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) static void get_cells(struct device_node *dp, int *addrc, int *sizec)
{ {
if (addrc) if (addrc)
......
...@@ -636,6 +636,12 @@ static struct device_attribute platform_dev_attrs[] = { ...@@ -636,6 +636,12 @@ static struct device_attribute platform_dev_attrs[] = {
static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
{ {
struct platform_device *pdev = to_platform_device(dev); 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, add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
(pdev->id_entry) ? pdev->id_entry->name : pdev->name); (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
......
...@@ -104,6 +104,11 @@ int of_device_register(struct of_device *ofdev) ...@@ -104,6 +104,11 @@ int of_device_register(struct of_device *ofdev)
device_initialize(&ofdev->dev); 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 /* device_add will assume that this device is on the same node as
* the parent. If there is no parent defined, set the node * the parent. If there is no parent defined, set the node
* explicitly */ * explicitly */
......
...@@ -20,6 +20,54 @@ ...@@ -20,6 +20,54 @@
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/platform_device.h>
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) #if defined(CONFIG_PPC_DCR)
#include <asm/dcr.h> #include <asm/dcr.h>
...@@ -392,16 +440,29 @@ int of_bus_type_init(struct bus_type *bus, const char *name) ...@@ -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) 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 */ /* register with core */
drv->driver.bus = bus;
return driver_register(&drv->driver); return driver_register(&drv->driver);
} }
EXPORT_SYMBOL(of_register_driver); EXPORT_SYMBOL(of_register_driver);
void of_unregister_driver(struct of_platform_driver *drv) 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); EXPORT_SYMBOL(of_unregister_driver);
...@@ -548,7 +609,7 @@ struct of_device *of_platform_device_create(struct device_node *np, ...@@ -548,7 +609,7 @@ struct of_device *of_platform_device_create(struct device_node *np,
dev->archdata.dma_mask = 0xffffffffUL; dev->archdata.dma_mask = 0xffffffffUL;
#endif #endif
dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 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. /* We do not fill the DMA ops for platform devices by default.
* This is currently the responsibility of the platform code * This is currently the responsibility of the platform code
......
...@@ -65,6 +65,12 @@ static inline int of_driver_match_device(struct device *dev, ...@@ -65,6 +65,12 @@ static inline int of_driver_match_device(struct device *dev,
return 0; return 0;
} }
static inline int of_device_uevent(struct device *dev,
struct kobj_uevent_env *env)
{
return -ENODEV;
}
#endif /* CONFIG_OF_DEVICE */ #endif /* CONFIG_OF_DEVICE */
#endif /* _LINUX_OF_DEVICE_H */ #endif /* _LINUX_OF_DEVICE_H */
...@@ -17,19 +17,19 @@ ...@@ -17,19 +17,19 @@
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h>
/* /*
* The of_platform_bus_type is a bus type used by drivers that do not * of_platform_bus_type isn't it's own bus anymore. It's now just an alias
* attach to a macio or similar bus but still use OF probing * for the platform bus.
* mechanism
*/ */
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[]; extern const struct of_device_id of_default_bus_ids[];
/* /*
* An of_platform_driver driver is attached to a basic of_device on * 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 struct of_platform_driver
{ {
...@@ -42,6 +42,7 @@ struct of_platform_driver ...@@ -42,6 +42,7 @@ struct of_platform_driver
int (*shutdown)(struct of_device* dev); int (*shutdown)(struct of_device* dev);
struct device_driver driver; struct device_driver driver;
struct platform_driver platform_driver;
}; };
#define to_of_platform_driver(drv) \ #define to_of_platform_driver(drv) \
container_of(drv,struct of_platform_driver, driver) container_of(drv,struct of_platform_driver, driver)
...@@ -51,14 +52,8 @@ extern int of_register_driver(struct of_platform_driver *drv, ...@@ -51,14 +52,8 @@ extern int of_register_driver(struct of_platform_driver *drv,
extern void of_unregister_driver(struct of_platform_driver *drv); extern void of_unregister_driver(struct of_platform_driver *drv);
/* Platform drivers register/unregister */ /* Platform drivers register/unregister */
static inline int of_register_platform_driver(struct of_platform_driver *drv) extern int of_register_platform_driver(struct of_platform_driver *drv);
{ extern void of_unregister_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 struct of_device *of_device_alloc(struct device_node *np, extern struct of_device *of_device_alloc(struct device_node *np,
const char *bus_id, const char *bus_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment