X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fvfb.c;h=a9b99b01bd8e377f2656058bd29b09accb7ef6ea;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=4fce711339a2e98177d49cf4865bc7906956e75c;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index 4fce71133..a9b99b01b 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c @@ -15,11 +15,12 @@ #include #include #include -#include #include #include #include #include +#include + #include #include #include @@ -35,10 +36,7 @@ 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 */