From: James Simmons <jsimmons@infradead.org>

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 */

_