Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+35 -31
+6 -30
drivers/video/fbdev/core/fb_chrdev.c
··· 314 314 static int fb_mmap(struct file *file, struct vm_area_struct *vma) 315 315 { 316 316 struct fb_info *info = file_fb_info(file); 317 - unsigned long mmio_pgoff; 318 - unsigned long start; 319 - u32 len; 317 + int res; 320 318 321 319 if (!info) 322 320 return -ENODEV; 321 + 323 322 mutex_lock(&info->mm_lock); 324 323 325 324 if (info->fbops->fb_mmap) { 326 - int res; 327 325 328 326 res = info->fbops->fb_mmap(info, vma); 329 - mutex_unlock(&info->mm_lock); 330 - return res; 331 327 #if IS_ENABLED(CONFIG_FB_DEFERRED_IO) 332 328 } else if (info->fbdefio) { 333 329 /* ··· 331 335 * minimum, point struct fb_ops.fb_mmap to fb_deferred_io_mmap(). 332 336 */ 333 337 dev_warn_once(info->dev, "fbdev mmap not set up for deferred I/O.\n"); 334 - mutex_unlock(&info->mm_lock); 335 - return -ENODEV; 338 + res = -ENODEV; 336 339 #endif 340 + } else { 341 + res = fb_io_mmap(info, vma); 337 342 } 338 343 339 - /* 340 - * Ugh. This can be either the frame buffer mapping, or 341 - * if pgoff points past it, the mmio mapping. 342 - */ 343 - start = info->fix.smem_start; 344 - len = info->fix.smem_len; 345 - mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; 346 - if (vma->vm_pgoff >= mmio_pgoff) { 347 - if (info->var.accel_flags) { 348 - mutex_unlock(&info->mm_lock); 349 - return -EINVAL; 350 - } 351 - 352 - vma->vm_pgoff -= mmio_pgoff; 353 - start = info->fix.mmio_start; 354 - len = info->fix.mmio_len; 355 - } 356 344 mutex_unlock(&info->mm_lock); 357 345 358 - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 359 - vma->vm_page_prot = pgprot_framebuffer(vma->vm_page_prot, vma->vm_start, 360 - vma->vm_end, start); 361 - 362 - return vm_iomap_memory(vma, start, len); 346 + return res; 363 347 } 364 348 365 349 static int fb_open(struct inode *inode, struct file *file)
+27
drivers/video/fbdev/core/fb_io_fops.c
··· 132 132 } 133 133 EXPORT_SYMBOL(fb_io_write); 134 134 135 + int fb_io_mmap(struct fb_info *info, struct vm_area_struct *vma) 136 + { 137 + unsigned long start = info->fix.smem_start; 138 + u32 len = info->fix.smem_len; 139 + unsigned long mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; 140 + 141 + /* 142 + * This can be either the framebuffer mapping, or if pgoff points 143 + * past it, the mmio mapping. 144 + */ 145 + if (vma->vm_pgoff >= mmio_pgoff) { 146 + if (info->var.accel_flags) 147 + return -EINVAL; 148 + 149 + vma->vm_pgoff -= mmio_pgoff; 150 + start = info->fix.mmio_start; 151 + len = info->fix.mmio_len; 152 + } 153 + 154 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 155 + vma->vm_page_prot = pgprot_framebuffer(vma->vm_page_prot, vma->vm_start, 156 + vma->vm_end, start); 157 + 158 + return vm_iomap_memory(vma, start, len); 159 + } 160 + EXPORT_SYMBOL(fb_io_mmap); 161 + 135 162 MODULE_DESCRIPTION("Fbdev helpers for framebuffers in I/O memory"); 136 163 MODULE_LICENSE("GPL");
+2 -1
include/linux/fb.h
··· 536 536 size_t count, loff_t *ppos); 537 537 extern ssize_t fb_io_write(struct fb_info *info, const char __user *buf, 538 538 size_t count, loff_t *ppos); 539 + int fb_io_mmap(struct fb_info *info, struct vm_area_struct *vma); 539 540 540 541 #define __FB_DEFAULT_IOMEM_OPS_RDWR \ 541 542 .fb_read = fb_io_read, \ ··· 548 547 .fb_imageblit = cfb_imageblit 549 548 550 549 #define __FB_DEFAULT_IOMEM_OPS_MMAP \ 551 - .fb_mmap = NULL /* default implementation */ 550 + .fb_mmap = fb_io_mmap 552 551 553 552 #define FB_DEFAULT_IOMEM_OPS \ 554 553 __FB_DEFAULT_IOMEM_OPS_RDWR, \