Commit 33253d9e authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

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: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231127131655.4020-31-tzimmermann@suse.de
parent 76f92201
Loading
Loading
Loading
Loading
+6 −30
Original line number Diff line number Diff line
@@ -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)
+27 −0
Original line number Diff line number Diff line
@@ -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");
+2 −1
Original line number Diff line number Diff line
@@ -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, \