aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/vfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/vfb.c')
-rw-r--r--drivers/video/vfb.c79
1 files changed, 74 insertions, 5 deletions
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 64ee78c3c12b..072638a9528a 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -21,7 +21,6 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23 23
24#include <asm/uaccess.h>
25#include <linux/fb.h> 24#include <linux/fb.h>
26#include <linux/init.h> 25#include <linux/init.h>
27 26
@@ -38,6 +37,48 @@ static void *videomemory;
38static u_long videomemorysize = VIDEOMEMSIZE; 37static u_long videomemorysize = VIDEOMEMSIZE;
39module_param(videomemorysize, ulong, 0); 38module_param(videomemorysize, ulong, 0);
40 39
40/**********************************************************************
41 *
42 * Memory management
43 *
44 **********************************************************************/
45static void *rvmalloc(unsigned long size)
46{
47 void *mem;
48 unsigned long adr;
49
50 size = PAGE_ALIGN(size);
51 mem = vmalloc_32(size);
52 if (!mem)
53 return NULL;
54
55 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
56 adr = (unsigned long) mem;
57 while (size > 0) {
58 SetPageReserved(vmalloc_to_page((void *)adr));
59 adr += PAGE_SIZE;
60 size -= PAGE_SIZE;
61 }
62
63 return mem;
64}
65
66static void rvfree(void *mem, unsigned long size)
67{
68 unsigned long adr;
69
70 if (!mem)
71 return;
72
73 adr = (unsigned long) mem;
74 while ((long) size > 0) {
75 ClearPageReserved(vmalloc_to_page((void *)adr));
76 adr += PAGE_SIZE;
77 size -= PAGE_SIZE;
78 }
79 vfree(mem);
80}
81
41static struct fb_var_screeninfo vfb_default __initdata = { 82static struct fb_var_screeninfo vfb_default __initdata = {
42 .xres = 640, 83 .xres = 640,
43 .yres = 480, 84 .yres = 480,
@@ -372,7 +413,33 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
372static int vfb_mmap(struct fb_info *info, 413static int vfb_mmap(struct fb_info *info,
373 struct vm_area_struct *vma) 414 struct vm_area_struct *vma)
374{ 415{
375 return -EINVAL; 416 unsigned long start = vma->vm_start;
417 unsigned long size = vma->vm_end - vma->vm_start;
418 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
419 unsigned long page, pos;
420
421 if (offset + size > info->fix.smem_len) {
422 return -EINVAL;
423 }
424
425 pos = (unsigned long)info->fix.smem_start + offset;
426
427 while (size > 0) {
428 page = vmalloc_to_pfn((void *)pos);
429 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
430 return -EAGAIN;
431 }
432 start += PAGE_SIZE;
433 pos += PAGE_SIZE;
434 if (size > PAGE_SIZE)
435 size -= PAGE_SIZE;
436 else
437 size = 0;
438 }
439
440 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
441 return 0;
442
376} 443}
377 444
378#ifndef MODULE 445#ifndef MODULE
@@ -407,7 +474,7 @@ static int __init vfb_probe(struct platform_device *dev)
407 /* 474 /*
408 * For real video cards we use ioremap. 475 * For real video cards we use ioremap.
409 */ 476 */
410 if (!(videomemory = vmalloc(videomemorysize))) 477 if (!(videomemory = rvmalloc(videomemorysize)))
411 return retval; 478 return retval;
412 479
413 /* 480 /*
@@ -430,6 +497,8 @@ static int __init vfb_probe(struct platform_device *dev)
430 497
431 if (!retval || (retval == 4)) 498 if (!retval || (retval == 4))
432 info->var = vfb_default; 499 info->var = vfb_default;
500 vfb_fix.smem_start = (unsigned long) videomemory;
501 vfb_fix.smem_len = videomemorysize;
433 info->fix = vfb_fix; 502 info->fix = vfb_fix;
434 info->pseudo_palette = info->par; 503 info->pseudo_palette = info->par;
435 info->par = NULL; 504 info->par = NULL;
@@ -453,7 +522,7 @@ err2:
453err1: 522err1:
454 framebuffer_release(info); 523 framebuffer_release(info);
455err: 524err:
456 vfree(videomemory); 525 rvfree(videomemory, videomemorysize);
457 return retval; 526 return retval;
458} 527}
459 528
@@ -463,7 +532,7 @@ static int vfb_remove(struct platform_device *dev)
463 532
464 if (info) { 533 if (info) {
465 unregister_framebuffer(info); 534 unregister_framebuffer(info);
466 vfree(videomemory); 535 rvfree(videomemory, videomemorysize);
467 framebuffer_release(info); 536 framebuffer_release(info);
468 } 537 }
469 return 0; 538 return 0;