mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 05:02:31 +00:00
fbdev: Move default fb_mmap code into helper function
Move the default fb_mmap code for I/O address spaces into the helper function fb_io_mmap(). The helper can either be called via struct fb_ops.fb_mmap or as the default if no fb_mmap has been set. Also set the new helper in __FB_DEFAULT_IOMEM_OPS_MMAP. In the mid-term, fb_io_mmap() is supposed to become optional. Fbdev drivers will initialize their struct fb_ops.fb_mmap to the helper and select a corresponding Kconfig token. The helper can then be made optional at compile time. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231127131655.4020-31-tzimmermann@suse.de
This commit is contained in:
parent
76f92201b8
commit
33253d9e01
@ -314,20 +314,16 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
static int fb_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
struct fb_info *info = file_fb_info(file);
|
||||
unsigned long mmio_pgoff;
|
||||
unsigned long start;
|
||||
u32 len;
|
||||
int res;
|
||||
|
||||
if (!info)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&info->mm_lock);
|
||||
|
||||
if (info->fbops->fb_mmap) {
|
||||
int res;
|
||||
|
||||
res = info->fbops->fb_mmap(info, vma);
|
||||
mutex_unlock(&info->mm_lock);
|
||||
return res;
|
||||
#if IS_ENABLED(CONFIG_FB_DEFERRED_IO)
|
||||
} else if (info->fbdefio) {
|
||||
/*
|
||||
@ -335,35 +331,15 @@ static int fb_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
* minimum, point struct fb_ops.fb_mmap to fb_deferred_io_mmap().
|
||||
*/
|
||||
dev_warn_once(info->dev, "fbdev mmap not set up for deferred I/O.\n");
|
||||
mutex_unlock(&info->mm_lock);
|
||||
return -ENODEV;
|
||||
res = -ENODEV;
|
||||
#endif
|
||||
} else {
|
||||
res = fb_io_mmap(info, vma);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ugh. This can be either the frame buffer mapping, or
|
||||
* if pgoff points past it, the mmio mapping.
|
||||
*/
|
||||
start = info->fix.smem_start;
|
||||
len = info->fix.smem_len;
|
||||
mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
|
||||
if (vma->vm_pgoff >= mmio_pgoff) {
|
||||
if (info->var.accel_flags) {
|
||||
mutex_unlock(&info->mm_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vma->vm_pgoff -= mmio_pgoff;
|
||||
start = info->fix.mmio_start;
|
||||
len = info->fix.mmio_len;
|
||||
}
|
||||
mutex_unlock(&info->mm_lock);
|
||||
|
||||
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
|
||||
vma->vm_page_prot = pgprot_framebuffer(vma->vm_page_prot, vma->vm_start,
|
||||
vma->vm_end, start);
|
||||
|
||||
return vm_iomap_memory(vma, start, len);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fb_open(struct inode *inode, struct file *file)
|
||||
|
@ -132,5 +132,32 @@ ssize_t fb_io_write(struct fb_info *info, const char __user *buf, size_t count,
|
||||
}
|
||||
EXPORT_SYMBOL(fb_io_write);
|
||||
|
||||
int fb_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long start = info->fix.smem_start;
|
||||
u32 len = info->fix.smem_len;
|
||||
unsigned long mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
|
||||
|
||||
/*
|
||||
* This can be either the framebuffer mapping, or if pgoff points
|
||||
* past it, the mmio mapping.
|
||||
*/
|
||||
if (vma->vm_pgoff >= mmio_pgoff) {
|
||||
if (info->var.accel_flags)
|
||||
return -EINVAL;
|
||||
|
||||
vma->vm_pgoff -= mmio_pgoff;
|
||||
start = info->fix.mmio_start;
|
||||
len = info->fix.mmio_len;
|
||||
}
|
||||
|
||||
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
|
||||
vma->vm_page_prot = pgprot_framebuffer(vma->vm_page_prot, vma->vm_start,
|
||||
vma->vm_end, start);
|
||||
|
||||
return vm_iomap_memory(vma, start, len);
|
||||
}
|
||||
EXPORT_SYMBOL(fb_io_mmap);
|
||||
|
||||
MODULE_DESCRIPTION("Fbdev helpers for framebuffers in I/O memory");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -536,6 +536,7 @@ extern ssize_t fb_io_read(struct fb_info *info, char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
extern ssize_t fb_io_write(struct fb_info *info, const char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
int fb_io_mmap(struct fb_info *info, struct vm_area_struct *vma);
|
||||
|
||||
#define __FB_DEFAULT_IOMEM_OPS_RDWR \
|
||||
.fb_read = fb_io_read, \
|
||||
@ -547,7 +548,7 @@ extern ssize_t fb_io_write(struct fb_info *info, const char __user *buf,
|
||||
.fb_imageblit = cfb_imageblit
|
||||
|
||||
#define __FB_DEFAULT_IOMEM_OPS_MMAP \
|
||||
.fb_mmap = NULL /* default implementation */
|
||||
.fb_mmap = fb_io_mmap
|
||||
|
||||
#define FB_DEFAULT_IOMEM_OPS \
|
||||
__FB_DEFAULT_IOMEM_OPS_RDWR, \
|
||||
|
Loading…
Reference in New Issue
Block a user