日期:2014-05-16  浏览次数:20754 次

我对linux理解之framebuffer
我们看下imx51的lcd控制器的驱动:
int __init mxcfb_init(void)
{
    int ret;

    ret = platform_driver_register(&mxcfb_driver);
    if (!ret)
        register_early_suspend(&fbdrv_earlysuspend);
    return ret;
}
mxcfb_driver定义如下:
static struct platform_driver mxcfb_driver = {
    .driver = {
           .name = MXCFB_NAME,
           },
    .probe = mxcfb_probe,
    .remove = mxcfb_remove,
    .suspend = mxcfb_suspend,
    .resume = mxcfb_resume,
};
我们知道这里platform匹配后将会执行mxcfb_probe:
static int mxcfb_probe(struct platform_device *pdev)
{
    struct fb_info *fbi;
    struct mxcfb_info *mxcfbi;
    struct mxc_fb_platform_data *plat_data = pdev->dev.platform_data;
    struct resource *res;
    char *options;
    char name[] = "mxcdi0fb";
    int ret = 0;

    /*
     * Initialize FB structures
     */
    fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);//这边涉及到ops的赋值,这个很重要,后面framebuffer子系统中好多都用到相应的ops操作
    if (!fbi) {
        ret = -ENOMEM;
        goto err0;
    }
    mxcfbi = (struct mxcfb_info *)fbi->par;

    name[5] += pdev->id;
    if (fb_get_options(name, &options))//从启动命令里面得到options
        return -ENODEV;

    if (options)
        mxcfb_option_setup(fbi, options);//根据得到的options设置信息

    if (!g_dp_in_use) {
        mxcfbi->ipu_ch_irq = IPU_IRQ_BG_SYNC_EOF;
        mxcfbi->ipu_ch = MEM_BG_SYNC;
        mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_UNBLANK;
    } else {
        mxcfbi->ipu_ch_irq = IPU_IRQ_DC_SYNC_EOF;
        mxcfbi->ipu_ch = MEM_DC_SYNC;
        mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
    }

    mxcfbi->ipu_di = pdev->id;

    if (pdev->id == 0) {//对应fb0
        ipu_disp_set_global_alpha(mxcfbi->ipu_ch, true, 0x80);
        ipu_disp_set_color_key(mxcfbi->ipu_ch, false, 0);
        strcpy(fbi->fix.id, "DISP3 BG");

        if (!g_dp_in_use)
            if (ipu_request_irq(IPU_IRQ_BG_ALPHA_SYNC_EOF,
                        mxcfb_alpha_irq_handler, 0,
                        MXCFB_NAME, fbi) != 0) {
                dev_err(&pdev->dev, "Error registering BG "
                    "alpha irq handler.\n");
                ret = -EBUSY;
                goto err1;
            }
        g_dp_in_use = true;
    } else if