aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/Kconfig5
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/fb_sys_fops.c104
-rw-r--r--include/linux/fb.h4
4 files changed, 114 insertions, 0 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6d32726e8751..85d0e8707ee3 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -122,6 +122,11 @@ config FB_SYS_IMAGEBLIT
122 blitting. This is used by drivers that don't provide their own 122 blitting. This is used by drivers that don't provide their own
123 (accelerated) version and the framebuffer is in system RAM. 123 (accelerated) version and the framebuffer is in system RAM.
124 124
125config FB_SYS_FOPS
126 tristate
127 depends on FB
128 default n
129
125config FB_DEFERRED_IO 130config FB_DEFERRED_IO
126 bool 131 bool
127 depends on FB 132 depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index fa025e786848..6c7b26e81fc2 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
21obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o 21obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
22obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o 22obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
23obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o 23obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
24obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
24obj-$(CONFIG_FB_SVGALIB) += svgalib.o 25obj-$(CONFIG_FB_SVGALIB) += svgalib.o
25obj-$(CONFIG_FB_MACMODES) += macmodes.o 26obj-$(CONFIG_FB_MACMODES) += macmodes.o
26obj-$(CONFIG_FB_DDC) += fb_ddc.o 27obj-$(CONFIG_FB_DDC) += fb_ddc.o
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fb_sys_fops.c
new file mode 100644
index 000000000000..cf2538d669cd
--- /dev/null
+++ b/drivers/video/fb_sys_fops.c
@@ -0,0 +1,104 @@
1/*
2 * linux/drivers/video/fb_sys_read.c - Generic file operations where
3 * framebuffer is in system RAM
4 *
5 * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive
9 * for more details.
10 *
11 */
12#include <linux/fb.h>
13#include <linux/module.h>
14#include <asm/uaccess.h>
15
16ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
17 loff_t *ppos)
18{
19 unsigned long p = *ppos;
20 void *src;
21 int err = 0;
22 unsigned long total_size;
23
24 if (info->state != FBINFO_STATE_RUNNING)
25 return -EPERM;
26
27 total_size = info->screen_size;
28
29 if (total_size == 0)
30 total_size = info->fix.smem_len;
31
32 if (p >= total_size)
33 return 0;
34
35 if (count >= total_size)
36 count = total_size;
37
38 if (count + p > total_size)
39 count = total_size - p;
40
41 src = (void __force *)(info->screen_base + p);
42
43 if (info->fbops->fb_sync)
44 info->fbops->fb_sync(info);
45
46 if (copy_to_user(buf, src, count))
47 err = -EFAULT;
48
49 if (!err)
50 *ppos += count;
51
52 return (err) ? err : count;
53}
54EXPORT_SYMBOL_GPL(fb_sys_read);
55
56ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
57 size_t count, loff_t *ppos)
58{
59 unsigned long p = *ppos;
60 void *dst;
61 int err = 0;
62 unsigned long total_size;
63
64 if (info->state != FBINFO_STATE_RUNNING)
65 return -EPERM;
66
67 total_size = info->screen_size;
68
69 if (total_size == 0)
70 total_size = info->fix.smem_len;
71
72 if (p > total_size)
73 return -EFBIG;
74
75 if (count > total_size) {
76 err = -EFBIG;
77 count = total_size;
78 }
79
80 if (count + p > total_size) {
81 if (!err)
82 err = -ENOSPC;
83
84 count = total_size - p;
85 }
86
87 dst = (void __force *) (info->screen_base + p);
88
89 if (info->fbops->fb_sync)
90 info->fbops->fb_sync(info);
91
92 if (copy_from_user(dst, buf, count))
93 err = -EFAULT;
94
95 if (!err)
96 *ppos += count;
97
98 return (err) ? err : count;
99}
100EXPORT_SYMBOL_GPL(fb_sys_write);
101
102MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
103MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
104MODULE_LICENSE("GPL");
diff --git a/include/linux/fb.h b/include/linux/fb.h
index acb6ddb68fa2..70d154a02c5c 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -903,6 +903,10 @@ extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
903extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect); 903extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
904extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area); 904extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area);
905extern void sys_imageblit(struct fb_info *info, const struct fb_image *image); 905extern void sys_imageblit(struct fb_info *info, const struct fb_image *image);
906extern ssize_t fb_sys_read(struct fb_info *info, char __user *buf,
907 size_t count, loff_t *ppos);
908extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
909 size_t count, loff_t *ppos);
906 910
907/* drivers/video/fbmem.c */ 911/* drivers/video/fbmem.c */
908extern int register_framebuffer(struct fb_info *fb_info); 912extern int register_framebuffer(struct fb_info *fb_info);