diff options
Diffstat (limited to 'drivers/of/platform.c')
| -rw-r--r-- | drivers/of/platform.c | 67 | 
1 files changed, 64 insertions, 3 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9d3d932bcb6..712dfd866df 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -20,6 +20,54 @@  #include <linux/of_device.h>  #include <linux/of_irq.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)  #include <asm/dcr.h> @@ -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  |