对于该函数,我想最好的办法就是跟着程序一步一步的解释。OK
static int __init s3c2410fb_probe(struct platform_device *pdev)
{
struct s3c2410 fb_info *info; //s3c2410fb_info
//
struct fb_info *fbinfo; /* fb_info
struct s3c2410fb_hw *mregs; // s3c2410fb_hw
//
……
mach_info = pdev->dev.platform_data; /*
这条语句,s3c24xx_fb_set_platdata()
void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
{
s3c_device_lcd.dev.platform_data = pd;
}
根据这些代码,可以清楚的看到s3c_device_lcd.dev.platform_data
if (mach_info == NULL) {
dev_err(&pdev->dev,"no platform data for lcd, cannot attach\n");
return -EINVAL;
}
mregs = &mach_info->regs; //mregs
//
irq = platform_get_irq(pdev, 0); /*
if (irq < 0) { //
dev_err(&pdev->dev, "no irq for device\n");
return -ENOENT;
}
fbinfo = buffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev); /* buffer_alloc
if (!fbinfo) {
return -ENOMEM;
}
//
info = fbinfo->par; //
info->fb = fbinfo;
platform_set_drvdata(pdev, fbinfo); /*
dprintk("devinit\n");
strcpy(fbinfo->fix.id, driver_name);
memcpy(&info->regs, &mach_info->regs, sizeof(info->regs));
/* Stop the video and unset ENVID if set */
info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
lcdcon1 = readl(S3C2410_LCDCON1);
writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);//
/*
……
for (i = 0; i < 256; i++) //
info->palette_buffer
if (!request_mem_region((unsigned long)S3C24XX_VA_LCD, SZ_1M, "s3c2410-lcd")) {
/*
ret = -EBUSY;
goto dealloc_fb;
}
……
ret = request_irq(irq, s3c2410fb_irq, IRQF_DISABLED, pdev->name, info);/*
if (ret) {
dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret);
ret = -EBUSY;
goto release_mem;
}
info->clk = clk_get(NULL, "lcd"); //
//
if (!info->clk || IS_ERR(info->clk)) {
printk(KERN_ERR "failed to get lcd clock source\n");
ret = -ENOENT;
goto release_irq; //
}
clk_enable(info->clk); //
dprintk("got and enabled clock\n");
msleep(1); //
/* Initialize video memory */
ret = s3c2410fb_map_video_memory(info);
if (ret) {
printk( KERN_ERR "Failed to allocate video RAM: %d\n", ret);
ret = -ENOMEM;
goto release_clock; //
}
dprintk("got video memory\n");
ret = s3c2410fb_init_registers(info); //
ret = s3c2410fb_check_var(&fbinfo->var, fbinfo); //
ret = register_buffer(fbinfo); //
if (ret < 0) {
printk(KERN_ERR "Failed to register buffer device: %d\n", ret);
goto free_video_memory; //
}
/* create device files */
device_create_file(&pdev->dev, &dev_attr_debug); //
printk(KERN_INFO "fb%d: %s buffer device\n",
fbinfo->node, fbinfo->fix.id);
return 0; //
free_video_memory:
s3c2410fb_unmap_video_memory(info);
release_clock:
clk_disable(info->clk);
clk_put(info->clk);
release_irq:
free_irq(irq,info);
release_mem:
release_mem_region((unsigned long)S3C24XX_VA_LCD, S3C24XX_SZ_LCD);
dealloc_fb:
buffer_release(fbinfo);
return ret;
}
转载自:http://blog.21ic.com/user1/5823/archives/2009/60263.html