diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-29 23:11:20 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-07 20:04:46 -0500 |
| commit | ecdf6ceb8cf4756bd4214bf9755755752b6015f5 (patch) | |
| tree | 828af56bdfe60396e77bbc05f28e231ffe70fe9b | |
| parent | 20ef9f46a9abe3c25d9f2834f6cc86bfab46d609 (diff) | |
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: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/base/platform.c | 58 | ||||
| -rw-r--r-- | include/linux/platform_device.h | 5 |
2 files changed, 63 insertions, 0 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 58efaf2f1259..937d58021d1b 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -548,6 +548,64 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, | |||
| 548 | } | 548 | } |
| 549 | EXPORT_SYMBOL_GPL(platform_driver_probe); | 549 | EXPORT_SYMBOL_GPL(platform_driver_probe); |
| 550 | 550 | ||
| 551 | /** | ||
| 552 | * platform_create_bundle - register driver and create corresponding device | ||
| 553 | * @driver: platform driver structure | ||
| 554 | * @probe: the driver probe routine, probably from an __init section | ||
| 555 | * @res: set of resources that needs to be allocated for the device | ||
| 556 | * @n_res: number of resources | ||
| 557 | * @data: platform specific data for this platform device | ||
| 558 | * @size: size of platform specific data | ||
| 559 | * | ||
| 560 | * Use this in legacy-style modules that probe hardware directly and | ||
| 561 | * register a single platform device and corresponding platform driver. | ||
| 562 | */ | ||
| 563 | struct platform_device * __init_or_module platform_create_bundle( | ||
| 564 | struct platform_driver *driver, | ||
| 565 | int (*probe)(struct platform_device *), | ||
| 566 | struct resource *res, unsigned int n_res, | ||
| 567 | const void *data, size_t size) | ||
| 568 | { | ||
| 569 | struct platform_device *pdev; | ||
| 570 | int error; | ||
| 571 | |||
| 572 | pdev = platform_device_alloc(driver->driver.name, -1); | ||
| 573 | if (!pdev) { | ||
| 574 | error = -ENOMEM; | ||
| 575 | goto err_out; | ||
| 576 | } | ||
| 577 | |||
| 578 | if (res) { | ||
| 579 | error = platform_device_add_resources(pdev, res, n_res); | ||
| 580 | if (error) | ||
| 581 | goto err_pdev_put; | ||
| 582 | } | ||
| 583 | |||
| 584 | if (data) { | ||
| 585 | error = platform_device_add_data(pdev, data, size); | ||
| 586 | if (error) | ||
| 587 | goto err_pdev_put; | ||
| 588 | } | ||
| 589 | |||
| 590 | error = platform_device_add(pdev); | ||
| 591 | if (error) | ||
| 592 | goto err_pdev_put; | ||
| 593 | |||
| 594 | error = platform_driver_probe(driver, probe); | ||
| 595 | if (error) | ||
| 596 | goto err_pdev_del; | ||
| 597 | |||
| 598 | return pdev; | ||
| 599 | |||
| 600 | err_pdev_del: | ||
| 601 | platform_device_del(pdev); | ||
| 602 | err_pdev_put: | ||
| 603 | platform_device_put(pdev); | ||
| 604 | err_out: | ||
| 605 | return ERR_PTR(error); | ||
| 606 | } | ||
| 607 | EXPORT_SYMBOL_GPL(platform_create_bundle); | ||
| 608 | |||
| 551 | /* modalias support enables more hands-off userspace setup: | 609 | /* modalias support enables more hands-off userspace setup: |
| 552 | * (a) environment variable lets new-style hotplug events work once system is | 610 | * (a) environment variable lets new-style hotplug events work once system is |
| 553 | * fully running: "modprobe $MODALIAS" | 611 | * fully running: "modprobe $MODALIAS" |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 71ff887ca44e..25e64b43e644 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
| @@ -77,6 +77,11 @@ extern int platform_driver_probe(struct platform_driver *driver, | |||
| 77 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) | 77 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) |
| 78 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) | 78 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) |
| 79 | 79 | ||
| 80 | extern struct platform_device *platform_create_bundle(struct platform_driver *driver, | ||
| 81 | int (*probe)(struct platform_device *), | ||
| 82 | struct resource *res, unsigned int n_res, | ||
| 83 | const void *data, size_t size); | ||
| 84 | |||
| 80 | /* early platform driver interface */ | 85 | /* early platform driver interface */ |
| 81 | struct early_platform_driver { | 86 | struct early_platform_driver { |
| 82 | const char *class_str; | 87 | const char *class_str; |
