Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

driver-core: platform: Provide helpers for multi-driver modules

Some modules register several sub-drivers. Provide a helper that makes
it easy to register and unregister a list of sub-drivers, as well as
unwind properly on error.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Thierry Reding and committed by
Greg Kroah-Hartman
dbe2256d 7568fb63

+83
+14
Documentation/driver-model/platform.txt
··· 63 63 int platform_driver_probe(struct platform_driver *drv, 64 64 int (*probe)(struct platform_device *)) 65 65 66 + Kernel modules can be composed of several platform drivers. The platform core 67 + provides helpers to register and unregister an array of drivers: 68 + 69 + int __platform_register_drivers(struct platform_driver * const *drivers, 70 + unsigned int count, struct module *owner); 71 + void platform_unregister_drivers(struct platform_driver * const *drivers, 72 + unsigned int count); 73 + 74 + If one of the drivers fails to register, all drivers registered up to that 75 + point will be unregistered in reverse order. Note that there is a convenience 76 + macro that passes THIS_MODULE as owner parameter: 77 + 78 + #define platform_register_driver(drivers, count) 79 + 66 80 67 81 Device Enumeration 68 82 ~~~~~~~~~~~~~~~~~~
+61
drivers/base/platform.c
··· 710 710 } 711 711 EXPORT_SYMBOL_GPL(__platform_create_bundle); 712 712 713 + /** 714 + * __platform_register_drivers - register an array of platform drivers 715 + * @drivers: an array of drivers to register 716 + * @count: the number of drivers to register 717 + * @owner: module owning the drivers 718 + * 719 + * Registers platform drivers specified by an array. On failure to register a 720 + * driver, all previously registered drivers will be unregistered. Callers of 721 + * this API should use platform_unregister_drivers() to unregister drivers in 722 + * the reverse order. 723 + * 724 + * Returns: 0 on success or a negative error code on failure. 725 + */ 726 + int __platform_register_drivers(struct platform_driver * const *drivers, 727 + unsigned int count, struct module *owner) 728 + { 729 + unsigned int i; 730 + int err; 731 + 732 + for (i = 0; i < count; i++) { 733 + pr_debug("registering platform driver %ps\n", drivers[i]); 734 + 735 + err = __platform_driver_register(drivers[i], owner); 736 + if (err < 0) { 737 + pr_err("failed to register platform driver %ps: %d\n", 738 + drivers[i], err); 739 + goto error; 740 + } 741 + } 742 + 743 + return 0; 744 + 745 + error: 746 + while (i--) { 747 + pr_debug("unregistering platform driver %ps\n", drivers[i]); 748 + platform_driver_unregister(drivers[i]); 749 + } 750 + 751 + return err; 752 + } 753 + EXPORT_SYMBOL_GPL(__platform_register_drivers); 754 + 755 + /** 756 + * platform_unregister_drivers - unregister an array of platform drivers 757 + * @drivers: an array of drivers to unregister 758 + * @count: the number of drivers to unregister 759 + * 760 + * Unegisters platform drivers specified by an array. This is typically used 761 + * to complement an earlier call to platform_register_drivers(). Drivers are 762 + * unregistered in the reverse order in which they were registered. 763 + */ 764 + void platform_unregister_drivers(struct platform_driver * const *drivers, 765 + unsigned int count) 766 + { 767 + while (count--) { 768 + pr_debug("unregistering platform driver %ps\n", drivers[count]); 769 + platform_driver_unregister(drivers[count]); 770 + } 771 + } 772 + EXPORT_SYMBOL_GPL(platform_unregister_drivers); 773 + 713 774 /* modalias support enables more hands-off userspace setup: 714 775 * (a) environment variable lets new-style hotplug events work once system is 715 776 * fully running: "modprobe $MODALIAS"
+8
include/linux/platform_device.h
··· 270 270 struct resource *res, unsigned int n_res, 271 271 const void *data, size_t size, struct module *module); 272 272 273 + int __platform_register_drivers(struct platform_driver * const *drivers, 274 + unsigned int count, struct module *owner); 275 + void platform_unregister_drivers(struct platform_driver * const *drivers, 276 + unsigned int count); 277 + 278 + #define platform_register_drivers(drivers, count) \ 279 + __platform_register_drivers(drivers, count, THIS_MODULE) 280 + 273 281 /* early platform driver interface */ 274 282 struct early_platform_driver { 275 283 const char *class_str;