Commit 09aaf268 authored by Antonino A. Daplas's avatar Antonino A. Daplas Committed by Linus Torvalds

fbdev: add fb_read/fb_write functions for framebuffers in system RAM

The functions fb_read() and fb_write in fbmem.c assume that the framebuffer
is in IO memory.  However, we have 3 drivers (hecubafb, arcfb, and vfb)
where the framebuffer is allocated from system RAM (via vmalloc). Using
__raw_read/__raw_write (fb_readl/fb_writel) for these drivers is
illegal, especially in other platforms.

Create file read and write methods for these types of drivers.  These are
named fb_sys_read() and fb_sys_write().
Signed-off-by: default avatarAntonino Daplas <adaplas@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3f9b0880
...@@ -122,6 +122,11 @@ config FB_SYS_IMAGEBLIT ...@@ -122,6 +122,11 @@ config FB_SYS_IMAGEBLIT
blitting. This is used by drivers that don't provide their own blitting. This is used by drivers that don't provide their own
(accelerated) version and the framebuffer is in system RAM. (accelerated) version and the framebuffer is in system RAM.
config FB_SYS_FOPS
tristate
depends on FB
default n
config FB_DEFERRED_IO config FB_DEFERRED_IO
bool bool
depends on FB depends on FB
......
...@@ -21,6 +21,7 @@ obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o ...@@ -21,6 +21,7 @@ obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
obj-$(CONFIG_FB_SVGALIB) += svgalib.o obj-$(CONFIG_FB_SVGALIB) += svgalib.o
obj-$(CONFIG_FB_MACMODES) += macmodes.o obj-$(CONFIG_FB_MACMODES) += macmodes.o
obj-$(CONFIG_FB_DDC) += fb_ddc.o obj-$(CONFIG_FB_DDC) += fb_ddc.o
......
/*
* linux/drivers/video/fb_sys_read.c - Generic file operations where
* framebuffer is in system RAM
*
* Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*
*/
#include <linux/fb.h>
#include <linux/module.h>
#include <asm/uaccess.h>
ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
loff_t *ppos)
{
unsigned long p = *ppos;
void *src;
int err = 0;
unsigned long total_size;
if (info->state != FBINFO_STATE_RUNNING)
return -EPERM;
total_size = info->screen_size;
if (total_size == 0)
total_size = info->fix.smem_len;
if (p >= total_size)
return 0;
if (count >= total_size)
count = total_size;
if (count + p > total_size)
count = total_size - p;
src = (void __force *)(info->screen_base + p);
if (info->fbops->fb_sync)
info->fbops->fb_sync(info);
if (copy_to_user(buf, src, count))
err = -EFAULT;
if (!err)
*ppos += count;
return (err) ? err : count;
}
EXPORT_SYMBOL_GPL(fb_sys_read);
ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
void *dst;
int err = 0;
unsigned long total_size;
if (info->state != FBINFO_STATE_RUNNING)
return -EPERM;
total_size = info->screen_size;
if (total_size == 0)
total_size = info->fix.smem_len;
if (p > total_size)
return -EFBIG;
if (count > total_size) {
err = -EFBIG;
count = total_size;
}
if (count + p > total_size) {
if (!err)
err = -ENOSPC;
count = total_size - p;
}
dst = (void __force *) (info->screen_base + p);
if (info->fbops->fb_sync)
info->fbops->fb_sync(info);
if (copy_from_user(dst, buf, count))
err = -EFAULT;
if (!err)
*ppos += count;
return (err) ? err : count;
}
EXPORT_SYMBOL_GPL(fb_sys_write);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
MODULE_LICENSE("GPL");
...@@ -903,6 +903,10 @@ extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image); ...@@ -903,6 +903,10 @@ extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect); extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area); extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area);
extern void sys_imageblit(struct fb_info *info, const struct fb_image *image); extern void sys_imageblit(struct fb_info *info, const struct fb_image *image);
extern ssize_t fb_sys_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
/* drivers/video/fbmem.c */ /* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info); extern int register_framebuffer(struct fb_info *fb_info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment