Linux内核驱动加载顺序

【问题】
背光驱动初始化先于LCD驱动初始化,导致LCD驱动初始化时出现闪屏的现象。
【解决过程】
1 mach-xxx.c中platform devices列表如下
/* platform devices */
static struct platform_device *athena_evt_platform_devices[] __initdata = {
//&xxx_led_device,
&xxx_rtc_device,
&xxx_uart0_device,
&xxx_uart1_device,
&xxx_uart2_device,
&xxx_uart3_device,
&xxx_nand_device,
&xxx_i2c_device,

&xxx_lcd_device,
&xxxpwm_backlight_device,
        ...
};
LCD(xxx_lcd_device)设备先于PWM(xxxpwm_backlight_device)设备。
可见驱动的初始化顺序并不是和这个表定义的顺序始终保持一致的。(记得PM操作 - resume/suspend的顺序
是和这个表的顺序保持一致的)

2 怀疑和编译顺序有关
Z:\kernel\drivers\video\Makefile:背光驱动(backlight/)的编译限于LCD驱动(xxxfb.o)的编译
obj-$(CONFIG_VT)   += console/
obj-$(CONFIG_LOGO)   += logo/
obj-y   += backlight/ display/
...
obj-$(CONFIG_FB_xxx)   += xxxfb.o ak_logo.o
obj-$(CONFIG_FB_AK88)   += ak88-fb/
这样编译生成的System.map中的顺序为:
906 c001f540 t __initcall_pwm_backlight_init6
907 c001f544 t __initcall_display_class_init6
908 c001f548 t __initcall_xxxfb_init6

Makefile更改为:
obj-$(CONFIG_VT)   += console/
obj-$(CONFIG_LOGO)   += logo/
obj-y   += display/
...
obj-$(CONFIG_FB_xxx)   += xxxfb.o ak_logo.o
obj-$(CONFIG_FB_AK88)   += ak88-fb/
obj-y   += backlight/
这样编译生成的System.map中的顺序为:
905 c001f53c t __initcall_display_class_init6
906 c001f540 t __initcall_xxxfb_init6
907 c001f544 t __initcall_genericbl_init6
908 c001f548 t __initcall_pwm_backlight_init6

加载运行:
xxxpwm_backlight_device的probe就会在xxx_lcd_device的probe之后执行,即LCD初始化先于PWM的初始化。

【结论】
同一级别的初始化是和编译顺序有关的,并不是和设备列表一致。
调整驱动加载顺序还可以通过使用不同级别的初始化,例如:
subsys_initcall()
module_init()
late_initcall()
...

原文地址:https://www.cnblogs.com/spinsoft/p/2596882.html