|  | 
 
| 内核启动的时候,各个驱动初始化的工作在文件init/main.c中的do_basic_setup()函数中做. 
 ------------------------------------------------------------------------------------------------------
 static void __init do_basic_setup(void)
 {
 /* drivers will send hotplug events */
 init_workqueues();
 usermodehelper_init();
 driver_init();
 
 #ifdef CONFIG_SYSCTL
 sysctl_init();
 #endif
 
 /* Networking initialization needs a process context */
 sock_init();
 
 do_initcalls();
 }
 ------------------------------------------------------------------------------------------------------
 其中的driver_init()做一些核心的初始化,看看代码就明白了.
 相应的驱动程序的初始化在do_initcalls()中做.
 ------------------------------------------------------------------------------------------------------
 static void __init do_initcalls(void)
 {
 initcall_t *call;
 int count = preempt_count();
 
 for (call = __initcall_start; call < __initcall_end; call++) {
 char *msg;
 
 if (initcall_debug) {
 printk(KERN_DEBUG "Calling initcall 0x%p", *call);
 print_fn_descriptor_symbol(": %s()", (unsigned long) *call);
 printk("\n");
 }
 
 (*call)();
 
 msg = NULL;
 if (preempt_count() != count) {
 msg = "preemption imbalance";
 preempt_count() = count;
 }
 if (irqs_disabled()) {
 msg = "disabled interrupts";
 local_irq_enable();
 }
 if (msg) {
 printk(KERN_WARNING "error in initcall at 0x%p: "
 "returned with %s\n", *call, msg);
 }
 }
 
 /* Make sure there is no pending stuff from the initcall sequence */
 flush_scheduled_work();
 }
 ------------------------------------------------------------------------------------------------------
 这个__initcall_start是在文件        arch/xxx/kernel/vmlinux.lds.S (其中的xxx 是你的体系结构的名称,例如i386)
 这个文件是内核ld的时候使用的.其中定义了各个sectioin,看看就明白了。
 在这个文件中有个.initcall.init, 代码如下:
 ------------------------------------------------------------------------------------------------------
 __initcall_start = .;
 .initcall.init : {
 *(.initcall1.init)
 *(.initcall2.init)
 *(.initcall3.init)
 *(.initcall4.init)
 *(.initcall5.init)
 *(.initcall6.init)
 *(.initcall7.init)
 }
 ------------------------------------------------------------------------------------------------------
 
 这里有7个初始化的优先级,内核会按照这个优先级的顺序依次加载.
 这些优先级是在文件include/linux/init.h 中定义的. 你注意一下宏 __define_initcall的实现就明白了.
 相关代码如下:
 
 
 #define __define_initcall(level,fn) \
 static initcall_t __initcall_##fn __attribute_used__ \
 __attribute__((__section__(".initcall" level ".init"))) = fn
 
 #define core_initcall(fn)                __define_initcall("1",fn)
 #define postcore_initcall(fn)                __define_initcall("2",fn)
 #define arch_initcall(fn)                __define_initcall("3",fn)
 #define subsys_initcall(fn)                __define_initcall("4",fn)
 #define fs_initcall(fn)                        __define_initcall("5",fn)
 #define device_initcall(fn)                __define_initcall("6",fn)
 #define late_initcall(fn)                __define_initcall("7",fn)
 
 
 我们可以看到,我们经常写的设备驱动程序中常用的module_init其实就是对应了优先级6:
 #define __initcall(fn) device_initcall(fn)
 
 #define module_init(x)        __initcall(x);
 
 ____________
 
 不过我怎么觉的你的问题不是由于加载顺序造成的?猜测而已.
 我也写过touchscreen 的驱动, 感觉touchscreen 用serio的多一些,也有用i2c的.
 你应该在自己的驱动里去封状这些的结构,一个input_dev结构,一个是serio(或着是i2c_driver),然后去控制加载顺序.
 module_init 中应该是注册i2c_driver, 然后在attach_adapter的时候再注册input_dev.
 
 
 
 | 
 |