summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/vfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/vfb.c')
-rw-r--r--drivers/video/fbdev/vfb.c129
1 files changed, 27 insertions, 102 deletions
diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index b9c2f81fb6b9..da653a080394 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -35,76 +35,23 @@
static void *videomemory;
static u_long videomemorysize = VIDEOMEMSIZE;
module_param(videomemorysize, ulong, 0);
+MODULE_PARM_DESC(videomemorysize, "RAM available to frame buffer (in bytes)");
-/**********************************************************************
- *
- * Memory management
- *
- **********************************************************************/
-static void *rvmalloc(unsigned long size)
-{
- void *mem;
- unsigned long adr;
-
- size = PAGE_ALIGN(size);
- mem = vmalloc_32(size);
- if (!mem)
- return NULL;
-
- /*
- * VFB must clear memory to prevent kernel info
- * leakage into userspace
- * VGA-based drivers MUST NOT clear memory if
- * they want to be able to take over vgacon
- */
-
- memset(mem, 0, size);
- adr = (unsigned long) mem;
- while (size > 0) {
- SetPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- return mem;
-}
-
-static void rvfree(void *mem, unsigned long size)
-{
- unsigned long adr;
-
- if (!mem)
- return;
-
- adr = (unsigned long) mem;
- while ((long) size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree(mem);
-}
+static char *mode_option = NULL;
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Preferred video mode (e.g. 640x480-8@60)");
-static struct fb_var_screeninfo vfb_default = {
+static const struct fb_videomode vfb_default = {
.xres = 640,
.yres = 480,
- .xres_virtual = 640,
- .yres_virtual = 480,
- .bits_per_pixel = 8,
- .red = { 0, 8, 0 },
- .green = { 0, 8, 0 },
- .blue = { 0, 8, 0 },
- .activate = FB_ACTIVATE_TEST,
- .height = -1,
- .width = -1,
- .pixclock = 20000,
- .left_margin = 64,
- .right_margin = 64,
- .upper_margin = 32,
- .lower_margin = 32,
- .hsync_len = 64,
- .vsync_len = 2,
- .vmode = FB_VMODE_NONINTERLACED,
+ .pixclock = 20000,
+ .left_margin = 64,
+ .right_margin = 64,
+ .upper_margin = 32,
+ .lower_margin = 32,
+ .hsync_len = 64,
+ .vsync_len = 2,
+ .vmode = FB_VMODE_NONINTERLACED,
};
static struct fb_fix_screeninfo vfb_fix = {
@@ -119,6 +66,7 @@ static struct fb_fix_screeninfo vfb_fix = {
static bool vfb_enable __initdata = 0; /* disabled by default */
module_param(vfb_enable, bool, 0);
+MODULE_PARM_DESC(vfb_enable, "Enable Virtual FB driver");
static int vfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info);
@@ -421,35 +369,7 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
static int vfb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
- unsigned long start = vma->vm_start;
- unsigned long size = vma->vm_end - vma->vm_start;
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long page, pos;
-
- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
- return -EINVAL;
- if (size > info->fix.smem_len)
- return -EINVAL;
- if (offset > info->fix.smem_len - size)
- return -EINVAL;
-
- pos = (unsigned long)info->fix.smem_start + offset;
-
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
-
- return 0;
-
+ return remap_vmalloc_range(vma, (void *)info->fix.smem_start, vma->vm_pgoff);
}
#ifndef MODULE
@@ -477,6 +397,8 @@ static int __init vfb_setup(char *options)
/* Test disable for backwards compatibility */
if (!strcmp(this_opt, "disable"))
vfb_enable = 0;
+ else
+ mode_option = this_opt;
}
return 1;
}
@@ -489,12 +411,13 @@ static int __init vfb_setup(char *options)
static int vfb_probe(struct platform_device *dev)
{
struct fb_info *info;
+ unsigned int size = PAGE_ALIGN(videomemorysize);
int retval = -ENOMEM;
/*
* For real video cards we use ioremap.
*/
- if (!(videomemory = rvmalloc(videomemorysize)))
+ if (!(videomemory = vmalloc_32_user(size)))
return retval;
info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
@@ -504,11 +427,13 @@ static int vfb_probe(struct platform_device *dev)
info->screen_base = (char __iomem *)videomemory;
info->fbops = &vfb_ops;
- retval = fb_find_mode(&info->var, info, NULL,
- NULL, 0, NULL, 8);
+ if (!fb_find_mode(&info->var, info, mode_option,
+ NULL, 0, &vfb_default, 8)){
+ fb_err(info, "Unable to find usable video mode.\n");
+ retval = -EINVAL;
+ goto err1;
+ }
- if (!retval || (retval == 4))
- info->var = vfb_default;
vfb_fix.smem_start = (unsigned long) videomemory;
vfb_fix.smem_len = videomemorysize;
info->fix = vfb_fix;
@@ -533,7 +458,7 @@ err2:
err1:
framebuffer_release(info);
err:
- rvfree(videomemory, videomemorysize);
+ vfree(videomemory);
return retval;
}
@@ -543,7 +468,7 @@ static int vfb_remove(struct platform_device *dev)
if (info) {
unregister_framebuffer(info);
- rvfree(videomemory, videomemorysize);
+ vfree(videomemory);
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}