From: James Simmons This is attempt 2 at the virtual framebuffer patch. It migrates the driver to the framebuffer_release/framebuffer_alloc api. It doesn't enable the driver by default. --- 25-akpm/drivers/video/vfb.c | 112 +++++++++++++++++++++++++++++++++----------- 1 files changed, 85 insertions(+), 27 deletions(-) diff -puN drivers/video/vfb.c~virtual-fbdev-updates drivers/video/vfb.c --- 25/drivers/video/vfb.c~virtual-fbdev-updates 2004-04-25 22:10:08.355973608 -0700 +++ 25-akpm/drivers/video/vfb.c 2004-04-25 22:10:08.359973000 -0700 @@ -37,9 +37,6 @@ static void *videomemory; static u_long videomemorysize = VIDEOMEMSIZE; MODULE_PARM(videomemorysize, "l"); -static struct fb_info fb_info; -static u32 vfb_pseudo_palette[17]; - static struct fb_var_screeninfo vfb_default __initdata = { .xres = 640, .yres = 480, @@ -404,18 +401,22 @@ int __init vfb_setup(char *options) * Initialisation */ -int __init vfb_init(void) +static void vfb_platform_release(struct device *device) { - int retval; + // This is called when the reference count goes to zero. +} - if (!vfb_enable) - return -ENXIO; +static int __init vfb_probe(struct device *device) +{ + struct platform_device *dev = to_platform_device(device); + struct fb_info *info; + int retval = -ENOMEM; /* * For real video cards we use ioremap. */ if (!(videomemory = vmalloc(videomemorysize))) - return -ENOMEM; + return retval; /* * VFB must clear memory to prevent kernel info @@ -425,41 +426,98 @@ int __init vfb_init(void) */ memset(videomemory, 0, videomemorysize); - fb_info.screen_base = videomemory; - fb_info.fbops = &vfb_ops; + info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev); + if (!info) + goto err; - retval = fb_find_mode(&fb_info.var, &fb_info, NULL, + info->screen_base = videomemory; + info->fbops = &vfb_ops; + + retval = fb_find_mode(&info->var, info, NULL, NULL, 0, NULL, 8); if (!retval || (retval == 4)) - fb_info.var = vfb_default; - fb_info.fix = vfb_fix; - fb_info.pseudo_palette = &vfb_pseudo_palette; - fb_info.flags = FBINFO_FLAG_DEFAULT; + info->var = vfb_default; + info->fix = vfb_fix; + info->pseudo_palette = info->par; + info->par = NULL; + info->flags = FBINFO_FLAG_DEFAULT; + + retval = fb_alloc_cmap(&info->cmap, 256, 0); + if (retval < 0) + goto err1; + + retval = register_framebuffer(info); + if (retval < 0) + goto err2; + dev_set_drvdata(&dev->dev, info); + + printk(KERN_INFO + "fb%d: Virtual frame buffer device, using %ldK of video memory\n", + info->node, videomemorysize >> 10); + return 0; +err2: + fb_dealloc_cmap(&info->cmap); +err1: + framebuffer_release(info); +err: + vfree(videomemory); + return retval; +} - fb_alloc_cmap(&fb_info.cmap, 256, 0); +static int vfb_remove(struct device *device) +{ + struct fb_info *info = dev_get_drvdata(device); - if (register_framebuffer(&fb_info) < 0) { + if (info) { + unregister_framebuffer(info); vfree(videomemory); - return -EINVAL; + framebuffer_release(info); } - - printk(KERN_INFO - "fb%d: Virtual frame buffer device, using %ldK of video memory\n", - fb_info.node, videomemorysize >> 10); return 0; } -#ifdef MODULE +static struct device_driver vfb_driver = { + .name = "vfb", + .bus = &platform_bus_type, + .probe = vfb_probe, + .remove = vfb_remove, +}; -static void __exit vfb_cleanup(void) +static struct platform_device vfb_device = { + .name = "vfb", + .id = 0, + .dev = { + .release = vfb_platform_release, + } +}; + +int __init vfb_init(void) { - unregister_framebuffer(&fb_info); - vfree(videomemory); + int ret = 0; + + if (!vfb_enable) + return -ENXIO; + + ret = driver_register(&vfb_driver); + + if (!ret) { + ret = platform_device_register(&vfb_device); + if (ret) + driver_unregister(&vfb_driver); + } + return ret; +} + +#ifdef MODULE +static void __exit vfb_exit(void) +{ + platform_device_unregister(&vfb_device); + driver_unregister(&vfb_driver); } module_init(vfb_init); -module_exit(vfb_cleanup); +module_exit(vfb_exit); MODULE_LICENSE("GPL"); #endif /* MODULE */ _