Skip to content

Commit

Permalink
Driver core: add platform_create_bundle() helper
Browse files Browse the repository at this point in the history
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: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Dmitry Torokhov authored and Greg Kroah-Hartman committed Mar 8, 2010
1 parent 20ef9f4 commit ecdf6ce
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
58 changes: 58 additions & 0 deletions drivers/base/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,64 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
}
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:
* (a) environment variable lets new-style hotplug events work once system is
* fully running: "modprobe $MODALIAS"
Expand Down
5 changes: 5 additions & 0 deletions include/linux/platform_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 */
struct early_platform_driver {
const char *class_str;
Expand Down

0 comments on commit ecdf6ce

Please sign in to comment.