aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2015-05-01 20:10:57 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2015-06-16 14:12:37 -0400
commitf309d4443130bf814e991f836e919dca22df37ae (patch)
tree5e34131d7a8ae8f36b3b8e0d521fb1d1b0117338
parent0f57d86787d8b1076ea8f9cbdddda2a46d534a27 (diff)
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>
-rw-r--r--include/linux/device.h22
-rw-r--r--include/linux/platform_device.h23
2 files changed, 45 insertions, 0 deletions
diff --git a/include/linux/device.h b/include/linux/device.h
index 6558af90c8fe..c2d6167cb4a3 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1269,4 +1269,26 @@ static void __exit __driver##_exit(void) \
1269} \ 1269} \
1270module_exit(__driver##_exit); 1270module_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, ...) \
1288static int __init __driver##_init(void) \
1289{ \
1290 return __register(&(__driver) , ##__VA_ARGS__); \
1291} \
1292device_initcall(__driver##_init);
1293
1272#endif /* _DEVICE_H_ */ 1294#endif /* _DEVICE_H_ */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 58f1e75ba105..bba08f44cc97 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -222,6 +222,15 @@ static inline void platform_set_drvdata(struct platform_device *pdev,
222 module_driver(__platform_driver, platform_driver_register, \ 222 module_driver(__platform_driver, platform_driver_register, \
223 platform_driver_unregister) 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/* module_platform_driver_probe() - Helper macro for drivers that don't do 234/* module_platform_driver_probe() - Helper macro for drivers that don't do
226 * anything special in module init/exit. This eliminates a lot of 235 * anything special in module init/exit. This eliminates a lot of
227 * boilerplate. Each module may only use this macro once, and 236 * boilerplate. Each module may only use this macro once, and
@@ -240,6 +249,20 @@ static void __exit __platform_driver##_exit(void) \
240} \ 249} \
241module_exit(__platform_driver##_exit); 250module_exit(__platform_driver##_exit);
242 251
252/* builtin_platform_driver_probe() - Helper macro for drivers that don't do
253 * anything special in device init. This eliminates some boilerplate. Each
254 * driver may only use this macro once, and using it replaces device_initcall.
255 * This is meant to be a parallel of module_platform_driver_probe above, but
256 * without the __exit parts.
257 */
258#define builtin_platform_driver_probe(__platform_driver, __platform_probe) \
259static int __init __platform_driver##_init(void) \
260{ \
261 return platform_driver_probe(&(__platform_driver), \
262 __platform_probe); \
263} \
264device_initcall(__platform_driver##_init); \
265
243#define platform_create_bundle(driver, probe, res, n_res, data, size) \ 266#define platform_create_bundle(driver, probe, res, n_res, data, size) \
244 __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE) 267 __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE)
245extern struct platform_device *__platform_create_bundle( 268extern struct platform_device *__platform_create_bundle(