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

platform_device: better support builtin boilerplate avoidance

We have macros that help reduce the boilerplate for modules
that register with no extra init/exit complexity other than the
most standard use case. However we see an increasing number of
non-modular drivers using these modular_driver() type register
functions.

There are several downsides to this:
1) The code can appear modular to a reader of the code, and they
won't know if the code really is modular without checking the
Makefile and Kconfig to see if compilation is governed by a
bool or tristate.
2) Coders of drivers may be tempted to code up an __exit function
that is never used, just in order to satisfy the required three
args of the modular registration function.
3) Non-modular code ends up including the <module.h> which increases
CPP overhead that they don't need.
4) It hinders us from performing better separation of the module
init code and the generic init code.

Here we introduce similar macros, with the mapping from module_driver
to builtin_driver and similar, so that simple changes of:

module_platform_driver() ---> builtin_platform_driver()
module_platform_driver_probe() ---> builtin_platform_driver_probe().

can help us avoid #3 above, without having to code up the same
__init functions and device_initcall() boilerplate.

For non modular code, module_init becomes __initcall. But direct use
of __initcall is discouraged, vs. one of the priority categorized
subgroups. As __initcall gets mapped onto device_initcall, our
use of device_initcall directly in this change means that the
runtime impact is zero -- drivers will remain at level 6 in the
initcall ordering.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>

+45
+22
include/linux/device.h
··· 1269 1269 } \ 1270 1270 module_exit(__driver##_exit); 1271 1271 1272 + /** 1273 + * builtin_driver() - Helper macro for drivers that don't do anything 1274 + * special in init and have no exit. This eliminates some boilerplate. 1275 + * Each driver may only use this macro once, and calling it replaces 1276 + * device_initcall (or in some cases, the legacy __initcall). This is 1277 + * meant to be a direct parallel of module_driver() above but without 1278 + * the __exit stuff that is not used for builtin cases. 1279 + * 1280 + * @__driver: driver name 1281 + * @__register: register function for this driver type 1282 + * @...: Additional arguments to be passed to __register 1283 + * 1284 + * Use this macro to construct bus specific macros for registering 1285 + * drivers, and do not use it on its own. 1286 + */ 1287 + #define builtin_driver(__driver, __register, ...) \ 1288 + static int __init __driver##_init(void) \ 1289 + { \ 1290 + return __register(&(__driver) , ##__VA_ARGS__); \ 1291 + } \ 1292 + device_initcall(__driver##_init); 1293 + 1272 1294 #endif /* _DEVICE_H_ */
+23
include/linux/platform_device.h
··· 222 222 module_driver(__platform_driver, platform_driver_register, \ 223 223 platform_driver_unregister) 224 224 225 + /* builtin_platform_driver() - Helper macro for builtin drivers that 226 + * don't do anything special in driver init. This eliminates some 227 + * boilerplate. Each driver may only use this macro once, and 228 + * calling it replaces device_initcall(). Note this is meant to be 229 + * a parallel of module_platform_driver() above, but w/o _exit stuff. 230 + */ 231 + #define builtin_platform_driver(__platform_driver) \ 232 + builtin_driver(__platform_driver, platform_driver_register) 233 + 225 234 /* module_platform_driver_probe() - Helper macro for drivers that don't do 226 235 * anything special in module init/exit. This eliminates a lot of 227 236 * boilerplate. Each module may only use this macro once, and ··· 248 239 platform_driver_unregister(&(__platform_driver)); \ 249 240 } \ 250 241 module_exit(__platform_driver##_exit); 242 + 243 + /* builtin_platform_driver_probe() - Helper macro for drivers that don't do 244 + * anything special in device init. This eliminates some boilerplate. Each 245 + * driver may only use this macro once, and using it replaces device_initcall. 246 + * This is meant to be a parallel of module_platform_driver_probe above, but 247 + * without the __exit parts. 248 + */ 249 + #define builtin_platform_driver_probe(__platform_driver, __platform_probe) \ 250 + static int __init __platform_driver##_init(void) \ 251 + { \ 252 + return platform_driver_probe(&(__platform_driver), \ 253 + __platform_probe); \ 254 + } \ 255 + device_initcall(__platform_driver##_init); \ 251 256 252 257 #define platform_create_bundle(driver, probe, res, n_res, data, size) \ 253 258 __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE)