硬件平台:mini2440 + TD035STED4 软件平台:linux-2.6.32.2 日期:2012/07/04
首先看驱动模块的初始化函数:
/* drivers/video/s3c2410fb.c */
1119 int __init s3c2410fb_init(void)
1120 {
1121 int ret = platform_driver_register(&s3c2410fb_driver);
1122
1123 if (ret == 0)
1124 ret = platform_driver_register(&s3c2412fb_driver);
1125
1126 return ret;
1127 }
1128
1129 static void __exit s3c2410fb_cleanup(void)
1130 {
1131 platform_driver_unregister(&s3c2410fb_driver);
1132 platform_driver_unregister(&s3c2412fb_driver);
1133 }
初始化函数里面就注册了一个平台设备驱动。
再来看驱动模块卸载函数:
1129 static void __exit s3c2410fb_cleanup(void)
1130 {
1131 platform_driver_unregister(&s3c2410fb_driver);
1132 platform_driver_unregister(&s3c2412fb_driver);
1133 }
卸载函数里面注销平台设备驱动。
s3c2440自然采用的是s3c2410fb_driver,我们来看这个结构的定义:
1097 static struct platform_driver s3c2410fb_driver = {
1098 .probe = s3c2410fb_probe,
1099 .remove = s3c2410fb_remove,
1100 .suspend = s3c2410fb_suspend,
1101 .resume = s3c2410fb_resume,
1102 .driver = {
1103 .name = "s3c2410-lcd",
1104 .owner = THIS_MODULE,
1105 },
1106 };
我们看driver中的name字段为s3c2410-lcd,那自然去找与之对应的平台设备。
我们在devs.c中找到了这个平台设备的定义:
/* arch/arm/plat-s3c24xx/devs.c */
141 /* LCD Controller */
142
143 static struct resource s3c_lcd_resource[] = {
144 [0] = {
145 .start = S3C24XX_PA_LCD,
146 .end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
147 .flags = IORESOURCE_MEM,
148 },
149 [1] = {
150 .start = IRQ_LCD,
151 .end = IRQ_LCD,
152 .flags = IORESOURCE_IRQ,
153 }
154
155 };
156
157 static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
158
159 struct platform_device s3c_device_lcd = {
160 .name = "s3c2410-lcd",
161 .id = -1,
162 .num_resources = ARRAY_SIZE(s3c_lcd_resource),
163 .resource = s3c_lcd_resource,
164 .dev = {
165 .dma_mask = &s3c_device_lcd_dmamask,
166 .coherent_dma_mask = 0xffffffffUL
167 }
168 };
169
170 EXPORT_SYMBOL(s3c_device_lcd);
平台设备也有了,平台设备注册进了内核之后,那自然会调用驱动中的probe函数。
815 static char driver_name[] = "s3c2410fb";
816
817 static int __init s3c24xxfb_probe(struct platform_device *pdev,
818 enum s3c_drv_type drv_type)
819 {
820 struct s3c2410fb_info *info;
821 struct s3c2410fb_display *display;
822 struct fb_info *fbinfo;
823 struct s3c2410fb_mach_info *mach_info;
824 struct resource *res;
825 int ret;
826 int irq;
827 int i;
828 int size;
829 u32 lcdcon1;
830
831 mach_info = pdev->dev.platform_data;
832 if (mach_info == NULL) {
833 dev_err(&pdev->dev,
834 "no platform data for lcd, cannot attachn");
835 return -EINVAL;
836 }
837
838 if (mach_info->default_display >= mach_info->num_displays) {
839 dev_err(&pdev->dev, "default is %d but only %d displaysn",
840 mach_info->default_display, mach_info->num_displays);
841 return -EINVAL;
842 }
843
844 display = mach_info->displays + mach_info->default_display;
845
846 irq = platform_get_irq(pdev, 0);
847 if (irq < 0) {
848 dev_err(&pdev->dev, "no irq for devicen");
849 return -ENOENT;
850 }
851
852 fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);
853 if (!fbinfo)
854 return -ENOMEM;
855
856 platform_set_drvdata(pdev, fbinfo);
857
858 info = fbinfo->par;
859 info->dev = &pdev->dev;
860 info->drv_type = drv_type;
861
862 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
863 if (res == NULL) {
864 dev_err(&pdev->dev, "failed to get memory registersn");
865 ret = -ENXIO;
866 goto dealloc_fb;