s3c2410fb_probe 分析:
 帧缓冲设备涉及的重要数据结构分析:
 static struct s3c2410fb_mach_info *mach_info;
 struct s3c2410fb_hw regs;
 struct s3c2410fb_hw {
 unsigned long lcdcon1;
 unsigned long lcdcon2;
 unsigned long lcdcon3;
 unsigned long lcdcon4;
 unsigned long lcdcon5;
 };
 struct fb_info {
 struct fb_var_screeninfo var/* 可变参数*/
 struct fb_fix_screeninfo fix; /* 固定参数*/
 struct fb_ops *fbops; /*操作底层硬件的方法*/

 char __iomem *screen_base; /*虚拟地址 */
 unsigned long screen_size;
 };
 struct fb_fix_screeninfo {
 unsigned long smem_start; /*物理地址*/
 __u32 smem_len; /*显存的大小 240*320*/
 __u32 line_length; /*一行的大小 */
 };

 __init s3c2410fb_probe(struct platform_device *pdev)
 /*构建一个 fb_info 结构体,用来描述一个帧缓冲设备*/
 struct s3c2410fb_info *info;
 struct fb_info *fbinfo;
 /*获取 lcd 屏的控制器配置参数*/ /*这个地方的资源在 mach-smdk2410.c 文件中,如果换了屏就要该相应的参数*/
 mach_info = pdev->dev.platform_data;
 /*2. 放到以个结构体里面*/
 mregs = &mach_info->regs;
 /*3.获取中断资源*/
 irq = platform_get_irq(pdev, 0);
 /*4.分配 fb_info 结构体*/
 fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);
 /*5.设置固定参数*/
 /* 6.设置可变参数*/
 /*7.申请 irq */
 /*8.使能 lcd 时钟*/
 /*9.分配内存空间*/
 ret = s3c2410fb_map_video_memory(info);
 /*对齐*/
 fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE);
 /*分配缓冲区*/
 fbi->map_cpu( (内核空间)虚拟地址) = dma_alloc_writecombine(fbi->dev, fbi->map_size,
 &fbi->map_dma(物理地址), GFP_KERNEL);
 /*这只 lcd 控制的几个寄存器*/
 ret = s3c2410fb_init_registers(info);
 /*向上注册*/
 ret = register_framebuffer(fbinfo);
 /*搜索数组,看那项是空的*/
 for (i = 0 ; i < FB_MAX; i++)
 if (!registered_fb[i])
 /*创建一个设备节点。在fbmem.c层只创建类,在此处LCD控制器驱动中创建fb_info结构体同时向上层注册之后才创建设备节点*/
fb_info->dev = device_create(fb_class, fb_info->device,
 MKDEV(FB_MAJOR, i), "fb%d", i);
 /*将 fb_info 加入到数组中*/
 registered_fb[i] = fb_info;