diff options
author | Wolfram Sang <wsa@the-dreams.de> | 2014-10-28 12:40:42 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-11-06 18:16:02 -0500 |
commit | 291f653a140ad880426125e5e9dbb70f4c184683 (patch) | |
tree | 5f80732c03b2ba2c9b2ef339036b8871e6148d6b | |
parent | c3b50dc219e1437e4dcb6a1639b004648dc29faa (diff) |
core: platform: let platform_create_bundle initialize module owner
Since commit 9447057eaff8 ("platform_device: use a macro instead of
platform_driver_register"), platform_driver_register() always overwrites
the .owner field of a platform_driver with THIS_MODULE. This breaks
platform_create_bundle() which uses it via platform_driver_probe() from
within the platform core instead of the module init. Fix it by using a
similar #define construct to obtain THIS_MODULE and pass it on later.
Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/base/platform.c | 11 | ||||
-rw-r--r-- | include/linux/platform_device.h | 6 |
2 files changed, 10 insertions, 7 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c87a63326871..cdb6c076c3f7 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -637,24 +637,25 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv, | |||
637 | EXPORT_SYMBOL_GPL(__platform_driver_probe); | 637 | EXPORT_SYMBOL_GPL(__platform_driver_probe); |
638 | 638 | ||
639 | /** | 639 | /** |
640 | * platform_create_bundle - register driver and create corresponding device | 640 | * __platform_create_bundle - register driver and create corresponding device |
641 | * @driver: platform driver structure | 641 | * @driver: platform driver structure |
642 | * @probe: the driver probe routine, probably from an __init section | 642 | * @probe: the driver probe routine, probably from an __init section |
643 | * @res: set of resources that needs to be allocated for the device | 643 | * @res: set of resources that needs to be allocated for the device |
644 | * @n_res: number of resources | 644 | * @n_res: number of resources |
645 | * @data: platform specific data for this platform device | 645 | * @data: platform specific data for this platform device |
646 | * @size: size of platform specific data | 646 | * @size: size of platform specific data |
647 | * @module: module which will be the owner of the driver | ||
647 | * | 648 | * |
648 | * Use this in legacy-style modules that probe hardware directly and | 649 | * Use this in legacy-style modules that probe hardware directly and |
649 | * register a single platform device and corresponding platform driver. | 650 | * register a single platform device and corresponding platform driver. |
650 | * | 651 | * |
651 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | 652 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. |
652 | */ | 653 | */ |
653 | struct platform_device * __init_or_module platform_create_bundle( | 654 | struct platform_device * __init_or_module __platform_create_bundle( |
654 | struct platform_driver *driver, | 655 | struct platform_driver *driver, |
655 | int (*probe)(struct platform_device *), | 656 | int (*probe)(struct platform_device *), |
656 | struct resource *res, unsigned int n_res, | 657 | struct resource *res, unsigned int n_res, |
657 | const void *data, size_t size) | 658 | const void *data, size_t size, struct module *module) |
658 | { | 659 | { |
659 | struct platform_device *pdev; | 660 | struct platform_device *pdev; |
660 | int error; | 661 | int error; |
@@ -677,7 +678,7 @@ struct platform_device * __init_or_module platform_create_bundle( | |||
677 | if (error) | 678 | if (error) |
678 | goto err_pdev_put; | 679 | goto err_pdev_put; |
679 | 680 | ||
680 | error = platform_driver_probe(driver, probe); | 681 | error = __platform_driver_probe(driver, probe, module); |
681 | if (error) | 682 | if (error) |
682 | goto err_pdev_del; | 683 | goto err_pdev_del; |
683 | 684 | ||
@@ -690,7 +691,7 @@ err_pdev_put: | |||
690 | err_out: | 691 | err_out: |
691 | return ERR_PTR(error); | 692 | return ERR_PTR(error); |
692 | } | 693 | } |
693 | EXPORT_SYMBOL_GPL(platform_create_bundle); | 694 | EXPORT_SYMBOL_GPL(__platform_create_bundle); |
694 | 695 | ||
695 | /* modalias support enables more hands-off userspace setup: | 696 | /* modalias support enables more hands-off userspace setup: |
696 | * (a) environment variable lets new-style hotplug events work once system is | 697 | * (a) environment variable lets new-style hotplug events work once system is |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index c8d95c60da19..ae4882ca4a64 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
@@ -240,10 +240,12 @@ static void __exit __platform_driver##_exit(void) \ | |||
240 | } \ | 240 | } \ |
241 | module_exit(__platform_driver##_exit); | 241 | module_exit(__platform_driver##_exit); |
242 | 242 | ||
243 | extern struct platform_device *platform_create_bundle( | 243 | #define platform_create_bundle(driver, probe, res, n_res, data, size) \ |
244 | __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE) | ||
245 | extern struct platform_device *__platform_create_bundle( | ||
244 | struct platform_driver *driver, int (*probe)(struct platform_device *), | 246 | struct platform_driver *driver, int (*probe)(struct platform_device *), |
245 | struct resource *res, unsigned int n_res, | 247 | struct resource *res, unsigned int n_res, |
246 | const void *data, size_t size); | 248 | const void *data, size_t size, struct module *module); |
247 | 249 | ||
248 | /* early platform driver interface */ | 250 | /* early platform driver interface */ |
249 | struct early_platform_driver { | 251 | struct early_platform_driver { |