diff options
Diffstat (limited to 'drivers/video/fbdev')
37 files changed, 307 insertions, 236 deletions
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 53693c826ebd..d5909a9206ff 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -146,10 +146,8 @@ config FB_ACORN config FB_CLPS711X tristate "CLPS711X LCD support" depends on FB && (ARCH_CLPS711X || COMPILE_TEST) + select FB_IOMEM_HELPERS select FB_MODE_HELPERS - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT select LCD_CLASS_DEVICE select VIDEOMODE_HELPERS help @@ -180,10 +178,7 @@ config FB_IMX config FB_CYBER2000 tristate "CyberPro 2000/2010/5000 support" depends on FB && PCI && (BROKEN || !SPARC64) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_IOMEM_FOPS + select FB_IOMEM_HELPERS select VIDEO_NOMODESET help This enables support for the Integraphics CyberPro 20x0 and 5000 @@ -272,10 +267,7 @@ config FB_FM2 config FB_ARC tristate "Arc Monochrome LCD board support" depends on FB && (X86 || COMPILE_TEST) - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS + select FB_SYSMEM_HELPERS_DEFERRED help This enables support for the Arc Monochrome LCD board. The board is based on the KS-108 lcd controller and is typically a matrix @@ -1460,10 +1452,7 @@ config FB_AU1100 config FB_AU1200 bool "Au1200/Au1300 LCD Driver" depends on (FB = y) && MIPS_ALCHEMY - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS + select FB_DMAMEM_HELPERS help This is the framebuffer driver for the Au1200/Au1300 SOCs. It can drive various panels and CRTs by passing in kernel cmd line @@ -1475,6 +1464,7 @@ config FB_VT8500 select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) select FB_SYS_IMAGEBLIT + select FB_SYSMEM_FOPS select FB_MODE_HELPERS select VIDEOMODE_HELPERS help @@ -1487,6 +1477,7 @@ config FB_WM8505 select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) select FB_SYS_IMAGEBLIT + select FB_SYSMEM_FOPS select FB_MODE_HELPERS select VIDEOMODE_HELPERS help @@ -1637,12 +1628,9 @@ config FB_SH_MOBILE_LCDC depends on FB && HAVE_CLK && HAS_IOMEM depends on SUPERH || ARCH_RENESAS || COMPILE_TEST depends on FB_DEVICE - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO select FB_BACKLIGHT + select FB_DEFERRED_IO + select FB_DMAMEM_HELPERS help Frame buffer driver for the on-chip SH-Mobile LCD controller. @@ -1689,11 +1677,7 @@ config FB_SMSCUFX tristate "SMSC UFX6000/7000 USB Framebuffer support" depends on FB && USB select FB_MODE_HELPERS - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO + select FB_SYSMEM_HELPERS_DEFERRED help This is a kernel framebuffer driver for SMSC UFX USB devices. Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and @@ -1706,11 +1690,7 @@ config FB_UDL depends on FB && USB depends on FB_DEVICE select FB_MODE_HELPERS - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO + select FB_SYSMEM_HELPERS_DEFERRED help This is a kernel framebuffer driver for DisplayLink USB devices. Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and @@ -1732,10 +1712,7 @@ config FB_IBM_GXT4500 config FB_PS3 tristate "PS3 GPU framebuffer driver" depends on FB && PS3_PS3AV - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS + select FB_SYSMEM_HELPERS help Include support for the virtual frame buffer in the PS3 platform. @@ -1800,10 +1777,7 @@ config FB_DA8XX config FB_VIRTUAL tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" depends on FB - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS + select FB_SYSMEM_HELPERS help This is a `virtual' frame buffer device. It operates on a chunk of unswappable kernel memory instead of on the memory of a graphics diff --git a/drivers/video/fbdev/acornfb.c b/drivers/video/fbdev/acornfb.c index 163d2c9f951c..f0600f6ca254 100644 --- a/drivers/video/fbdev/acornfb.c +++ b/drivers/video/fbdev/acornfb.c @@ -605,7 +605,7 @@ acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) static const struct fb_ops acornfb_ops = { .owner = THIS_MODULE, - FB_IOMEM_DEFAULT_OPS, + FB_DEFAULT_IOMEM_OPS, .fb_check_var = acornfb_check_var, .fb_set_par = acornfb_set_par, .fb_setcolreg = acornfb_setcolreg, diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 0399db369e70..47d373f04f3f 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -829,6 +829,8 @@ static int clcdfb_of_dma_setup(struct clcd_fb *fb) static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) { + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base, fb->fb.fix.smem_start, fb->fb.fix.smem_len); } diff --git a/drivers/video/fbdev/arcfb.c b/drivers/video/fbdev/arcfb.c index cff11cb04a55..b2408543277c 100644 --- a/drivers/video/fbdev/arcfb.c +++ b/drivers/video/fbdev/arcfb.c @@ -363,39 +363,6 @@ static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx, } } -static void arcfb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - struct arcfb_par *par = info->par; - - sys_fillrect(info, rect); - - /* update the physical lcd */ - arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); -} - -static void arcfb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - struct arcfb_par *par = info->par; - - sys_copyarea(info, area); - - /* update the physical lcd */ - arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); -} - -static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct arcfb_par *par = info->par; - - sys_imageblit(info, image); - - /* update the physical lcd */ - arcfb_lcd_update(par, image->dx, image->dy, image->width, - image->height); -} - static int arcfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { @@ -436,76 +403,48 @@ static int arcfb_ioctl(struct fb_info *info, } } -/* - * this is the access path from userspace. they can seek and write to - * the fb. it's inefficient for them to do anything less than 64*8 - * writes since we update the lcd in each write() anyway. - */ -static ssize_t arcfb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos) +static void arcfb_damage_range(struct fb_info *info, off_t off, size_t len) { - /* modded from epson 1355 */ - - unsigned long p; - int err; - unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount; - struct arcfb_par *par; - unsigned int xres; - - if (!info->screen_buffer) - return -ENODEV; - - p = *ppos; - par = info->par; - xres = info->var.xres; - fbmemlength = (xres * info->var.yres)/8; - - if (p > fbmemlength) - return -ENOSPC; - - err = 0; - if ((count + p) > fbmemlength) { - count = fbmemlength - p; - err = -ENOSPC; - } - - if (count) { - char *base_addr; - - base_addr = info->screen_buffer; - count -= copy_from_user(base_addr + p, buf, count); - *ppos += count; - err = -EFAULT; - } - + struct arcfb_par *par = info->par; + unsigned int xres = info->var.xres; + unsigned int bitppos, startpos, endpos, bitcount; + unsigned int x, y, width, height; - bitppos = p*8; + bitppos = off * 8; startpos = floorXres(bitppos, xres); - endpos = ceilXres((bitppos + (count*8)), xres); + endpos = ceilXres((bitppos + (len * 8)), xres); bitcount = endpos - startpos; x = startpos % xres; y = startpos / xres; - w = xres; - h = bitcount / xres; - arcfb_lcd_update(par, x, y, w, h); + width = xres; + height = bitcount / xres; + + arcfb_lcd_update(par, x, y, width, height); +} - if (count) - return count; - return err; +static void arcfb_damage_area(struct fb_info *info, u32 x, u32 y, + u32 width, u32 height) +{ + struct arcfb_par *par = info->par; + + /* update the physical lcd */ + arcfb_lcd_update(par, x, y, width, height); } +FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(arcfb, + arcfb_damage_range, + arcfb_damage_area) + static const struct fb_ops arcfb_ops = { .owner = THIS_MODULE, .fb_open = arcfb_open, - .fb_read = fb_sys_read, - .fb_write = arcfb_write, + __FB_DEFAULT_DEFERRED_OPS_RDWR(arcfb), .fb_release = arcfb_release, .fb_pan_display = arcfb_pan_display, - .fb_fillrect = arcfb_fillrect, - .fb_copyarea = arcfb_copyarea, - .fb_imageblit = arcfb_imageblit, + __FB_DEFAULT_DEFERRED_OPS_DRAW(arcfb), .fb_ioctl = arcfb_ioctl, + // .fb_mmap reqires deferred I/O }; static int arcfb_probe(struct platform_device *dev) @@ -529,6 +468,7 @@ static int arcfb_probe(struct platform_device *dev) if (!info) goto err_fb_alloc; + info->flags |= FBINFO_VIRTFB; info->screen_buffer = videomemory; info->fbops = &arcfb_ops; diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index a9c8d33a6ef7..08109ce535cd 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -342,6 +342,8 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) { struct au1100fb_device *fbdev = to_au1100fb_device(fbi); + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 return dma_mmap_coherent(fbdev->dev, vma, fbdev->fb_mem, fbdev->fb_phys, diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 98afd385c49c..6f20efc663d7 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1236,6 +1236,8 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct au1200fb_device *fbdev = info->par; + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + return dma_mmap_coherent(fbdev->dev, vma, fbdev->fb_mem, fbdev->fb_phys, fbdev->fb_len); } @@ -1488,15 +1490,12 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, static const struct fb_ops au1200fb_fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_DMAMEM_OPS_RDWR, .fb_check_var = au1200fb_fb_check_var, .fb_set_par = au1200fb_fb_set_par, .fb_setcolreg = au1200fb_fb_setcolreg, .fb_blank = au1200fb_fb_blank, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, + __FB_DEFAULT_DMAMEM_OPS_DRAW, .fb_sync = NULL, .fb_ioctl = au1200fb_ioctl, .fb_mmap = au1200fb_fb_mmap, @@ -1568,6 +1567,8 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) fbi->fix.mmio_len = 0; fbi->fix.accel = FB_ACCEL_NONE; + fbi->flags |= FBINFO_VIRTFB; + fbi->screen_buffer = fbdev->fb_mem; au1200fb_update_fbinfo(fbi); diff --git a/drivers/video/fbdev/clps711x-fb.c b/drivers/video/fbdev/clps711x-fb.c index e956c90efcdc..dcfd1fbbc7e1 100644 --- a/drivers/video/fbdev/clps711x-fb.c +++ b/drivers/video/fbdev/clps711x-fb.c @@ -155,13 +155,11 @@ static int clps711x_fb_blank(int blank, struct fb_info *info) static const struct fb_ops clps711x_fb_ops = { .owner = THIS_MODULE, + FB_DEFAULT_IOMEM_OPS, .fb_setcolreg = clps711x_fb_setcolreg, .fb_check_var = clps711x_fb_check_var, .fb_set_par = clps711x_fb_set_par, .fb_blank = clps711x_fb_blank, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, }; static int clps711x_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi) diff --git a/drivers/video/fbdev/core/Kconfig b/drivers/video/fbdev/core/Kconfig index 7a3ed13bed70..21053bf00dc5 100644 --- a/drivers/video/fbdev/core/Kconfig +++ b/drivers/video/fbdev/core/Kconfig @@ -4,7 +4,6 @@ # config FB_CORE - select FB_IOMEM_FOPS select VIDEO_CMDLINE tristate @@ -129,7 +128,7 @@ config FB_LITTLE_ENDIAN endchoice -config FB_SYS_FOPS +config FB_SYSMEM_FOPS tristate depends on FB_CORE @@ -142,8 +141,8 @@ config FB_DMAMEM_HELPERS depends on FB_CORE select FB_SYS_COPYAREA select FB_SYS_FILLRECT - select FB_SYS_FOPS select FB_SYS_IMAGEBLIT + select FB_SYSMEM_FOPS config FB_IOMEM_FOPS tristate @@ -168,8 +167,8 @@ config FB_SYSMEM_HELPERS depends on FB_CORE select FB_SYS_COPYAREA select FB_SYS_FILLRECT - select FB_SYS_FOPS select FB_SYS_IMAGEBLIT + select FB_SYSMEM_FOPS config FB_SYSMEM_HELPERS_DEFERRED bool diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile index c1d657601b2b..d15974759086 100644 --- a/drivers/video/fbdev/core/Makefile +++ b/drivers/video/fbdev/core/Makefile @@ -32,6 +32,6 @@ obj-$(CONFIG_FB_IOMEM_FOPS) += fb_io_fops.o obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o -obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o +obj-$(CONFIG_FB_SYSMEM_FOPS) += fb_sys_fops.o obj-$(CONFIG_FB_SVGALIB) += svgalib.o obj-$(CONFIG_FB_DDC) += fb_ddc.o diff --git a/drivers/video/fbdev/core/cfbcopyarea.c b/drivers/video/fbdev/core/cfbcopyarea.c index 5b80bf3dae50..a271f57d9c6c 100644 --- a/drivers/video/fbdev/core/cfbcopyarea.c +++ b/drivers/video/fbdev/core/cfbcopyarea.c @@ -391,6 +391,9 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) if (p->state != FBINFO_STATE_RUNNING) return; + if (p->flags & FBINFO_VIRTFB) + fb_warn_once(p, "Framebuffer is not in I/O address space."); + /* if the beginning of the target area might overlap with the end of the source area, be have to copy the area reverse. */ if ((dy == sy && dx > sx) || (dy > sy)) { diff --git a/drivers/video/fbdev/core/cfbfillrect.c b/drivers/video/fbdev/core/cfbfillrect.c index ba9f58b2a5e8..cbaa4c9e2355 100644 --- a/drivers/video/fbdev/core/cfbfillrect.c +++ b/drivers/video/fbdev/core/cfbfillrect.c @@ -287,6 +287,9 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) if (p->state != FBINFO_STATE_RUNNING) return; + if (p->flags & FBINFO_VIRTFB) + fb_warn_once(p, "Framebuffer is not in I/O address space."); + if (p->fix.visual == FB_VISUAL_TRUECOLOR || p->fix.visual == FB_VISUAL_DIRECTCOLOR ) fg = ((u32 *) (p->pseudo_palette))[rect->color]; diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c index 9ebda4e0dc7a..7d1d2f1a627d 100644 --- a/drivers/video/fbdev/core/cfbimgblt.c +++ b/drivers/video/fbdev/core/cfbimgblt.c @@ -326,6 +326,9 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) if (p->state != FBINFO_STATE_RUNNING) return; + if (p->flags & FBINFO_VIRTFB) + fb_warn_once(p, "Framebuffer is not in I/O address space."); + bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); start_index = bitstart & (32 - 1); pitch_index = (p->fix.line_length & (bpl - 1)) * 8; diff --git a/drivers/video/fbdev/core/fb_chrdev.c b/drivers/video/fbdev/core/fb_chrdev.c index 32a7315b4b6d..4ebd16b7e3b8 100644 --- a/drivers/video/fbdev/core/fb_chrdev.c +++ b/drivers/video/fbdev/core/fb_chrdev.c @@ -34,13 +34,13 @@ static ssize_t fb_read(struct file *file, char __user *buf, size_t count, loff_t if (!info) return -ENODEV; + if (fb_WARN_ON_ONCE(info, !info->fbops->fb_read)) + return -EINVAL; + if (info->state != FBINFO_STATE_RUNNING) return -EPERM; - if (info->fbops->fb_read) - return info->fbops->fb_read(info, buf, count, ppos); - - return fb_io_read(info, buf, count, ppos); + return info->fbops->fb_read(info, buf, count, ppos); } static ssize_t fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) @@ -50,13 +50,13 @@ static ssize_t fb_write(struct file *file, const char __user *buf, size_t count, if (!info) return -ENODEV; + if (fb_WARN_ON_ONCE(info, !info->fbops->fb_write)) + return -EINVAL; + if (info->state != FBINFO_STATE_RUNNING) return -EPERM; - if (info->fbops->fb_write) - return info->fbops->fb_write(info, buf, count, ppos); - - return fb_io_write(info, buf, count, ppos); + return info->fbops->fb_write(info, buf, count, ppos); } static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, @@ -314,61 +314,19 @@ 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; - - /* - * The framebuffer needs to be accessed decrypted, be sure - * SME protection is removed ahead of the call - */ - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); - 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) { - /* - * FB deferred I/O wants you to handle mmap in your drivers. At a - * 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); + if (fb_WARN_ON_ONCE(info, !info->fbops->fb_mmap)) return -ENODEV; -#endif - } - - /* - * 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_lock(&info->mm_lock); + res = info->fbops->fb_mmap(info, vma); 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) diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 274f5d0fa247..1b0b85e59e5e 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -227,6 +227,8 @@ static const struct address_space_operations fb_deferred_io_aops = { int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) { + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + vma->vm_ops = &fb_deferred_io_vm_ops; vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP); if (!(info->flags & FBINFO_VIRTFB)) diff --git a/drivers/video/fbdev/core/fb_io_fops.c b/drivers/video/fbdev/core/fb_io_fops.c index 871b829521af..3408ff1b2b7a 100644 --- a/drivers/video/fbdev/core/fb_io_fops.c +++ b/drivers/video/fbdev/core/fb_io_fops.c @@ -12,6 +12,9 @@ ssize_t fb_io_read(struct fb_info *info, char __user *buf, size_t count, loff_t int c, cnt = 0, err = 0; unsigned long total_size, trailing; + if (info->flags & FBINFO_VIRTFB) + fb_warn_once(info, "Framebuffer is not in I/O address space."); + if (!info->screen_base) return -ENODEV; @@ -73,6 +76,9 @@ ssize_t fb_io_write(struct fb_info *info, const char __user *buf, size_t count, int c, cnt = 0, err = 0; unsigned long total_size, trailing; + if (info->flags & FBINFO_VIRTFB) + fb_warn_once(info, "Framebuffer is not in I/O address space."); + if (!info->screen_base) return -ENODEV; @@ -132,5 +138,35 @@ 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; + + if (info->flags & FBINFO_VIRTFB) + fb_warn_once(info, "Framebuffer is not in I/O address space."); + + /* + * 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"); diff --git a/drivers/video/fbdev/core/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c index 0cb0989abda6..a9aa6519a5b3 100644 --- a/drivers/video/fbdev/core/fb_sys_fops.c +++ b/drivers/video/fbdev/core/fb_sys_fops.c @@ -22,6 +22,9 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count, unsigned long total_size, c; ssize_t ret; + if (!(info->flags & FBINFO_VIRTFB)) + fb_warn_once(info, "Framebuffer is not in virtual address space."); + if (!info->screen_buffer) return -ENODEV; @@ -64,6 +67,9 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, unsigned long total_size, c; size_t ret; + if (!(info->flags & FBINFO_VIRTFB)) + fb_warn_once(info, "Framebuffer is not in virtual address space."); + if (!info->screen_buffer) return -ENODEV; diff --git a/drivers/video/fbdev/core/syscopyarea.c b/drivers/video/fbdev/core/syscopyarea.c index 7b8bd3a2bedc..75e7001e8450 100644 --- a/drivers/video/fbdev/core/syscopyarea.c +++ b/drivers/video/fbdev/core/syscopyarea.c @@ -324,6 +324,9 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area) if (p->state != FBINFO_STATE_RUNNING) return; + if (!(p->flags & FBINFO_VIRTFB)) + fb_warn_once(p, "Framebuffer is not in virtual address space."); + /* if the beginning of the target area might overlap with the end of the source area, be have to copy the area reverse. */ if ((dy == sy && dx > sx) || (dy > sy)) { diff --git a/drivers/video/fbdev/core/sysfillrect.c b/drivers/video/fbdev/core/sysfillrect.c index bcdcaeae6538..e49221a88ccc 100644 --- a/drivers/video/fbdev/core/sysfillrect.c +++ b/drivers/video/fbdev/core/sysfillrect.c @@ -242,6 +242,9 @@ void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect) if (p->state != FBINFO_STATE_RUNNING) return; + if (!(p->flags & FBINFO_VIRTFB)) + fb_warn_once(p, "Framebuffer is not in virtual address space."); + if (p->fix.visual == FB_VISUAL_TRUECOLOR || p->fix.visual == FB_VISUAL_DIRECTCOLOR ) fg = ((u32 *) (p->pseudo_palette))[rect->color]; diff --git a/drivers/video/fbdev/core/sysimgblt.c b/drivers/video/fbdev/core/sysimgblt.c index 665ef7a0a249..6949bbd51d92 100644 --- a/drivers/video/fbdev/core/sysimgblt.c +++ b/drivers/video/fbdev/core/sysimgblt.c @@ -296,6 +296,9 @@ void sys_imageblit(struct fb_info *p, const struct fb_image *image) if (p->state != FBINFO_STATE_RUNNING) return; + if (!(p->flags & FBINFO_VIRTFB)) + fb_warn_once(p, "Framebuffer is not in virtual address space."); + bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); start_index = bitstart & (32 - 1); pitch_index = (p->fix.line_length & (bpl - 1)) * 8; diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c index 52105dc1a72f..abb87d3576db 100644 --- a/drivers/video/fbdev/cyber2000fb.c +++ b/drivers/video/fbdev/cyber2000fb.c @@ -227,13 +227,6 @@ cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) CO_REG_CMD_H, cfb); } -static void -cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image) -{ - cfb_imageblit(info, image); - return; -} - static int cyber2000fb_sync(struct fb_info *info) { struct cfb_info *cfb = container_of(info, struct cfb_info, fb); @@ -1069,7 +1062,7 @@ static const struct fb_ops cyber2000fb_ops = { .fb_pan_display = cyber2000fb_pan_display, .fb_fillrect = cyber2000fb_fillrect, .fb_copyarea = cyber2000fb_copyarea, - .fb_imageblit = cyber2000fb_imageblit, + .fb_imageblit = cfb_imageblit, .fb_sync = cyber2000fb_sync, __FB_DEFAULT_IOMEM_OPS_MMAP, }; diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c index cae00deee001..3e378874ccc7 100644 --- a/drivers/video/fbdev/ep93xx-fb.c +++ b/drivers/video/fbdev/ep93xx-fb.c @@ -311,6 +311,8 @@ static int ep93xxfb_mmap(struct fb_info *info, struct vm_area_struct *vma) { unsigned int offset = vma->vm_pgoff << PAGE_SHIFT; + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + if (offset < info->fix.smem_len) { return dma_mmap_wc(info->device, vma, info->screen_base, info->fix.smem_start, info->fix.smem_len); diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c index e89e5579258e..8463de833d1e 100644 --- a/drivers/video/fbdev/gbefb.c +++ b/drivers/video/fbdev/gbefb.c @@ -1000,6 +1000,8 @@ static int gbefb_mmap(struct fb_info *info, unsigned long phys_addr, phys_size; u16 *tile; + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + /* check range */ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index a80939fe2ee6..6a29d2594b91 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -927,8 +927,8 @@ static phys_addr_t hvfb_get_phymem(struct hv_device *hdev, if (request_size == 0) return -1; - if (order <= MAX_ORDER) { - /* Call alloc_pages if the size is less than 2^MAX_ORDER */ + if (order <= MAX_PAGE_ORDER) { + /* Call alloc_pages if the size is less than 2^MAX_PAGE_ORDER */ page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); if (!page) return -1; @@ -958,7 +958,7 @@ static void hvfb_release_phymem(struct hv_device *hdev, { unsigned int order = get_order(size); - if (order <= MAX_ORDER) + if (order <= MAX_PAGE_ORDER) __free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order); else dma_free_coherent(&hdev->device, diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c index 694cf6318782..aa31c0d26e92 100644 --- a/drivers/video/fbdev/omap/omapfb_main.c +++ b/drivers/video/fbdev/omap/omapfb_main.c @@ -1203,6 +1203,8 @@ static int omapfb_mmap(struct fb_info *info, struct vm_area_struct *vma) struct omapfb_device *fbdev = plane->fbdev; int r; + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + omapfb_rqueue_lock(fbdev); r = fbdev->ctrl->mmap(info, vma); omapfb_rqueue_unlock(fbdev); diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c index c9fd0ad352d7..0db9c55fce5a 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c @@ -1095,6 +1095,8 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) u32 len; int r; + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + rg = omapfb_get_mem_region(ofbi->region); start = omapfb_get_region_paddr(ofbi); diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c index 64d291d6b153..dbcda307f6a6 100644 --- a/drivers/video/fbdev/ps3fb.c +++ b/drivers/video/fbdev/ps3fb.c @@ -708,6 +708,8 @@ static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { int r; + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + r = vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len); dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", @@ -939,15 +941,12 @@ static const struct fb_ops ps3fb_ops = { .owner = THIS_MODULE, .fb_open = ps3fb_open, .fb_release = ps3fb_release, - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, + __FB_DEFAULT_SYSMEM_OPS_RDWR, .fb_check_var = ps3fb_check_var, .fb_set_par = ps3fb_set_par, .fb_setcolreg = ps3fb_setcolreg, .fb_pan_display = ps3fb_pan_display, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + __FB_DEFAULT_SYSMEM_OPS_DRAW, .fb_mmap = ps3fb_mmap, .fb_blank = ps3fb_blank, .fb_ioctl = ps3fb_ioctl, @@ -1145,7 +1144,7 @@ static int ps3fb_probe(struct ps3_system_bus_device *dev) info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START; info->pseudo_palette = par->pseudo_palette; - info->flags = FBINFO_READS_FAST | + info->flags = FBINFO_VIRTFB | FBINFO_READS_FAST | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; retval = fb_alloc_cmap(&info->cmap, 256, 0); diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index befd3fe2f659..0d362d2bf0e3 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -562,6 +562,8 @@ static int sa1100fb_mmap(struct fb_info *info, container_of(info, struct sa1100fb_info, fb); unsigned long off = vma->vm_pgoff << PAGE_SHIFT; + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + if (off < info->fix.smem_len) { vma->vm_pgoff += 1; /* skip over the palette */ return dma_mmap_wc(fbi->dev, vma, fbi->map_cpu, fbi->map_dma, diff --git a/drivers/video/fbdev/sbuslib.c b/drivers/video/fbdev/sbuslib.c index 21e9fd8e69e2..634e3d159452 100644 --- a/drivers/video/fbdev/sbuslib.c +++ b/drivers/video/fbdev/sbuslib.c @@ -48,7 +48,7 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map, unsigned long map_offset = 0; unsigned long off; int i; - + if (!(vma->vm_flags & (VM_SHARED | VM_MAYSHARE))) return -EINVAL; @@ -60,6 +60,7 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map, /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* Each page, see which map applies */ @@ -72,7 +73,7 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map, #define POFF_MASK (PAGE_MASK|0x1UL) #else #define POFF_MASK (PAGE_MASK) -#endif +#endif map_offset = (physbase + map[i].poff) & POFF_MASK; break; } diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index 1364dafaadb1..eb2297b37504 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -1482,19 +1482,18 @@ sh_mobile_lcdc_overlay_mmap(struct fb_info *info, struct vm_area_struct *vma) if (info->fbdefio) return fb_deferred_io_mmap(info, vma); + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + return dma_mmap_coherent(ovl->channel->lcdc->dev, vma, ovl->fb_mem, ovl->dma_handle, ovl->fb_size); } static const struct fb_ops sh_mobile_lcdc_overlay_ops = { .owner = THIS_MODULE, - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + __FB_DEFAULT_DMAMEM_OPS_RDWR, .fb_blank = sh_mobile_lcdc_overlay_blank, .fb_pan_display = sh_mobile_lcdc_overlay_pan, + __FB_DEFAULT_DMAMEM_OPS_DRAW, .fb_ioctl = sh_mobile_lcdc_overlay_ioctl, .fb_check_var = sh_mobile_lcdc_overlay_check_var, .fb_set_par = sh_mobile_lcdc_overlay_set_par, @@ -1567,6 +1566,7 @@ sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl) info->fbops = &sh_mobile_lcdc_overlay_ops; info->device = priv->dev; + info->flags |= FBINFO_VIRTFB; info->screen_buffer = ovl->fb_mem; info->par = ovl; @@ -1958,6 +1958,8 @@ sh_mobile_lcdc_mmap(struct fb_info *info, struct vm_area_struct *vma) if (info->fbdefio) return fb_deferred_io_mmap(info, vma); + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem, ch->dma_handle, ch->fb_size); } @@ -1965,8 +1967,7 @@ sh_mobile_lcdc_mmap(struct fb_info *info, struct vm_area_struct *vma) static const struct fb_ops sh_mobile_lcdc_ops = { .owner = THIS_MODULE, .fb_setcolreg = sh_mobile_lcdc_setcolreg, - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, + __FB_DEFAULT_DMAMEM_OPS_RDWR, .fb_fillrect = sh_mobile_lcdc_fillrect, .fb_copyarea = sh_mobile_lcdc_copyarea, .fb_imageblit = sh_mobile_lcdc_imageblit, @@ -2053,6 +2054,7 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, info->fbops = &sh_mobile_lcdc_ops; info->device = priv->dev; + info->flags |= FBINFO_VIRTFB; info->screen_buffer = ch->fb_mem; info->pseudo_palette = &ch->pseudo_palette; info->par = ch; diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 62f99f6fccd3..6f58ee276ad1 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -21,9 +21,11 @@ #include <linux/platform_device.h> #include <linux/clk.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/of_clk.h> #include <linux/of_platform.h> #include <linux/parser.h> +#include <linux/pm_domain.h> #include <linux/regulator/consumer.h> static const struct fb_fix_screeninfo simplefb_fix = { @@ -77,6 +79,11 @@ struct simplefb_par { unsigned int clk_count; struct clk **clks; #endif +#if defined CONFIG_OF && defined CONFIG_PM_GENERIC_DOMAINS + unsigned int num_genpds; + struct device **genpds; + struct device_link **genpd_links; +#endif #if defined CONFIG_OF && defined CONFIG_REGULATOR bool regulators_enabled; u32 regulator_count; @@ -121,12 +128,13 @@ struct simplefb_params { u32 height; u32 stride; struct simplefb_format *format; + struct resource memory; }; static int simplefb_parse_dt(struct platform_device *pdev, struct simplefb_params *params) { - struct device_node *np = pdev->dev.of_node; + struct device_node *np = pdev->dev.of_node, *mem; int ret; const char *format; int i; @@ -166,6 +174,23 @@ static int simplefb_parse_dt(struct platform_device *pdev, return -EINVAL; } + mem = of_parse_phandle(np, "memory-region", 0); + if (mem) { + ret = of_address_to_resource(mem, 0, ¶ms->memory); + if (ret < 0) { + dev_err(&pdev->dev, "failed to parse memory-region\n"); + of_node_put(mem); + return ret; + } + + if (of_property_present(np, "reg")) + dev_warn(&pdev->dev, "preferring \"memory-region\" over \"reg\" property\n"); + + of_node_put(mem); + } else { + memset(¶ms->memory, 0, sizeof(params->memory)); + } + return 0; } @@ -193,6 +218,8 @@ static int simplefb_parse_pd(struct platform_device *pdev, return -EINVAL; } + memset(¶ms->memory, 0, sizeof(params->memory)); + return 0; } @@ -411,6 +438,93 @@ static void simplefb_regulators_enable(struct simplefb_par *par, static void simplefb_regulators_destroy(struct simplefb_par *par) { } #endif +#if defined CONFIG_OF && defined CONFIG_PM_GENERIC_DOMAINS +static void simplefb_detach_genpds(void *res) +{ + struct simplefb_par *par = res; + unsigned int i = par->num_genpds; + + if (par->num_genpds <= 1) + return; + + while (i--) { + if (par->genpd_links[i]) + device_link_del(par->genpd_links[i]); + + if (!IS_ERR_OR_NULL(par->genpds[i])) + dev_pm_domain_detach(par->genpds[i], true); + } +} + +static int simplefb_attach_genpds(struct simplefb_par *par, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + unsigned int i; + int err; + + err = of_count_phandle_with_args(dev->of_node, "power-domains", + "#power-domain-cells"); + if (err < 0) { + /* Nothing wrong if optional PDs are missing */ + if (err == -ENOENT) + return 0; + + dev_info(dev, "failed to parse power-domains: %d\n", err); + return err; + } + + par->num_genpds = err; + + /* + * Single power-domain devices are handled by the driver core, so + * nothing to do here. + */ + if (par->num_genpds <= 1) + return 0; + + par->genpds = devm_kcalloc(dev, par->num_genpds, sizeof(*par->genpds), + GFP_KERNEL); + if (!par->genpds) + return -ENOMEM; + + par->genpd_links = devm_kcalloc(dev, par->num_genpds, + sizeof(*par->genpd_links), + GFP_KERNEL); + if (!par->genpd_links) + return -ENOMEM; + + for (i = 0; i < par->num_genpds; i++) { + par->genpds[i] = dev_pm_domain_attach_by_id(dev, i); + if (IS_ERR(par->genpds[i])) { + err = PTR_ERR(par->genpds[i]); + if (err == -EPROBE_DEFER) { + simplefb_detach_genpds(par); + return err; + } + + dev_warn(dev, "failed to attach domain %u: %d\n", i, err); + continue; + } + + par->genpd_links[i] = device_link_add(dev, par->genpds[i], + DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); + if (!par->genpd_links[i]) + dev_warn(dev, "failed to link power-domain %u\n", i); + } + + return devm_add_action_or_reset(dev, simplefb_detach_genpds, par); +} +#else +static int simplefb_attach_genpds(struct simplefb_par *par, + struct platform_device *pdev) +{ + return 0; +} +#endif + static int simplefb_probe(struct platform_device *pdev) { int ret; @@ -431,10 +545,14 @@ static int simplefb_probe(struct platform_device *pdev) if (ret) return ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "No memory resource\n"); - return -EINVAL; + if (params.memory.start == 0 && params.memory.end == 0) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "No memory resource\n"); + return -EINVAL; + } + } else { + res = ¶ms.memory; } mem = request_mem_region(res->start, resource_size(res), "simplefb"); @@ -493,6 +611,10 @@ static int simplefb_probe(struct platform_device *pdev) if (ret < 0) goto error_clocks; + ret = simplefb_attach_genpds(par, pdev); + if (ret < 0) + goto error_regulators; + simplefb_clocks_enable(par, pdev); simplefb_regulators_enable(par, pdev); diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index 3f8ef50e3209..104f122e0f27 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1347,16 +1347,14 @@ static int smtc_set_par(struct fb_info *info) static const struct fb_ops smtcfb_ops = { .owner = THIS_MODULE, - FB_DEFAULT_IOMEM_OPS, .fb_check_var = smtc_check_var, .fb_set_par = smtc_set_par, .fb_setcolreg = smtc_setcolreg, .fb_blank = smtc_blank, - .fb_fillrect = cfb_fillrect, - .fb_imageblit = cfb_imageblit, - .fb_copyarea = cfb_copyarea, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_read = smtcfb_read, .fb_write = smtcfb_write, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c index 90a77d19b236..35d682b110c4 100644 --- a/drivers/video/fbdev/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -783,6 +783,8 @@ static int ufx_ops_mmap(struct fb_info *info, struct vm_area_struct *vma) if (info->fbdefio) return fb_deferred_io_mmap(info, vma); + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; if (size > info->fix.smem_len) diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index 2460ff4ac86b..1514ddac4caf 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -331,6 +331,8 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma) if (info->fbdefio) return fb_deferred_io_mmap(info, vma); + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; if (size > info->fix.smem_len) diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c index 840ead69654b..974da83b37dc 100644 --- a/drivers/video/fbdev/vermilion/vermilion.c +++ b/drivers/video/fbdev/vermilion/vermilion.c @@ -197,7 +197,7 @@ static int vmlfb_alloc_vram(struct vml_info *vinfo, va = &vinfo->vram[i]; order = 0; - while (requested > (PAGE_SIZE << order) && order <= MAX_ORDER) + while (requested > (PAGE_SIZE << order) && order <= MAX_PAGE_ORDER) order++; err = vmlfb_alloc_vram_area(va, order, 0); @@ -998,6 +998,8 @@ static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma) int ret; unsigned long prot; + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + ret = vmlfb_vram_offset(vinfo, offset); if (ret) return -EINVAL; diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c index 1b7c338f9956..f86149ba3835 100644 --- a/drivers/video/fbdev/vfb.c +++ b/drivers/video/fbdev/vfb.c @@ -80,15 +80,12 @@ static int vfb_mmap(struct fb_info *info, static const struct fb_ops vfb_ops = { .owner = THIS_MODULE, - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, + __FB_DEFAULT_SYSMEM_OPS_RDWR, .fb_check_var = vfb_check_var, .fb_set_par = vfb_set_par, .fb_setcolreg = vfb_setcolreg, .fb_pan_display = vfb_pan_display, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + __FB_DEFAULT_SYSMEM_OPS_DRAW, .fb_mmap = vfb_mmap, }; @@ -385,6 +382,8 @@ static int vfb_pan_display(struct fb_var_screeninfo *var, static int vfb_mmap(struct fb_info *info, struct vm_area_struct *vma) { + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + return remap_vmalloc_range(vma, (void *)info->fix.smem_start, vma->vm_pgoff); } @@ -440,6 +439,7 @@ static int vfb_probe(struct platform_device *dev) if (!info) goto err; + info->flags |= FBINFO_VIRTFB; info->screen_buffer = videomemory; info->fbops = &vfb_ops; diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c index 42d39a9d5130..42c25dc85197 100644 --- a/drivers/video/fbdev/vt8500lcdfb.c +++ b/drivers/video/fbdev/vt8500lcdfb.c @@ -241,6 +241,7 @@ static int vt8500lcd_blank(int blank, struct fb_info *info) static const struct fb_ops vt8500lcd_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_DMAMEM_OPS_RDWR, .fb_set_par = vt8500lcd_set_par, .fb_setcolreg = vt8500lcd_setcolreg, .fb_fillrect = wmt_ge_fillrect, @@ -250,6 +251,7 @@ static const struct fb_ops vt8500lcd_ops = { .fb_ioctl = vt8500lcd_ioctl, .fb_pan_display = vt8500lcd_pan_display, .fb_blank = vt8500lcd_blank, + // .fb_mmap needs DMA mmap }; static irqreturn_t vt8500lcd_handle_irq(int irq, void *dev_id) @@ -357,7 +359,7 @@ static int vt8500lcd_probe(struct platform_device *pdev) fbi->fb.fix.smem_start = fb_mem_phys; fbi->fb.fix.smem_len = fb_mem_len; - fbi->fb.screen_base = fb_mem_virt; + fbi->fb.screen_buffer = fb_mem_virt; fbi->palette_size = PAGE_ALIGN(512); fbi->palette_cpu = dma_alloc_coherent(&pdev->dev, diff --git a/drivers/video/fbdev/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c index 5833147aa43d..00952e9c8802 100644 --- a/drivers/video/fbdev/wm8505fb.c +++ b/drivers/video/fbdev/wm8505fb.c @@ -248,6 +248,7 @@ static int wm8505fb_blank(int blank, struct fb_info *info) static const struct fb_ops wm8505fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_DMAMEM_OPS_RDWR, .fb_set_par = wm8505fb_set_par, .fb_setcolreg = wm8505fb_setcolreg, .fb_fillrect = wmt_ge_fillrect, @@ -256,6 +257,7 @@ static const struct fb_ops wm8505fb_ops = { .fb_sync = wmt_ge_sync, .fb_pan_display = wm8505fb_pan_display, .fb_blank = wm8505fb_blank, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int wm8505fb_probe(struct platform_device *pdev) |