diff options
author | Noralf Trønnes <noralf@tronnes.org> | 2016-04-28 11:18:34 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-05-02 10:24:49 -0400 |
commit | ba0263340a2aeaf5f08e4f2b0f4c29e300828b06 (patch) | |
tree | 47602035bd6b760a0d4fa93f1a9b1dc9401717f6 | |
parent | eaa434defaca1781fb2932c685289b610aeb8b4b (diff) |
fbdev: fb_defio: Export fb_deferred_io_mmap
Export fb_deferred_io_mmap so drivers can change vma->vm_page_prot.
When the framebuffer memory is allocated using dma_alloc_writecombine()
instead of vmalloc(), I get cache syncing problems on ARM.
This solves it:
static int drm_fbdev_cma_deferred_io_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
fb_deferred_io_mmap(info, vma);
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
return 0;
}
Could this have been done in the core?
Drivers that don't set (struct fb_ops *)->fb_mmap, gets a call to
fb_pgprotect() at the end of the default fb_mmap implementation
(drivers/video/fbdev/core/fbmem.c). This is an architecture specific
function that on many platforms uses pgprot_writecombine(), but not on
all. And looking at some of the fb_mmap implementations, some of them
sets vm_page_prot to nocache for instance, so I think the safest bet is
to do this in the driver and not in the fbdev core. And we can't call
fb_pgprotect() from fb_deferred_io_mmap() either because we don't have
access to the file pointer that powerpc needs.
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Acked-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1461856717-6476-5-git-send-email-noralf@tronnes.org
-rw-r--r-- | drivers/video/fbdev/core/fb_defio.c | 3 | ||||
-rw-r--r-- | include/linux/fb.h | 1 |
2 files changed, 3 insertions, 1 deletions
diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 57721c73177f..74b5bcac8bf2 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c | |||
@@ -164,7 +164,7 @@ static const struct address_space_operations fb_deferred_io_aops = { | |||
164 | .set_page_dirty = fb_deferred_io_set_page_dirty, | 164 | .set_page_dirty = fb_deferred_io_set_page_dirty, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) | 167 | int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) |
168 | { | 168 | { |
169 | vma->vm_ops = &fb_deferred_io_vm_ops; | 169 | vma->vm_ops = &fb_deferred_io_vm_ops; |
170 | vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; | 170 | vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; |
@@ -173,6 +173,7 @@ static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) | |||
173 | vma->vm_private_data = info; | 173 | vma->vm_private_data = info; |
174 | return 0; | 174 | return 0; |
175 | } | 175 | } |
176 | EXPORT_SYMBOL(fb_deferred_io_mmap); | ||
176 | 177 | ||
177 | /* workqueue callback */ | 178 | /* workqueue callback */ |
178 | static void fb_deferred_io_work(struct work_struct *work) | 179 | static void fb_deferred_io_work(struct work_struct *work) |
diff --git a/include/linux/fb.h b/include/linux/fb.h index dfe88351341f..a964d076b4dc 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -673,6 +673,7 @@ static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, | |||
673 | } | 673 | } |
674 | 674 | ||
675 | /* drivers/video/fb_defio.c */ | 675 | /* drivers/video/fb_defio.c */ |
676 | int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma); | ||
676 | extern void fb_deferred_io_init(struct fb_info *info); | 677 | extern void fb_deferred_io_init(struct fb_info *info); |
677 | extern void fb_deferred_io_open(struct fb_info *info, | 678 | extern void fb_deferred_io_open(struct fb_info *info, |
678 | struct inode *inode, | 679 | struct inode *inode, |