aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2007-05-08 03:39:03 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:15:30 -0400
commit09aaf268eb1d22eee690d26a913f660e2081597f (patch)
tree9179447608d1c7ee23af266d2bae2eef6d05a1c9
parent3f9b0880e4a96b02bc0131451f2f6231cd90bd94 (diff)
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: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-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);