Commit ecdf6ceb authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Greg Kroah-Hartman

Driver core: add platform_create_bundle() helper

Many legacy-style module create singleton platform devices themselves,
along with corresponding platform driver. Instead of replicating error
handling code in all such drivers, provide a helper that allocates and
registers a single platform device and a driver and binds them together.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 20ef9f46
...@@ -548,6 +548,64 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, ...@@ -548,6 +548,64 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
} }
EXPORT_SYMBOL_GPL(platform_driver_probe); EXPORT_SYMBOL_GPL(platform_driver_probe);
/**
* platform_create_bundle - register driver and create corresponding device
* @driver: platform driver structure
* @probe: the driver probe routine, probably from an __init section
* @res: set of resources that needs to be allocated for the device
* @n_res: number of resources
* @data: platform specific data for this platform device
* @size: size of platform specific data
*
* Use this in legacy-style modules that probe hardware directly and
* register a single platform device and corresponding platform driver.
*/
struct platform_device * __init_or_module platform_create_bundle(
struct platform_driver *driver,
int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
const void *data, size_t size)
{
struct platform_device *pdev;
int error;
pdev = platform_device_alloc(driver->driver.name, -1);
if (!pdev) {
error = -ENOMEM;
goto err_out;
}
if (res) {
error = platform_device_add_resources(pdev, res, n_res);
if (error)
goto err_pdev_put;
}
if (data) {
error = platform_device_add_data(pdev, data, size);
if (error)
goto err_pdev_put;
}
error = platform_device_add(pdev);
if (error)
goto err_pdev_put;
error = platform_driver_probe(driver, probe);
if (error)
goto err_pdev_del;
return pdev;
err_pdev_del:
platform_device_del(pdev);
err_pdev_put:
platform_device_put(pdev);
err_out:
return ERR_PTR(error);
}
EXPORT_SYMBOL_GPL(platform_create_bundle);
/* modalias support enables more hands-off userspace setup: /* modalias support enables more hands-off userspace setup:
* (a) environment variable lets new-style hotplug events work once system is * (a) environment variable lets new-style hotplug events work once system is
* fully running: "modprobe $MODALIAS" * fully running: "modprobe $MODALIAS"
......
...@@ -77,6 +77,11 @@ extern int platform_driver_probe(struct platform_driver *driver, ...@@ -77,6 +77,11 @@ extern int platform_driver_probe(struct platform_driver *driver,
#define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
#define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data))
extern struct platform_device *platform_create_bundle(struct platform_driver *driver,
int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
const void *data, size_t size);
/* early platform driver interface */ /* early platform driver interface */
struct early_platform_driver { struct early_platform_driver {
const char *class_str; const char *class_str;
......
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