fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / video / vfb.c
index 4fce711..a9b99b0 100644 (file)
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/tty.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
 #include <asm/uaccess.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 
 static void *videomemory;
 static u_long videomemorysize = VIDEOMEMSIZE;
-MODULE_PARM(videomemorysize, "l");
-
-static struct fb_info fb_info;
-static u32 vfb_pseudo_palette[17];
+module_param(videomemorysize, ulong, 0);
 
 static struct fb_var_screeninfo vfb_default __initdata = {
        .xres =         640,
@@ -73,13 +71,7 @@ static struct fb_fix_screeninfo vfb_fix __initdata = {
 };
 
 static int vfb_enable __initdata = 0;  /* disabled by default */
-MODULE_PARM(vfb_enable, "i");
-
-    /*
-     *  Interface used by the world
-     */
-int vfb_init(void);
-int vfb_setup(char *);
+module_param(vfb_enable, bool, 0);
 
 static int vfb_check_var(struct fb_var_screeninfo *var,
                         struct fb_info *info);
@@ -88,7 +80,7 @@ static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                         u_int transp, struct fb_info *info);
 static int vfb_pan_display(struct fb_var_screeninfo *var,
                           struct fb_info *info);
-static int vfb_mmap(struct fb_info *info, struct file *file,
+static int vfb_mmap(struct fb_info *info,
                    struct vm_area_struct *vma);
 
 static struct fb_ops vfb_ops = {
@@ -99,7 +91,6 @@ static struct fb_ops vfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_mmap        = vfb_mmap,
 };
 
@@ -376,13 +367,14 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
      *  Most drivers don't need their own mmap function 
      */
 
-static int vfb_mmap(struct fb_info *info, struct file *file,
+static int vfb_mmap(struct fb_info *info,
                    struct vm_area_struct *vma)
 {
        return -EINVAL;
 }
 
-int __init vfb_setup(char *options)
+#ifndef MODULE
+static int __init vfb_setup(char *options)
 {
        char *this_opt;
 
@@ -399,23 +391,22 @@ int __init vfb_setup(char *options)
        }
        return 1;
 }
+#endif  /*  MODULE  */
 
     /*
      *  Initialisation
      */
 
-int __init vfb_init(void)
+static int __init vfb_probe(struct platform_device *dev)
 {
-       int retval;
-
-       if (!vfb_enable)
-               return -ENXIO;
+       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 +416,111 @@ 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 = (char __iomem *)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;
 
-       fb_alloc_cmap(&fb_info.cmap, 256, 0);
+       retval = fb_alloc_cmap(&info->cmap, 256, 0);
+       if (retval < 0)
+               goto err1;
 
-       if (register_framebuffer(&fb_info) < 0) {
-               vfree(videomemory);
-               return -EINVAL;
-       }
+       retval = register_framebuffer(info);
+       if (retval < 0)
+               goto err2;
+       platform_set_drvdata(dev, info);
 
        printk(KERN_INFO
               "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
-              fb_info.node, videomemorysize >> 10);
+              info->node, videomemorysize >> 10);
        return 0;
+err2:
+       fb_dealloc_cmap(&info->cmap);
+err1:
+       framebuffer_release(info);
+err:
+       vfree(videomemory);
+       return retval;
 }
 
-#ifdef MODULE
+static int vfb_remove(struct platform_device *dev)
+{
+       struct fb_info *info = platform_get_drvdata(dev);
+
+       if (info) {
+               unregister_framebuffer(info);
+               vfree(videomemory);
+               framebuffer_release(info);
+       }
+       return 0;
+}
 
-static void __exit vfb_cleanup(void)
+static struct platform_driver vfb_driver = {
+       .probe  = vfb_probe,
+       .remove = vfb_remove,
+       .driver = {
+               .name   = "vfb",
+       },
+};
+
+static struct platform_device *vfb_device;
+
+static int __init vfb_init(void)
 {
-       unregister_framebuffer(&fb_info);
-       vfree(videomemory);
+       int ret = 0;
+
+#ifndef MODULE
+       char *option = NULL;
+
+       if (fb_get_options("vfb", &option))
+               return -ENODEV;
+       vfb_setup(option);
+#endif
+
+       if (!vfb_enable)
+               return -ENXIO;
+
+       ret = platform_driver_register(&vfb_driver);
+
+       if (!ret) {
+               vfb_device = platform_device_alloc("vfb", 0);
+
+               if (vfb_device)
+                       ret = platform_device_add(vfb_device);
+               else
+                       ret = -ENOMEM;
+
+               if (ret) {
+                       platform_device_put(vfb_device);
+                       platform_driver_unregister(&vfb_driver);
+               }
+       }
+
+       return ret;
 }
 
 module_init(vfb_init);
-module_exit(vfb_cleanup);
+
+#ifdef MODULE
+static void __exit vfb_exit(void)
+{
+       platform_device_unregister(vfb_device);
+       platform_driver_unregister(&vfb_driver);
+}
+
+module_exit(vfb_exit);
 
 MODULE_LICENSE("GPL");
 #endif                         /* MODULE */