[1/4] driver core: introduce helper macro initcall_driver()

Message ID 1380518035-5319-2-git-send-email-hanjun.guo@linaro.org
State New
Headers show

Commit Message

Hanjun Guo Sept. 30, 2013, 5:13 a.m.
For some devices especially on platform/I2C/SPI bus, they want to
be initialized earlier than other devices, so the driver use initcall
such as subsys_initcall to make this device initialize earlier.

But for those drivers, lots of them just do nothing special in
xxx_initcall/exit, so introduce a helper macro initcall_driver() to
eliminate lots of boilerplate just like module_driver() did.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 include/linux/device.h |   27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

Comments

Mark Brown Sept. 30, 2013, 9:16 a.m. | #1
On Mon, Sep 30, 2013 at 01:13:52PM +0800, Hanjun Guo wrote:
> For some devices especially on platform/I2C/SPI bus, they want to
> be initialized earlier than other devices, so the driver use initcall
> such as subsys_initcall to make this device initialize earlier.

We're trying to move away from needing to do this and to using deferred
probing to resolve init ordering issues.  Should we not be able to
convert the drivers to module_X_driver()?
Wolfram Sang Sept. 30, 2013, 10:15 a.m. | #2
On Mon, Sep 30, 2013 at 01:13:52PM +0800, Hanjun Guo wrote:
> For some devices especially on platform/I2C/SPI bus, they want to
> be initialized earlier than other devices, so the driver use initcall
> such as subsys_initcall to make this device initialize earlier.

And this is something we want to get rid of in favor of deferred
probing.

> 
> But for those drivers, lots of them just do nothing special in
> xxx_initcall/exit, so introduce a helper macro initcall_driver() to
> eliminate lots of boilerplate just like module_driver() did.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>

So, NACK because using some *_initcall in drivers should not be
encouraged.

Thanks,

   Wolfram
Hanjun Guo Sept. 30, 2013, 2:23 p.m. | #3
On 2013年09月30日 17:16, Mark Brown wrote:
> On Mon, Sep 30, 2013 at 01:13:52PM +0800, Hanjun Guo wrote:
>> For some devices especially on platform/I2C/SPI bus, they want to
>> be initialized earlier than other devices, so the driver use initcall
>> such as subsys_initcall to make this device initialize earlier.
> We're trying to move away from needing to do this and to using deferred
> probing to resolve init ordering issues.  Should we not be able to
> convert the drivers to module_X_driver()?
Hi Mark,

Thanks for your comments.

That would be great to move away *_initcall in module driver, and
this patch set is not necessary if we can use deferred probe to solve
all the init order issues.

Thanks
Hanjun
Hanjun Guo Sept. 30, 2013, 2:28 p.m. | #4
On 2013年09月30日 18:15, Wolfram Sang wrote:
> On Mon, Sep 30, 2013 at 01:13:52PM +0800, Hanjun Guo wrote:
>> For some devices especially on platform/I2C/SPI bus, they want to
>> be initialized earlier than other devices, so the driver use initcall
>> such as subsys_initcall to make this device initialize earlier.
> And this is something we want to get rid of in favor of deferred
> probing.
>
>> But for those drivers, lots of them just do nothing special in
>> xxx_initcall/exit, so introduce a helper macro initcall_driver() to
>> eliminate lots of boilerplate just like module_driver() did.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> So, NACK because using some *_initcall in drivers should not be
> encouraged.

Ok, got it. I agree with you, *_initcall in module driver is really
confusing people :)

Thanks
Hanjun
>
> Thanks,
>
>     Wolfram
>

Patch

diff --git a/include/linux/device.h b/include/linux/device.h
index 2a9d6ed..1903f7f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1198,4 +1198,31 @@  static void __exit __driver##_exit(void) \
 } \
 module_exit(__driver##_exit);
 
+/**
+ * initcall_driver() - Helper macro for drivers that don't do anything
+ * special in buid-in module xxx_initcall/exit. This eliminates a lot
+ * of boilerplate. Each driver may only use this macro once, and calling
+ * it replaces xxx_initcall() and module_exit().
+ *
+ * @__type: initcall type
+ * @__driver: driver name
+ * @__register: register function for this driver type
+ * @__unregister: unregister function for this driver type
+ * @...: Additional arguments to be passed to __register and __unregister.
+ *
+ * Use this macro to construct bus specific macros for registering
+ * drivers, and do not use it on its own.
+ */
+#define initcall_driver(__type, __driver, __register, __unregister, ...) \
+static int __init __driver##_init(void) \
+{ \
+	return __register(&(__driver) , ##__VA_ARGS__); \
+} \
+__type##_initcall(__driver##_init); \
+static void __exit __driver##_exit(void) \
+{ \
+	__unregister(&(__driver) , ##__VA_ARGS__); \
+} \
+module_exit(__driver##_exit);
+
 #endif /* _DEVICE_H_ */