diff options
Diffstat (limited to 'drivers/video/fb_defio.c')
-rw-r--r-- | drivers/video/fb_defio.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 4835bdc4e9f1..082026546aee 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c | |||
@@ -24,6 +24,19 @@ | |||
24 | #include <linux/rmap.h> | 24 | #include <linux/rmap.h> |
25 | #include <linux/pagemap.h> | 25 | #include <linux/pagemap.h> |
26 | 26 | ||
27 | struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs) | ||
28 | { | ||
29 | void *screen_base = (void __force *) info->screen_base; | ||
30 | struct page *page; | ||
31 | |||
32 | if (is_vmalloc_addr(screen_base + offs)) | ||
33 | page = vmalloc_to_page(screen_base + offs); | ||
34 | else | ||
35 | page = pfn_to_page((info->fix.smem_start + offs) >> PAGE_SHIFT); | ||
36 | |||
37 | return page; | ||
38 | } | ||
39 | |||
27 | /* this is to find and return the vmalloc-ed fb pages */ | 40 | /* this is to find and return the vmalloc-ed fb pages */ |
28 | static int fb_deferred_io_fault(struct vm_area_struct *vma, | 41 | static int fb_deferred_io_fault(struct vm_area_struct *vma, |
29 | struct vm_fault *vmf) | 42 | struct vm_fault *vmf) |
@@ -31,14 +44,12 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma, | |||
31 | unsigned long offset; | 44 | unsigned long offset; |
32 | struct page *page; | 45 | struct page *page; |
33 | struct fb_info *info = vma->vm_private_data; | 46 | struct fb_info *info = vma->vm_private_data; |
34 | /* info->screen_base is virtual memory */ | ||
35 | void *screen_base = (void __force *) info->screen_base; | ||
36 | 47 | ||
37 | offset = vmf->pgoff << PAGE_SHIFT; | 48 | offset = vmf->pgoff << PAGE_SHIFT; |
38 | if (offset >= info->fix.smem_len) | 49 | if (offset >= info->fix.smem_len) |
39 | return VM_FAULT_SIGBUS; | 50 | return VM_FAULT_SIGBUS; |
40 | 51 | ||
41 | page = vmalloc_to_page(screen_base + offset); | 52 | page = fb_deferred_io_page(info, offset); |
42 | if (!page) | 53 | if (!page) |
43 | return VM_FAULT_SIGBUS; | 54 | return VM_FAULT_SIGBUS; |
44 | 55 | ||
@@ -60,6 +71,10 @@ int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
60 | { | 71 | { |
61 | struct fb_info *info = file->private_data; | 72 | struct fb_info *info = file->private_data; |
62 | 73 | ||
74 | /* Skip if deferred io is complied-in but disabled on this fbdev */ | ||
75 | if (!info->fbdefio) | ||
76 | return 0; | ||
77 | |||
63 | /* Kill off the delayed work */ | 78 | /* Kill off the delayed work */ |
64 | cancel_rearming_delayed_work(&info->deferred_work); | 79 | cancel_rearming_delayed_work(&info->deferred_work); |
65 | 80 | ||
@@ -184,7 +199,6 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open); | |||
184 | 199 | ||
185 | void fb_deferred_io_cleanup(struct fb_info *info) | 200 | void fb_deferred_io_cleanup(struct fb_info *info) |
186 | { | 201 | { |
187 | void *screen_base = (void __force *) info->screen_base; | ||
188 | struct fb_deferred_io *fbdefio = info->fbdefio; | 202 | struct fb_deferred_io *fbdefio = info->fbdefio; |
189 | struct page *page; | 203 | struct page *page; |
190 | int i; | 204 | int i; |
@@ -195,9 +209,12 @@ void fb_deferred_io_cleanup(struct fb_info *info) | |||
195 | 209 | ||
196 | /* clear out the mapping that we setup */ | 210 | /* clear out the mapping that we setup */ |
197 | for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { | 211 | for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { |
198 | page = vmalloc_to_page(screen_base + i); | 212 | page = fb_deferred_io_page(info, i); |
199 | page->mapping = NULL; | 213 | page->mapping = NULL; |
200 | } | 214 | } |
215 | |||
216 | info->fbops->fb_mmap = NULL; | ||
217 | mutex_destroy(&fbdefio->lock); | ||
201 | } | 218 | } |
202 | EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); | 219 | EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); |
203 | 220 | ||