summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/Kconfig35
-rw-r--r--drivers/video/fbdev/Makefile17
-rw-r--r--drivers/video/fbdev/au1200fb.c9
-rw-r--r--drivers/video/fbdev/bw2.c17
-rw-r--r--drivers/video/fbdev/cg14.c19
-rw-r--r--drivers/video/fbdev/cg3.c17
-rw-r--r--drivers/video/fbdev/cg6.c17
-rw-r--r--drivers/video/fbdev/core/Kconfig6
-rw-r--r--drivers/video/fbdev/core/Makefile2
-rw-r--r--drivers/video/fbdev/core/fb_chrdev.c3
-rw-r--r--drivers/video/fbdev/core/fb_internal.h17
-rw-r--r--drivers/video/fbdev/core/fb_logo.c508
-rw-r--r--drivers/video/fbdev/core/fbcon.c2
-rw-r--r--drivers/video/fbdev/core/fbmem.c542
-rw-r--r--drivers/video/fbdev/ffb.c17
-rw-r--r--drivers/video/fbdev/hyperv_fb.c48
-rw-r--r--drivers/video/fbdev/leo.c19
-rw-r--r--drivers/video/fbdev/mmp/fb/mmpfb.c7
-rw-r--r--drivers/video/fbdev/p9100.c18
-rw-r--r--drivers/video/fbdev/sbuslib.h37
-rw-r--r--drivers/video/fbdev/smscufx.c85
-rw-r--r--drivers/video/fbdev/tcx.c20
-rw-r--r--drivers/video/fbdev/udlfb.c89
23 files changed, 703 insertions, 848 deletions
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index c29754b65c0e..e142b15862cb 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -518,21 +518,23 @@ config FB_SBUS
help
Say Y if you want support for SBUS or UPA based frame buffer device.
+config FB_SBUS_HELPERS
+ bool
+ select FB_CFB_COPYAREA
+ select FB_CFB_FILLRECT
+ select FB_CFB_IMAGEBLIT
+
config FB_BW2
bool "BWtwo support"
depends on (FB = y) && (SPARC && FB_SBUS)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SBUS_HELPERS
help
This is the frame buffer device driver for the BWtwo frame buffer.
config FB_CG3
bool "CGthree support"
depends on (FB = y) && (SPARC && FB_SBUS)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SBUS_HELPERS
help
This is the frame buffer device driver for the CGthree frame buffer.
@@ -557,9 +559,7 @@ config FB_FFB
config FB_TCX
bool "TCX (SS4/SS5 only) support"
depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SBUS_HELPERS
help
This is the frame buffer device driver for the TCX 24/8bit frame
buffer.
@@ -567,9 +567,7 @@ config FB_TCX
config FB_CG14
bool "CGfourteen (SX) support"
depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SBUS_HELPERS
help
This is the frame buffer device driver for the CGfourteen frame
buffer on Desktop SPARCsystems with the SX graphics option.
@@ -577,9 +575,7 @@ config FB_CG14
config FB_P9100
bool "P9100 (Sparcbook 3 only) support"
depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SBUS_HELPERS
help
This is the frame buffer device driver for the P9100 card
supported on Sparcbook 3 machines.
@@ -587,9 +583,7 @@ config FB_P9100
config FB_LEO
bool "Leo (ZX) support"
depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SBUS_HELPERS
help
This is the frame buffer device driver for the SBUS-based Sun ZX
(leo) frame buffer cards.
@@ -1900,11 +1894,8 @@ config FB_BROADSHEET
config FB_HYPERV
tristate "Microsoft Hyper-V Synthetic Video support"
depends on FB && HYPERV
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_DEFERRED_IO
select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA
+ select FB_IOMEM_HELPERS_DEFERRED
select VIDEO_NOMODESET
help
This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 70569f7027ed..8e15220152bd 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -8,6 +8,7 @@
obj-y += core/
obj-$(CONFIG_FB_MACMODES) += macmodes.o
+obj-$(CONFIG_FB_SBUS) += sbuslib.o
obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
# Hardware specific drivers go first
@@ -45,14 +46,14 @@ obj-$(CONFIG_FB_LE80578) += vermilion/
obj-$(CONFIG_FB_S3) += s3fb.o
obj-$(CONFIG_FB_ARK) += arkfb.o
obj-$(CONFIG_FB_STI) += stifb.o
-obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
-obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
-obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o
-obj-$(CONFIG_FB_BW2) += bw2.o sbuslib.o
-obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o
-obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o
-obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o
-obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
+obj-$(CONFIG_FB_FFB) += ffb.o
+obj-$(CONFIG_FB_CG6) += cg6.o
+obj-$(CONFIG_FB_CG3) += cg3.o
+obj-$(CONFIG_FB_BW2) += bw2.o
+obj-$(CONFIG_FB_CG14) += cg14.o
+obj-$(CONFIG_FB_P9100) += p9100.o
+obj-$(CONFIG_FB_TCX) += tcx.o
+obj-$(CONFIG_FB_LEO) += leo.o
obj-$(CONFIG_FB_ACORN) += acornfb.o
obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c
index c137d6afe484..98afd385c49c 100644
--- a/drivers/video/fbdev/au1200fb.c
+++ b/drivers/video/fbdev/au1200fb.c
@@ -1719,15 +1719,6 @@ static int au1200fb_drv_probe(struct platform_device *dev)
}
au1200fb_fb_set_par(fbi);
-
-#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
- if (plane == 0)
- if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
- /* Start display and show logo on boot */
- fb_set_cmap(&fbi->cmap, fbi);
- fb_show_logo(fbi, FB_ROTATE_UR);
- }
-#endif
}
/* Now hook interrupt too */
diff --git a/drivers/video/fbdev/bw2.c b/drivers/video/fbdev/bw2.c
index de34f1f333e2..eaab51be74f8 100644
--- a/drivers/video/fbdev/bw2.c
+++ b/drivers/video/fbdev/bw2.c
@@ -31,8 +31,8 @@
static int bw2_blank(int, struct fb_info *);
-static int bw2_mmap(struct fb_info *, struct vm_area_struct *);
-static int bw2_ioctl(struct fb_info *, unsigned int, unsigned long);
+static int bw2_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int bw2_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
/*
* Frame buffer operations
@@ -40,15 +40,8 @@ static int bw2_ioctl(struct fb_info *, unsigned int, unsigned long);
static const struct fb_ops bw2_ops = {
.owner = THIS_MODULE,
+ FB_DEFAULT_SBUS_OPS(bw2),
.fb_blank = bw2_blank,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_mmap = bw2_mmap,
- .fb_ioctl = bw2_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sbusfb_compat_ioctl,
-#endif
};
/* OBio addresses for the bwtwo registers */
@@ -161,7 +154,7 @@ static struct sbus_mmap_map bw2_mmap_map[] = {
{ .size = 0 }
};
-static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int bw2_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct bw2_par *par = (struct bw2_par *)info->par;
@@ -171,7 +164,7 @@ static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
vma);
}
-static int bw2_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int bw2_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
return sbusfb_ioctl_helper(cmd, arg, info,
FBTYPE_SUN2BW, 1, info->fix.smem_len);
diff --git a/drivers/video/fbdev/cg14.c b/drivers/video/fbdev/cg14.c
index c0336c051c24..c161b2af8933 100644
--- a/drivers/video/fbdev/cg14.c
+++ b/drivers/video/fbdev/cg14.c
@@ -31,27 +31,20 @@
static int cg14_setcolreg(unsigned, unsigned, unsigned, unsigned,
unsigned, struct fb_info *);
-
-static int cg14_mmap(struct fb_info *, struct vm_area_struct *);
-static int cg14_ioctl(struct fb_info *, unsigned int, unsigned long);
static int cg14_pan_display(struct fb_var_screeninfo *, struct fb_info *);
+static int cg14_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int cg14_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
+
/*
* Frame buffer operations
*/
static const struct fb_ops cg14_ops = {
.owner = THIS_MODULE,
+ FB_DEFAULT_SBUS_OPS(cg14),
.fb_setcolreg = cg14_setcolreg,
.fb_pan_display = cg14_pan_display,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_mmap = cg14_mmap,
- .fb_ioctl = cg14_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sbusfb_compat_ioctl,
-#endif
};
#define CG14_MCR_INTENABLE_SHIFT 7
@@ -265,7 +258,7 @@ static int cg14_setcolreg(unsigned regno,
return 0;
}
-static int cg14_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int cg14_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct cg14_par *par = (struct cg14_par *) info->par;
@@ -274,7 +267,7 @@ static int cg14_mmap(struct fb_info *info, struct vm_area_struct *vma)
par->iospace, vma);
}
-static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int cg14_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct cg14_par *par = (struct cg14_par *) info->par;
struct cg14_regs __iomem *regs = par->regs;
diff --git a/drivers/video/fbdev/cg3.c b/drivers/video/fbdev/cg3.c
index 0a897d5be334..5e1f1b9a81b6 100644
--- a/drivers/video/fbdev/cg3.c
+++ b/drivers/video/fbdev/cg3.c
@@ -33,8 +33,8 @@ static int cg3_setcolreg(unsigned, unsigned, unsigned, unsigned,
unsigned, struct fb_info *);
static int cg3_blank(int, struct fb_info *);
-static int cg3_mmap(struct fb_info *, struct vm_area_struct *);
-static int cg3_ioctl(struct fb_info *, unsigned int, unsigned long);
+static int cg3_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int cg3_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
/*
* Frame buffer operations
@@ -42,16 +42,9 @@ static int cg3_ioctl(struct fb_info *, unsigned int, unsigned long);
static const struct fb_ops cg3_ops = {
.owner = THIS_MODULE,
+ FB_DEFAULT_SBUS_OPS(cg3),
.fb_setcolreg = cg3_setcolreg,
.fb_blank = cg3_blank,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_mmap = cg3_mmap,
- .fb_ioctl = cg3_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sbusfb_compat_ioctl,
-#endif
};
@@ -225,7 +218,7 @@ static struct sbus_mmap_map cg3_mmap_map[] = {
{ .size = 0 }
};
-static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int cg3_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct cg3_par *par = (struct cg3_par *)info->par;
@@ -235,7 +228,7 @@ static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
vma);
}
-static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int cg3_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
return sbusfb_ioctl_helper(cmd, arg, info,
FBTYPE_SUN3COLOR, 8, info->fix.smem_len);
diff --git a/drivers/video/fbdev/cg6.c b/drivers/video/fbdev/cg6.c
index 8ef6ac9132f3..69d3ce50948d 100644
--- a/drivers/video/fbdev/cg6.c
+++ b/drivers/video/fbdev/cg6.c
@@ -37,16 +37,18 @@ static void cg6_imageblit(struct fb_info *, const struct fb_image *);
static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *);
static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area);
static int cg6_sync(struct fb_info *);
-static int cg6_mmap(struct fb_info *, struct vm_area_struct *);
-static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long);
static int cg6_pan_display(struct fb_var_screeninfo *, struct fb_info *);
+static int cg6_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int cg6_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
+
/*
* Frame buffer operations
*/
static const struct fb_ops cg6_ops = {
.owner = THIS_MODULE,
+ __FB_DEFAULT_SBUS_OPS_RDWR(cg6),
.fb_setcolreg = cg6_setcolreg,
.fb_blank = cg6_blank,
.fb_pan_display = cg6_pan_display,
@@ -54,11 +56,8 @@ static const struct fb_ops cg6_ops = {
.fb_copyarea = cg6_copyarea,
.fb_imageblit = cg6_imageblit,
.fb_sync = cg6_sync,
- .fb_mmap = cg6_mmap,
- .fb_ioctl = cg6_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sbusfb_compat_ioctl,
-#endif
+ __FB_DEFAULT_SBUS_OPS_IOCTL(cg6),
+ __FB_DEFAULT_SBUS_OPS_MMAP(cg6),
};
/* Offset of interesting structures in the OBIO space */
@@ -590,7 +589,7 @@ static struct sbus_mmap_map cg6_mmap_map[] = {
{ .size = 0 }
};
-static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int cg6_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct cg6_par *par = (struct cg6_par *)info->par;
@@ -599,7 +598,7 @@ static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma)
par->which_io, vma);
}
-static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int cg6_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
return sbusfb_ioctl_helper(cmd, arg, info,
FBTYPE_SUNFAST_COLOR, 8, info->fix.smem_len);
diff --git a/drivers/video/fbdev/core/Kconfig b/drivers/video/fbdev/core/Kconfig
index 5ac1b0637531..756c8603cf39 100644
--- a/drivers/video/fbdev/core/Kconfig
+++ b/drivers/video/fbdev/core/Kconfig
@@ -151,6 +151,12 @@ config FB_IOMEM_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_IMAGEBLIT
+config FB_IOMEM_HELPERS_DEFERRED
+ bool
+ depends on FB_CORE
+ select FB_DEFERRED_IO
+ select FB_IOMEM_HELPERS
+
config FB_SYSMEM_HELPERS
bool
depends on FB_CORE
diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
index edfde2948e5c..36d3156dc759 100644
--- a/drivers/video/fbdev/core/Makefile
+++ b/drivers/video/fbdev/core/Makefile
@@ -23,6 +23,8 @@ fb-y += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
endif
endif
+fb-$(CONFIG_LOGO) += fb_logo.o
+
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
diff --git a/drivers/video/fbdev/core/fb_chrdev.c b/drivers/video/fbdev/core/fb_chrdev.c
index eadb81f53a82..32a7315b4b6d 100644
--- a/drivers/video/fbdev/core/fb_chrdev.c
+++ b/drivers/video/fbdev/core/fb_chrdev.c
@@ -365,7 +365,8 @@ static int fb_mmap(struct file *file, struct vm_area_struct *vma)
mutex_unlock(&info->mm_lock);
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
- fb_pgprotect(file, vma, start);
+ vma->vm_page_prot = pgprot_framebuffer(vma->vm_page_prot, vma->vm_start,
+ vma->vm_end, start);
return vm_iomap_memory(vma, start, len);
}
diff --git a/drivers/video/fbdev/core/fb_internal.h b/drivers/video/fbdev/core/fb_internal.h
index 4c8d509a0026..613832d335fe 100644
--- a/drivers/video/fbdev/core/fb_internal.h
+++ b/drivers/video/fbdev/core/fb_internal.h
@@ -20,6 +20,23 @@ static inline void fb_unregister_chrdev(void)
{ }
#endif
+/* fb_logo.c */
+#if defined(CONFIG_LOGO)
+extern bool fb_center_logo;
+extern int fb_logo_count;
+int fb_prepare_logo(struct fb_info *fb_info, int rotate);
+int fb_show_logo(struct fb_info *fb_info, int rotate);
+#else
+static inline int fb_prepare_logo(struct fb_info *info, int rotate)
+{
+ return 0;
+}
+static inline int fb_show_logo(struct fb_info *info, int rotate)
+{
+ return 0;
+}
+#endif /* CONFIG_LOGO */
+
/* fbmem.c */
extern struct class *fb_class;
extern struct mutex registration_lock;
diff --git a/drivers/video/fbdev/core/fb_logo.c b/drivers/video/fbdev/core/fb_logo.c
new file mode 100644
index 000000000000..0bab8352b684
--- /dev/null
+++ b/drivers/video/fbdev/core/fb_logo.c
@@ -0,0 +1,508 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/fb.h>
+#include <linux/linux_logo.h>
+
+#include "fb_internal.h"
+
+bool fb_center_logo __read_mostly;
+int fb_logo_count __read_mostly = -1;
+
+static inline unsigned int safe_shift(unsigned int d, int n)
+{
+ return n < 0 ? d >> -n : d << n;
+}
+
+static void fb_set_logocmap(struct fb_info *info,
+ const struct linux_logo *logo)
+{
+ struct fb_cmap palette_cmap;
+ u16 palette_green[16];
+ u16 palette_blue[16];
+ u16 palette_red[16];
+ int i, j, n;
+ const unsigned char *clut = logo->clut;
+
+ palette_cmap.start = 0;
+ palette_cmap.len = 16;
+ palette_cmap.red = palette_red;
+ palette_cmap.green = palette_green;
+ palette_cmap.blue = palette_blue;
+ palette_cmap.transp = NULL;
+
+ for (i = 0; i < logo->clutsize; i += n) {
+ n = logo->clutsize - i;
+ /* palette_cmap provides space for only 16 colors at once */
+ if (n > 16)
+ n = 16;
+ palette_cmap.start = 32 + i;
+ palette_cmap.len = n;
+ for (j = 0; j < n; ++j) {
+ palette_cmap.red[j] = clut[0] << 8 | clut[0];
+ palette_cmap.green[j] = clut[1] << 8 | clut[1];
+ palette_cmap.blue[j] = clut[2] << 8 | clut[2];
+ clut += 3;
+ }
+ fb_set_cmap(&palette_cmap, info);
+ }
+}
+
+static void fb_set_logo_truepalette(struct fb_info *info,
+ const struct linux_logo *logo,
+ u32 *palette)
+{
+ static const unsigned char mask[] = {
+ 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
+ };
+ unsigned char redmask, greenmask, bluemask;
+ int redshift, greenshift, blueshift;
+ int i;
+ const unsigned char *clut = logo->clut;
+
+ /*
+ * We have to create a temporary palette since console palette is only
+ * 16 colors long.
+ */
+ /* Bug: Doesn't obey msb_right ... (who needs that?) */
+ redmask = mask[info->var.red.length < 8 ? info->var.red.length : 8];
+ greenmask = mask[info->var.green.length < 8 ? info->var.green.length : 8];
+ bluemask = mask[info->var.blue.length < 8 ? info->var.blue.length : 8];
+ redshift = info->var.red.offset - (8 - info->var.red.length);
+ greenshift = info->var.green.offset - (8 - info->var.green.length);
+ blueshift = info->var.blue.offset - (8 - info->var.blue.length);
+
+ for (i = 0; i < logo->clutsize; i++) {
+ palette[i+32] = (safe_shift((clut[0] & redmask), redshift) |
+ safe_shift((clut[1] & greenmask), greenshift) |
+ safe_shift((clut[2] & bluemask), blueshift));
+ clut += 3;
+ }
+}
+
+static void fb_set_logo_directpalette(struct fb_info *info,
+ const struct linux_logo *logo,
+ u32 *palette)
+{
+ int redshift, greenshift, blueshift;
+ int i;
+
+ redshift = info->var.red.offset;
+ greenshift = info->var.green.offset;
+ blueshift = info->var.blue.offset;
+
+ for (i = 32; i < 32 + logo->clutsize; i++)
+ palette[i] = i << redshift | i << greenshift | i << blueshift;
+}
+
+static void fb_set_logo(struct fb_info *info,
+ const struct linux_logo *logo, u8 *dst,
+ int depth)
+{
+ int i, j, k;
+ const u8 *src = logo->data;
+ u8 xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0;
+ u8 fg = 1, d;
+
+ switch (fb_get_color_depth(&info->var, &info->fix)) {
+ case 1:
+ fg = 1;
+ break;
+ case 2:
+ fg = 3;
+ break;
+ default:
+ fg = 7;
+ break;
+ }
+
+ if (info->fix.visual == FB_VISUAL_MONO01 ||
+ info->fix.visual == FB_VISUAL_MONO10)
+ fg = ~((u8) (0xfff << info->var.green.length));
+
+ switch (depth) {
+ case 4:
+ for (i = 0; i < logo->height; i++)
+ for (j = 0; j < logo->width; src++) {
+ *dst++ = *src >> 4;
+ j++;
+ if (j < logo->width) {
+ *dst++ = *src & 0x0f;
+ j++;
+ }
+ }
+ break;
+ case 1:
+ for (i = 0; i < logo->height; i++) {
+ for (j = 0; j < logo->width; src++) {
+ d = *src ^ xor;
+ for (k = 7; k >= 0 && j < logo->width; k--) {
+ *dst++ = ((d >> k) & 1) ? fg : 0;
+ j++;
+ }
+ }
+ }
+ break;
+ }
+}
+
+/*
+ * Three (3) kinds of logo maps exist. linux_logo_clut224 (>16 colors),
+ * linux_logo_vga16 (16 colors) and linux_logo_mono (2 colors). Depending on
+ * the visual format and color depth of the framebuffer, the DAC, the
+ * pseudo_palette, and the logo data will be adjusted accordingly.
+ *
+ * Case 1 - linux_logo_clut224:
+ * Color exceeds the number of console colors (16), thus we set the hardware DAC
+ * using fb_set_cmap() appropriately. The "needs_cmapreset" flag will be set.
+ *
+ * For visuals that require color info from the pseudo_palette, we also construct
+ * one for temporary use. The "needs_directpalette" or "needs_truepalette" flags
+ * will be set.
+ *
+ * Case 2 - linux_logo_vga16:
+ * The number of colors just matches the console colors, thus there is no need
+ * to set the DAC or the pseudo_palette. However, the bitmap is packed, ie,
+ * each byte contains color information for two pixels (upper and lower nibble).
+ * To be consistent with fb_imageblit() usage, we therefore separate the two
+ * nibbles into separate bytes. The "depth" flag will be set to 4.
+ *
+ * Case 3 - linux_logo_mono:
+ * This is similar with Case 2. Each byte contains information for 8 pixels.
+ * We isolate each bit and expand each into a byte. The "depth" flag will
+ * be set to 1.
+ */
+static struct logo_data {
+ int depth;
+ int needs_directpalette;
+ int needs_truepalette;
+ int needs_cmapreset;
+ const struct linux_logo *logo;
+} fb_logo __read_mostly;
+
+static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
+{
+ u32 size = width * height, i;
+
+ out += size - 1;
+
+ for (i = size; i--; )
+ *out-- = *in++;
+}
+
+static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
+{
+ int i, j, h = height - 1;
+
+ for (i = 0; i < height; i++)
+ for (j = 0; j < width; j++)
+ out[height * j + h - i] = *in++;
+}
+
+static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
+{
+ int i, j, w = width - 1;
+
+ for (i = 0; i < height; i++)
+ for (j = 0; j < width; j++)
+ out[height * (w - j) + i] = *in++;
+}
+
+static void fb_rotate_logo(struct fb_info *info, u8 *dst,
+ struct fb_image *image, int rotate)
+{
+ u32 tmp;
+
+ if (rotate == FB_ROTATE_UD) {
+ fb_rotate_logo_ud(image->data, dst, image->width,
+ image->height);
+ image->dx = info->var.xres - image->width - image->dx;
+ image->dy = info->var.yres - image->height - image->dy;
+ } else if (rotate == FB_ROTATE_CW) {
+ fb_rotate_logo_cw(image->data, dst, image->width,
+ image->height);
+ swap(image->width, image->height);
+ tmp = image->dy;
+ image->dy = image->dx;
+ image->dx = info->var.xres - image->width - tmp;
+ } else if (rotate == FB_ROTATE_CCW) {
+ fb_rotate_logo_ccw(image->data, dst, image->width,
+ image->height);
+ swap(image->width, image->height);
+ tmp = image->dx;
+ image->dx = image->dy;
+ image->dy = info->var.yres - image->height - tmp;
+ }
+
+ image->data = dst;
+}
+
+static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
+ int rotate, unsigned int num)
+{
+ unsigned int x;
+
+ if (image->width > info->var.xres || image->height > info->var.yres)
+ return;
+
+ if (rotate == FB_ROTATE_UR) {
+ for (x = 0;
+ x < num && image->dx + image->width <= info->var.xres;
+ x++) {
+ info->fbops->fb_imageblit(info, image);
+ image->dx += image->width + 8;
+ }
+ } else if (rotate == FB_ROTATE_UD) {
+ u32 dx = image->dx;
+
+ for (x = 0; x < num && image->dx <= dx; x++) {
+ info->fbops->fb_imageblit(info, image);
+ image->dx -= image->width + 8;
+ }
+ } else if (rotate == FB_ROTATE_CW) {
+ for (x = 0;
+ x < num && image->dy + image->height <= info->var.yres;
+ x++) {
+ info->fbops->fb_imageblit(info, image);
+ image->dy += image->height + 8;
+ }
+ } else if (rotate == FB_ROTATE_CCW) {
+ u32 dy = image->dy;
+
+ for (x = 0; x < num && image->dy <= dy; x++) {
+ info->fbops->fb_imageblit(info, image);
+ image->dy -= image->height + 8;
+ }
+ }
+}
+
+static int fb_show_logo_line(struct fb_info *info, int rotate,
+ const struct linux_logo *logo, int y,
+ unsigned int n)
+{
+ u32 *palette = NULL, *saved_pseudo_palette = NULL;
+ unsigned char *logo_new = NULL, *logo_rotate = NULL;
+ struct fb_image image;
+
+ /* Return if the frame buffer is not mapped or suspended */
+ if (logo == NULL || info->state != FBINFO_STATE_RUNNING ||
+ info->fbops->owner)
+ return 0;
+
+ image.depth = 8;
+ image.data = logo->data;
+
+ if (fb_logo.needs_cmapreset)
+ fb_set_logocmap(info, logo);
+
+ if (fb_logo.needs_truepalette ||
+ fb_logo.needs_directpalette) {
+ palette = kmalloc(256 * 4, GFP_KERNEL);
+ if (palette == NULL)
+ return 0;
+
+ if (fb_logo.needs_truepalette)
+ fb_set_logo_truepalette(info, logo, palette);
+ else
+ fb_set_logo_directpalette(info, logo, palette);
+
+ saved_pseudo_palette = info->pseudo_palette;
+ info->pseudo_palette = palette;
+ }
+
+ if (fb_logo.depth <= 4) {
+ logo_new = kmalloc_array(logo->width, logo->height,
+ GFP_KERNEL);
+ if (logo_new == NULL) {
+ kfree(palette);
+ if (saved_pseudo_palette)
+ info->pseudo_palette = saved_pseudo_palette;
+ return 0;
+ }
+ image.data = logo_new;
+ fb_set_logo(info, logo, logo_new, fb_logo.depth);
+ }
+
+ if (fb_center_logo) {
+ int xres = info->var.xres;
+ int yres = info->var.yres;
+
+ if (rotate == FB_ROTATE_CW || rotate == FB_ROTATE_CCW) {
+ xres = info->var.yres;
+ yres = info->var.xres;
+ }
+
+ while (n && (n * (logo->width + 8) - 8 > xres))
+ --n;
+ image.dx = (xres - (n * (logo->width + 8) - 8)) / 2;
+ image.dy = y ?: (yres - logo->height) / 2;
+ } else {
+ image.dx = 0;
+ image.dy = y;
+ }
+
+ image.width = logo->width;
+ image.height = logo->height;
+
+ if (rotate) {
+ logo_rotate = kmalloc_array(logo->width, logo->height,
+ GFP_KERNEL);
+ if (logo_rotate)
+ fb_rotate_logo(info, logo_rotate, &image, rotate);
+ }
+
+ fb_do_show_logo(info, &image, rotate, n);
+
+ kfree(palette);
+ if (saved_pseudo_palette != NULL)
+ info->pseudo_palette = saved_pseudo_palette;
+ kfree(logo_new);
+ kfree(logo_rotate);
+ return image.dy + logo->height;
+}
+
+#ifdef CONFIG_FB_LOGO_EXTRA
+
+#define FB_LOGO_EX_NUM_MAX 10
+static struct logo_data_extra {
+ const struct linux_logo *logo;
+ unsigned int n;
+} fb_logo_ex[FB_LOGO_EX_NUM_MAX];
+static unsigned int fb_logo_ex_num;
+
+void fb_append_extra_logo(const struct linux_logo *logo, unsigned int n)
+{
+ if (!n || fb_logo_ex_num == FB_LOGO_EX_NUM_MAX)
+ return;
+
+ fb_logo_ex[fb_logo_ex_num].logo = logo;
+ fb_logo_ex[fb_logo_ex_num].n = n;
+ fb_logo_ex_num++;
+}
+
+static int fb_prepare_extra_logos(struct fb_info *info, unsigned int height,
+ unsigned int yres)
+{
+ unsigned int i;
+
+ /* FIXME: logo_ex supports only truecolor fb. */
+ if (info->fix.visual != FB_VISUAL_TRUECOLOR)
+ fb_logo_ex_num = 0;
+
+ for (i = 0; i < fb_logo_ex_num; i++) {
+ if (fb_logo_ex[i].logo->type != fb_logo.logo->type) {
+ fb_logo_ex[i].logo = NULL;
+ continue;
+ }
+ height += fb_logo_ex[i].logo->height;
+ if (height > yres) {
+ height -= fb_logo_ex[i].logo->height;
+ fb_logo_ex_num = i;
+ break;
+ }
+ }
+ return height;
+}
+
+static int fb_show_extra_logos(struct fb_info *info, int y, int rotate)
+{
+ unsigned int i;
+
+ for (i = 0; i < fb_logo_ex_num; i++)
+ y = fb_show_logo_line(info, rotate,
+ fb_logo_ex[i].logo, y, fb_logo_ex[i].n);
+
+ return y;
+}
+#endif /* CONFIG_FB_LOGO_EXTRA */
+
+int fb_prepare_logo(struct fb_info *info, int rotate)
+{
+ int depth = fb_get_color_depth(&info->var, &info->fix);
+ unsigned int yres;
+ int height;
+
+ memset(&fb_logo, 0, sizeof(struct logo_data));
+
+ if (info->flags & FBINFO_MISC_TILEBLITTING ||
+ info->fbops->owner || !fb_logo_count)
+ return 0;
+
+ if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ depth = info->var.blue.length;
+ if (info->var.red.length < depth)
+ depth = info->var.red.length;
+ if (info->var.green.length < depth)
+ depth = info->var.green.length;
+ }
+
+ if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) {
+ /* assume console colormap */
+ depth = 4;
+ }
+
+ /* Return if no suitable logo was found */
+ fb_logo.logo = fb_find_logo(depth);
+
+ if (!fb_logo.logo)
+ return 0;
+
+ if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
+ yres = info->var.yres;
+ else
+ yres = info->var.xres;
+
+ if (fb_logo.logo->height > yres) {
+ fb_logo.logo = NULL;
+ return 0;
+ }
+
+ /* What depth we asked for might be different from what we get */
+ if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
+ fb_logo.depth = 8;
+ else if (fb_logo.logo->type == LINUX_LOGO_VGA16)
+ fb_logo.depth = 4;
+ else
+ fb_logo.depth = 1;
+
+
+ if (fb_logo.depth > 4 && depth > 4) {
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ fb_logo.needs_truepalette = 1;
+ break;
+ case FB_VISUAL_DIRECTCOLOR:
+ fb_logo.needs_directpalette = 1;
+ fb_logo.needs_cmapreset = 1;
+ break;
+ case FB_VISUAL_PSEUDOCOLOR:
+ fb_logo.needs_cmapreset = 1;
+ break;
+ }
+ }
+
+ height = fb_logo.logo->height;
+ if (fb_center_logo)
+ height += (yres - fb_logo.logo->height) / 2;
+#ifdef CONFIG_FB_LOGO_EXTRA
+ height = fb_prepare_extra_logos(info, height, yres);
+#endif
+
+ return height;
+}
+
+int fb_show_logo(struct fb_info *info, int rotate)
+{
+ unsigned int count;
+ int y;
+
+ if (!fb_logo_count)
+ return 0;
+
+ count = fb_logo_count < 0 ? num_online_cpus() : fb_logo_count;
+ y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, count);
+#ifdef CONFIG_FB_LOGO_EXTRA
+ y = fb_show_extra_logos(info, y, rotate);
+#endif
+
+ return y;
+}
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index f157a5a1dffc..63af6ab034b5 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -472,6 +472,7 @@ static int __init fb_console_setup(char *this_opt)
}
#endif
+#ifdef CONFIG_LOGO
if (!strncmp(options, "logo-pos:", 9)) {
options += 9;
if (!strcmp(options, "center"))
@@ -485,6 +486,7 @@ static int __init fb_console_setup(char *this_opt)
fb_logo_count = simple_strtol(options, &options, 0);
continue;
}
+#endif
}
return 1;
}
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index ee44a46a66be..fc206755f5f6 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -11,30 +11,12 @@
* for more details.
*/
-#include <linux/module.h>
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/vt.h>
-#include <linux/init.h>
-#include <linux/linux_logo.h>
-#include <linux/platform_device.h>
#include <linux/console.h>
-#include <linux/kmod.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/efi.h>
+#include <linux/export.h>
#include <linux/fb.h>
#include <linux/fbcon.h>
-#include <linux/mem_encrypt.h>
-#include <linux/pci.h>
#include <video/nomodeset.h>
-#include <video/vga.h>
#include "fb_internal.h"
@@ -53,10 +35,6 @@ int num_registered_fb __read_mostly;
for (i = 0; i < FB_MAX; i++) \
if (!registered_fb[i]) {} else
-bool fb_center_logo __read_mostly;
-
-int fb_logo_count __read_mostly = -1;
-
struct fb_info *get_fb_info(unsigned int idx)
{
struct fb_info *fb_info;
@@ -184,524 +162,6 @@ char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size
}
EXPORT_SYMBOL(fb_get_buffer_offset);
-#ifdef CONFIG_LOGO
-
-static inline unsigned safe_shift(unsigned d, int n)
-{
- return n < 0 ? d >> -n : d << n;
-}
-
-static void fb_set_logocmap(struct fb_info *info,
- const struct linux_logo *logo)
-{
- struct fb_cmap palette_cmap;
- u16 palette_green[16];
- u16 palette_blue[16];
- u16 palette_red[16];
- int i, j, n;
- const unsigned char *clut = logo->clut;
-
- palette_cmap.start = 0;
- palette_cmap.len = 16;
- palette_cmap.red = palette_red;
- palette_cmap.green = palette_green;
- palette_cmap.blue = palette_blue;
- palette_cmap.transp = NULL;
-
- for (i = 0; i < logo->clutsize; i += n) {
- n = logo->clutsize - i;
- /* palette_cmap provides space for only 16 colors at once */
- if (n > 16)
- n = 16;
- palette_cmap.start = 32 + i;
- palette_cmap.len = n;
- for (j = 0; j < n; ++j) {
- palette_cmap.red[j] = clut[0] << 8 | clut[0];
- palette_cmap.green[j] = clut[1] << 8 | clut[1];
- palette_cmap.blue[j] = clut[2] << 8 | clut[2];
- clut += 3;
- }
- fb_set_cmap(&palette_cmap, info);
- }
-}
-
-static void fb_set_logo_truepalette(struct fb_info *info,
- const struct linux_logo *logo,
- u32 *palette)
-{
- static const unsigned char mask[] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
- unsigned char redmask, greenmask, bluemask;
- int redshift, greenshift, blueshift;
- int i;
- const unsigned char *clut = logo->clut;
-
- /*
- * We have to create a temporary palette since console palette is only
- * 16 colors long.
- */
- /* Bug: Doesn't obey msb_right ... (who needs that?) */
- redmask = mask[info->var.red.length < 8 ? info->var.red.length : 8];
- greenmask = mask[info->var.green.length < 8 ? info->var.green.length : 8];
- bluemask = mask[info->var.blue.length < 8 ? info->var.blue.length : 8];
- redshift = info->var.red.offset - (8 - info->var.red.length);
- greenshift = info->var.green.offset - (8 - info->var.green.length);
- blueshift = info->var.blue.offset - (8 - info->var.blue.length);
-
- for ( i = 0; i < logo->clutsize; i++) {
- palette[i+32] = (safe_shift((clut[0] & redmask), redshift) |
- safe_shift((clut[1] & greenmask), greenshift) |
- safe_shift((clut[2] & bluemask), blueshift));
- clut += 3;
- }
-}
-
-static void fb_set_logo_directpalette(struct fb_info *info,
- const struct linux_logo *logo,
- u32 *palette)
-{
- int redshift, greenshift, blueshift;
- int i;
-
- redshift = info->var.red.offset;
- greenshift = info->var.green.offset;
- blueshift = info->var.blue.offset;
-
- for (i = 32; i < 32 + logo->clutsize; i++)
- palette[i] = i << redshift | i << greenshift | i << blueshift;
-}
-
-static void fb_set_logo(struct fb_info *info,
- const struct linux_logo *logo, u8 *dst,
- int depth)
-{
- int i, j, k;
- const u8 *src = logo->data;
- u8 xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0;
- u8 fg = 1, d;
-
- switch (fb_get_color_depth(&info->var, &info->fix)) {
- case 1:
- fg = 1;
- break;
- case 2:
- fg = 3;
- break;
- default:
- fg = 7;
- break;
- }
-
- if (info->fix.visual == FB_VISUAL_MONO01 ||
- info->fix.visual == FB_VISUAL_MONO10)
- fg = ~((u8) (0xfff << info->var.green.length));
-
- switch (depth) {
- case 4:
- for (i = 0; i < logo->height; i++)
- for (j = 0; j < logo->width; src++) {
- *dst++ = *src >> 4;
- j++;
- if (j < logo->width) {
- *dst++ = *src & 0x0f;
- j++;
- }
- }
- break;
- case 1:
- for (i = 0; i < logo->height; i++) {
- for (j = 0; j < logo->width; src++) {
- d = *src ^ xor;
- for (k = 7; k >= 0 && j < logo->width; k--) {
- *dst++ = ((d >> k) & 1) ? fg : 0;
- j++;
- }
- }
- }
- break;
- }
-}
-
-/*
- * Three (3) kinds of logo maps exist. linux_logo_clut224 (>16 colors),
- * linux_logo_vga16 (16 colors) and linux_logo_mono (2 colors). Depending on
- * the visual format and color depth of the framebuffer, the DAC, the
- * pseudo_palette, and the logo data will be adjusted accordingly.
- *
- * Case 1 - linux_logo_clut224:
- * Color exceeds the number of console colors (16), thus we set the hardware DAC
- * using fb_set_cmap() appropriately. The "needs_cmapreset" flag will be set.
- *
- * For visuals that require color info from the pseudo_palette, we also construct
- * one for temporary use. The "needs_directpalette" or "needs_truepalette" flags
- * will be set.
- *
- * Case 2 - linux_logo_vga16:
- * The number of colors just matches the console colors, thus there is no need
- * to set the DAC or the pseudo_palette. However, the bitmap is packed, ie,
- * each byte contains color information for two pixels (upper and lower nibble).
- * To be consistent with fb_imageblit() usage, we therefore separate the two
- * nibbles into separate bytes. The "depth" flag will be set to 4.
- *
- * Case 3 - linux_logo_mono:
- * This is similar with Case 2. Each byte contains information for 8 pixels.
- * We isolate each bit and expand each into a byte. The "depth" flag will
- * be set to 1.
- */
-static struct logo_data {
- int depth;
- int needs_directpalette;
- int needs_truepalette;
- int needs_cmapreset;
- const struct linux_logo *logo;
-} fb_logo __read_mostly;
-
-static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
-{
- u32 size = width * height, i;
-
- out += size - 1;
-
- for (i = size; i--; )
- *out-- = *in++;
-}
-
-static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
-{
- int i, j, h = height - 1;
-
- for (i = 0; i < height; i++)
- for (j = 0; j < width; j++)
- out[height * j + h - i] = *in++;
-}
-
-static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
-{
- int i, j, w = width - 1;
-
- for (i = 0; i < height; i++)
- for (j = 0; j < width; j++)
- out[height * (w - j) + i] = *in++;
-}
-
-static void fb_rotate_logo(struct fb_info *info, u8 *dst,
- struct fb_image *image, int rotate)
-{
- u32 tmp;
-
- if (rotate == FB_ROTATE_UD) {
- fb_rotate_logo_ud(image->data, dst, image->width,
- image->height);
- image->dx = info->var.xres - image->width - image->dx;
- image->dy = info->var.yres - image->height - image->dy;
- } else if (rotate == FB_ROTATE_CW) {
- fb_rotate_logo_cw(image->data, dst, image->width,
- image->height);
- swap(image->width, image->height);
- tmp = image->dy;
- image->dy = image->dx;
- image->dx = info->var.xres - image->width - tmp;
- } else if (rotate == FB_ROTATE_CCW) {
- fb_rotate_logo_ccw(image->data, dst, image->width,
- image->height);
- swap(image->width, image->height);
- tmp = image->dx;
- image->dx = image->dy;
- image->dy = info->var.yres - image->height - tmp;
- }
-
- image->data = dst;
-}
-
-static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
- int rotate, unsigned int num)
-{
- unsigned int x;
-
- if (image->width > info->var.xres || image->height > info->var.yres)
- return;
-
- if (rotate == FB_ROTATE_UR) {
- for (x = 0;
- x < num && image->dx + image->width <= info->var.xres;
- x++) {
- info->fbops->fb_imageblit(info, image);
- image->dx += image->width + 8;
- }
- } else if (rotate == FB_ROTATE_UD) {
- u32 dx = image->dx;
-
- for (x = 0; x < num && image->dx <= dx; x++) {
- info->fbops->fb_imageblit(info, image);
- image->dx -= image->width + 8;
- }
- } else if (rotate == FB_ROTATE_CW) {
- for (x = 0;
- x < num && image->dy + image->height <= info->var.yres;
- x++) {
- info->fbops->fb_imageblit(info, image);
- image->dy += image->height + 8;
- }
- } else if (rotate == FB_ROTATE_CCW) {
- u32 dy = image->dy;
-
- for (x = 0; x < num && image->dy <= dy; x++) {
- info->fbops->fb_imageblit(info, image);
- image->dy -= image->height + 8;
- }
- }
-}
-
-static int fb_show_logo_line(struct fb_info *info, int rotate,
- const struct linux_logo *logo, int y,
- unsigned int n)
-{
- u32 *palette = NULL, *saved_pseudo_palette = NULL;
- unsigned char *logo_new = NULL, *logo_rotate = NULL;
- struct fb_image image;
-
- /* Return if the frame buffer is not mapped or suspended */
- if (logo == NULL || info->state != FBINFO_STATE_RUNNING ||
- info->fbops->owner)
- return 0;
-
- image.depth = 8;
- image.data = logo->data;
-
- if (fb_logo.needs_cmapreset)
- fb_set_logocmap(info, logo);
-
- if (fb_logo.needs_truepalette ||
- fb_logo.needs_directpalette) {
- palette = kmalloc(256 * 4, GFP_KERNEL);
- if (palette == NULL)
- return 0;
-
- if (fb_logo.needs_truepalette)
- fb_set_logo_truepalette(info, logo, palette);
- else
- fb_set_logo_directpalette(info, logo, palette);
-
- saved_pseudo_palette = info->pseudo_palette;
- info->pseudo_palette = palette;
- }
-
- if (fb_logo.depth <= 4) {
- logo_new = kmalloc_array(logo->width, logo->height,
- GFP_KERNEL);
- if (logo_new == NULL) {
- kfree(palette);
- if (saved_pseudo_palette)
- info->pseudo_palette = saved_pseudo_palette;
- return 0;
- }
- image.data = logo_new;
- fb_set_logo(info, logo, logo_new, fb_logo.depth);
- }
-
- if (fb_center_logo) {
- int xres = info->var.xres;
- int yres = info->var.yres;
-
- if (rotate == FB_ROTATE_CW || rotate == FB_ROTATE_CCW) {
- xres = info->var.yres;
- yres = info->var.xres;
- }
-
- while (n && (n * (logo->width + 8) - 8 > xres))
- --n;
- image.dx = (xres - (n * (logo->width + 8) - 8)) / 2;
- image.dy = y ?: (yres - logo->height) / 2;
- } else {
- image.dx = 0;
- image.dy = y;
- }
-
- image.width = logo->width;
- image.height = logo->height;
-
- if (rotate) {
- logo_rotate = kmalloc_array(logo->width, logo->height,
- GFP_KERNEL);
- if (logo_rotate)
- fb_rotate_logo(info, logo_rotate, &image, rotate);
- }
-
- fb_do_show_logo(info, &image, rotate, n);
-
- kfree(palette);
- if (saved_pseudo_palette != NULL)
- info->pseudo_palette = saved_pseudo_palette;
- kfree(logo_new);
- kfree(logo_rotate);
- return image.dy + logo->height;
-}
-
-
-#ifdef CONFIG_FB_LOGO_EXTRA
-
-#define FB_LOGO_EX_NUM_MAX 10
-static struct logo_data_extra {
- const struct linux_logo *logo;
- unsigned int n;
-} fb_logo_ex[FB_LOGO_EX_NUM_MAX];
-static unsigned int fb_logo_ex_num;
-
-void fb_append_extra_logo(const struct linux_logo *logo, unsigned int n)
-{
- if (!n || fb_logo_ex_num == FB_LOGO_EX_NUM_MAX)
- return;
-
- fb_logo_ex[fb_logo_ex_num].logo = logo;
- fb_logo_ex[fb_logo_ex_num].n = n;
- fb_logo_ex_num++;
-}
-
-static int fb_prepare_extra_logos(struct fb_info *info, unsigned int height,
- unsigned int yres)
-{
- unsigned int i;
-
- /* FIXME: logo_ex supports only truecolor fb. */
- if (info->fix.visual != FB_VISUAL_TRUECOLOR)
- fb_logo_ex_num = 0;
-
- for (i = 0; i < fb_logo_ex_num; i++) {
- if (fb_logo_ex[i].logo->type != fb_logo.logo->type) {
- fb_logo_ex[i].logo = NULL;
- continue;
- }
- height += fb_logo_ex[i].logo->height;
- if (height > yres) {
- height -= fb_logo_ex[i].logo->height;
- fb_logo_ex_num = i;
- break;
- }
- }
- return height;
-}
-
-static int fb_show_extra_logos(struct fb_info *info, int y, int rotate)
-{
- unsigned int i;
-
- for (i = 0; i < fb_logo_ex_num; i++)
- y = fb_show_logo_line(info, rotate,
- fb_logo_ex[i].logo, y, fb_logo_ex[i].n);
-
- return y;
-}
-
-#else /* !CONFIG_FB_LOGO_EXTRA */
-
-static inline int fb_prepare_extra_logos(struct fb_info *info,
- unsigned int height,
- unsigned int yres)
-{
- return height;
-}
-
-static inline int fb_show_extra_logos(struct fb_info *info, int y, int rotate)
-{
- return y;
-}
-
-#endif /* CONFIG_FB_LOGO_EXTRA */
-
-
-int fb_prepare_logo(struct fb_info *info, int rotate)
-{
- int depth = fb_get_color_depth(&info->var, &info->fix);
- unsigned int yres;
- int height;
-
- memset(&fb_logo, 0, sizeof(struct logo_data));
-
- if (info->flags & FBINFO_MISC_TILEBLITTING ||
- info->fbops->owner || !fb_logo_count)
- return 0;
-
- if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
- depth = info->var.blue.length;
- if (info->var.red.length < depth)
- depth = info->var.red.length;
- if (info->var.green.length < depth)
- depth = info->var.green.length;
- }
-
- if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) {
- /* assume console colormap */
- depth = 4;
- }
-
- /* Return if no suitable logo was found */
- fb_logo.logo = fb_find_logo(depth);
-
- if (!fb_logo.logo) {
- return 0;
- }
-
- if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
- yres = info->var.yres;
- else
- yres = info->var.xres;
-
- if (fb_logo.logo->height > yres) {
- fb_logo.logo = NULL;
- return 0;
- }
-
- /* What depth we asked for might be different from what we get */
- if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
- fb_logo.depth = 8;
- else if (fb_logo.logo->type == LINUX_LOGO_VGA16)
- fb_logo.depth = 4;
- else
- fb_logo.depth = 1;
-
-
- if (fb_logo.depth > 4 && depth > 4) {
- switch (info->fix.visual) {
- case FB_VISUAL_TRUECOLOR:
- fb_logo.needs_truepalette = 1;
- break;
- case FB_VISUAL_DIRECTCOLOR:
- fb_logo.needs_directpalette = 1;
- fb_logo.needs_cmapreset = 1;
- break;
- case FB_VISUAL_PSEUDOCOLOR:
- fb_logo.needs_cmapreset = 1;
- break;
- }
- }
-
- height = fb_logo.logo->height;
- if (fb_center_logo)
- height += (yres - fb_logo.logo->height) / 2;
-
- return fb_prepare_extra_logos(info, height, yres);
-}
-
-int fb_show_logo(struct fb_info *info, int rotate)
-{
- unsigned int count;
- int y;
-
- if (!fb_logo_count)
- return 0;
-
- count = fb_logo_count < 0 ? num_online_cpus() : fb_logo_count;
- y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, count);
- y = fb_show_extra_logos(info, y, rotate);
-
- return y;
-}
-#else
-int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
-int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
-#endif /* CONFIG_LOGO */
-EXPORT_SYMBOL(fb_prepare_logo);
-EXPORT_SYMBOL(fb_show_logo);
-
int
fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
{
diff --git a/drivers/video/fbdev/ffb.c b/drivers/video/fbdev/ffb.c
index e3a9bb7e9dea..2a0f5337e091 100644
--- a/drivers/video/fbdev/ffb.c
+++ b/drivers/video/fbdev/ffb.c
@@ -37,16 +37,18 @@ static void ffb_imageblit(struct fb_info *, const struct fb_image *);
static void ffb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void ffb_copyarea(struct fb_info *, const struct fb_copyarea *);
static int ffb_sync(struct fb_info *);
-static int ffb_mmap(struct fb_info *, struct vm_area_struct *);
-static int ffb_ioctl(struct fb_info *, unsigned int, unsigned long);
static int ffb_pan_display(struct fb_var_screeninfo *, struct fb_info *);
+static int ffb_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int ffb_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
+
/*
* Frame buffer operations
*/
static const struct fb_ops ffb_ops = {
.owner = THIS_MODULE,
+ __FB_DEFAULT_SBUS_OPS_RDWR(ffb),
.fb_setcolreg = ffb_setcolreg,
.fb_blank = ffb_blank,
.fb_pan_display = ffb_pan_display,
@@ -54,11 +56,8 @@ static const struct fb_ops ffb_ops = {
.fb_copyarea = ffb_copyarea,
.fb_imageblit = ffb_imageblit,
.fb_sync = ffb_sync,
- .fb_mmap = ffb_mmap,
- .fb_ioctl = ffb_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sbusfb_compat_ioctl,
-#endif
+ __FB_DEFAULT_SBUS_OPS_IOCTL(ffb),
+ __FB_DEFAULT_SBUS_OPS_MMAP(ffb),
};
/* Register layout and definitions */
@@ -850,7 +849,7 @@ static struct sbus_mmap_map ffb_mmap_map[] = {
{ .size = 0 }
};
-static int ffb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int ffb_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct ffb_par *par = (struct ffb_par *)info->par;
@@ -859,7 +858,7 @@ static int ffb_mmap(struct fb_info *info, struct vm_area_struct *vma)
0, vma);
}
-static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int ffb_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct ffb_par *par = (struct ffb_par *)info->par;
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index b9965cbdd764..2e27c6bd8044 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -848,58 +848,38 @@ static int hvfb_blank(int blank, struct fb_info *info)
return 1; /* get fb_blank to set the colormap to all black */
}
-static void hvfb_cfb_fillrect(struct fb_info *p,
- const struct fb_fillrect *rect)
+static void hvfb_ops_damage_range(struct fb_info *info, off_t off, size_t len)
{
- struct hvfb_par *par = p->par;
-
- cfb_fillrect(p, rect);
- if (par->synchronous_fb)
- synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
- else
- hvfb_ondemand_refresh_throttle(par, rect->dx, rect->dy,
- rect->width, rect->height);
+ /* TODO: implement damage handling */
}
-static void hvfb_cfb_copyarea(struct fb_info *p,
- const struct fb_copyarea *area)
+static void hvfb_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height)
{
- struct hvfb_par *par = p->par;
+ struct hvfb_par *par = info->par;
- cfb_copyarea(p, area);
if (par->synchronous_fb)
- synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
+ synthvid_update(info, 0, 0, INT_MAX, INT_MAX);
else
- hvfb_ondemand_refresh_throttle(par, area->dx, area->dy,
- area->width, area->height);
+ hvfb_ondemand_refresh_throttle(par, x, y, width, height);
}
-static void hvfb_cfb_imageblit(struct fb_info *p,
- const struct fb_image *image)
-{
- struct hvfb_par *par = p->par;
-
- cfb_imageblit(p, image);
- if (par->synchronous_fb)
- synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
- else
- hvfb_ondemand_refresh_throttle(par, image->dx, image->dy,
- image->width, image->height);
-}
+/*
+ * TODO: GEN1 codepaths allocate from system or DMA-able memory. Fix the
+ * driver to use the _SYSMEM_ or _DMAMEM_ helpers in these cases.
+ */
+FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(hvfb_ops,
+ hvfb_ops_damage_range,
+ hvfb_ops_damage_area)
static const struct fb_ops hvfb_ops = {
.owner = THIS_MODULE,
+ FB_DEFAULT_DEFERRED_OPS(hvfb_ops),
.fb_check_var = hvfb_check_var,
.fb_set_par = hvfb_set_par,
.fb_setcolreg = hvfb_setcolreg,
- .fb_fillrect = hvfb_cfb_fillrect,
- .fb_copyarea = hvfb_cfb_copyarea,
- .fb_imageblit = hvfb_cfb_imageblit,
.fb_blank = hvfb_blank,
- .fb_mmap = fb_deferred_io_mmap,
};
-
/* Get options from kernel paramenter "video=" */
static void hvfb_get_option(struct fb_info *info)
{
diff --git a/drivers/video/fbdev/leo.c b/drivers/video/fbdev/leo.c
index 2f725cd7633a..7cf525c76079 100644
--- a/drivers/video/fbdev/leo.c
+++ b/drivers/video/fbdev/leo.c
@@ -31,28 +31,21 @@
static int leo_setcolreg(unsigned, unsigned, unsigned, unsigned,
unsigned, struct fb_info *);
static int leo_blank(int, struct fb_info *);
-
-static int leo_mmap(struct fb_info *, struct vm_area_struct *);
-static int leo_ioctl(struct fb_info *, unsigned int, unsigned long);
static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *);
+static int leo_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int leo_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
+
/*
* Frame buffer operations
*/
static const struct fb_ops leo_ops = {
.owner = THIS_MODULE,
+ FB_DEFAULT_SBUS_OPS(leo),
.fb_setcolreg = leo_setcolreg,
.fb_blank = leo_blank,
.fb_pan_display = leo_pan_display,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_mmap = leo_mmap,
- .fb_ioctl = leo_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sbusfb_compat_ioctl,
-#endif
};
#define LEO_OFF_LC_SS0_KRN 0x00200000UL
@@ -414,7 +407,7 @@ static struct sbus_mmap_map leo_mmap_map[] = {
{ .size = 0 }
};
-static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int leo_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct leo_par *par = (struct leo_par *)info->par;
@@ -423,7 +416,7 @@ static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
par->which_io, vma);
}
-static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int leo_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
return sbusfb_ioctl_helper(cmd, arg, info,
FBTYPE_SUNLEO, 32, info->fix.smem_len);
diff --git a/drivers/video/fbdev/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c
index 42a87474bcea..2d9797c6fb3e 100644
--- a/drivers/video/fbdev/mmp/fb/mmpfb.c
+++ b/drivers/video/fbdev/mmp/fb/mmpfb.c
@@ -628,13 +628,6 @@ static int mmpfb_probe(struct platform_device *pdev)
dev_info(fbi->dev, "loaded to /dev/fb%d <%s>.\n",
info->node, info->fix.id);
-#ifdef CONFIG_LOGO
- if (fbi->fb_start) {
- fb_prepare_logo(info, 0);
- fb_show_logo(info, 0);
- }
-#endif
-
return 0;
failed_clear_info:
diff --git a/drivers/video/fbdev/p9100.c b/drivers/video/fbdev/p9100.c
index ca06886d9578..e1356f8a866e 100644
--- a/drivers/video/fbdev/p9100.c
+++ b/drivers/video/fbdev/p9100.c
@@ -31,8 +31,8 @@ static int p9100_setcolreg(unsigned, unsigned, unsigned, unsigned,
unsigned, struct fb_info *);
static int p9100_blank(int, struct fb_info *);
-static int p9100_mmap(struct fb_info *, struct vm_area_struct *);
-static int p9100_ioctl(struct fb_info *, unsigned int, unsigned long);
+static int p9100_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int p9100_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
/*
* Frame buffer operations
@@ -40,16 +40,9 @@ static int p9100_ioctl(struct fb_info *, unsigned int, unsigned long);
static const struct fb_ops p9100_ops = {
.owner = THIS_MODULE,
+ FB_DEFAULT_SBUS_OPS(p9100),
.fb_setcolreg = p9100_setcolreg,
.fb_blank = p9100_blank,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_mmap = p9100_mmap,
- .fb_ioctl = p9100_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sbusfb_compat_ioctl,
-#endif
};
/* P9100 control registers */
@@ -218,7 +211,7 @@ static struct sbus_mmap_map p9100_mmap_map[] = {
{ 0, 0, 0 }
};
-static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int p9100_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct p9100_par *par = (struct p9100_par *)info->par;
@@ -227,8 +220,7 @@ static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma)
par->which_io, vma);
}
-static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
+static int p9100_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
/* Make it look like a cg3. */
return sbusfb_ioctl_helper(cmd, arg, info,
diff --git a/drivers/video/fbdev/sbuslib.h b/drivers/video/fbdev/sbuslib.h
index a6b9a2467646..6466b4cbcd7b 100644
--- a/drivers/video/fbdev/sbuslib.h
+++ b/drivers/video/fbdev/sbuslib.h
@@ -3,6 +3,11 @@
#ifndef _SBUSLIB_H
#define _SBUSLIB_H
+struct device_node;
+struct fb_info;
+struct fb_var_screeninfo;
+struct vm_area_struct;
+
struct sbus_mmap_map {
unsigned long voff;
unsigned long poff;
@@ -14,7 +19,6 @@ struct sbus_mmap_map {
extern void sbusfb_fill_var(struct fb_var_screeninfo *var,
struct device_node *dp, int bpp);
-struct vm_area_struct;
extern int sbusfb_mmap_helper(struct sbus_mmap_map *map,
unsigned long physbase, unsigned long fbsize,
unsigned long iospace,
@@ -25,4 +29,35 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg);
+/*
+ * Initialize struct fb_ops for SBUS I/O.
+ */
+
+#define __FB_DEFAULT_SBUS_OPS_RDWR(__prefix) \
+ .fb_read = fb_io_read, \
+ .fb_write = fb_io_write
+
+#define __FB_DEFAULT_SBUS_OPS_DRAW(__prefix) \
+ .fb_fillrect = cfb_fillrect, \
+ .fb_copyarea = cfb_copyarea, \
+ .fb_imageblit = cfb_imageblit
+
+#ifdef CONFIG_COMPAT
+#define __FB_DEFAULT_SBUS_OPS_IOCTL(__prefix) \
+ .fb_ioctl = __prefix ## _sbusfb_ioctl, \
+ .fb_compat_ioctl = sbusfb_compat_ioctl
+#else
+#define __FB_DEFAULT_SBUS_OPS_IOCTL(__prefix) \
+ .fb_ioctl = __prefix ## _sbusfb_ioctl
+#endif
+
+#define __FB_DEFAULT_SBUS_OPS_MMAP(__prefix) \
+ .fb_mmap = __prefix ## _sbusfb_mmap
+
+#define FB_DEFAULT_SBUS_OPS(__prefix) \
+ __FB_DEFAULT_SBUS_OPS_RDWR(__prefix), \
+ __FB_DEFAULT_SBUS_OPS_DRAW(__prefix), \
+ __FB_DEFAULT_SBUS_OPS_IOCTL(__prefix), \
+ __FB_DEFAULT_SBUS_OPS_MMAP(__prefix)
+
#endif /* _SBUSLIB_H */
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 387d18706fec..90a77d19b236 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -894,64 +894,6 @@ static int ufx_handle_damage(struct ufx_data *dev, int x, int y,
return 0;
}
-/* Path triggered by usermode clients who write to filesystem
- * e.g. cat filename > /dev/fb1
- * Not used by X Windows or text-mode console. But useful for testing.
- * Slow because of extra copy and we must assume all pixels dirty. */
-static ssize_t ufx_ops_write(struct fb_info *info, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- ssize_t result;
- struct ufx_data *dev = info->par;
- u32 offset = (u32) *ppos;
-
- result = fb_sys_write(info, buf, count, ppos);
-
- if (result > 0) {
- int start = max((int)(offset / info->fix.line_length), 0);
- int lines = min((u32)((result / info->fix.line_length) + 1),
- (u32)info->var.yres);
-
- ufx_handle_damage(dev, 0, start, info->var.xres, lines);
- }
-
- return result;
-}
-
-static void ufx_ops_copyarea(struct fb_info *info,
- const struct fb_copyarea *area)
-{
-
- struct ufx_data *dev = info->par;
-
- sys_copyarea(info, area);
-
- ufx_handle_damage(dev, area->dx, area->dy,
- area->width, area->height);
-}
-
-static void ufx_ops_imageblit(struct fb_info *info,
- const struct fb_image *image)
-{
- struct ufx_data *dev = info->par;
-
- sys_imageblit(info, image);
-
- ufx_handle_damage(dev, image->dx, image->dy,
- image->width, image->height);
-}
-
-static void ufx_ops_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect)
-{
- struct ufx_data *dev = info->par;
-
- sys_fillrect(info, rect);
-
- ufx_handle_damage(dev, rect->dx, rect->dy, rect->width,
- rect->height);
-}
-
/* NOTE: fb_defio.c is holding info->fbdefio.mutex
* Touching ANY framebuffer memory that triggers a page fault
* in fb_defio will cause a deadlock, when it also tries to
@@ -1279,14 +1221,31 @@ static int ufx_ops_blank(int blank_mode, struct fb_info *info)
return 0;
}
+static void ufx_ops_damage_range(struct fb_info *info, off_t off, size_t len)
+{
+ struct ufx_data *dev = info->par;
+ int start = max((int)(off / info->fix.line_length), 0);
+ int lines = min((u32)((len / info->fix.line_length) + 1), (u32)info->var.yres);
+
+ ufx_handle_damage(dev, 0, start, info->var.xres, lines);
+}
+
+static void ufx_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height)
+{
+ struct ufx_data *dev = info->par;
+
+ ufx_handle_damage(dev, x, y, width, height);
+}
+
+FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(ufx_ops,
+ ufx_ops_damage_range,
+ ufx_ops_damage_area)
+
static const struct fb_ops ufx_ops = {
.owner = THIS_MODULE,
- .fb_read = fb_sys_read,
- .fb_write = ufx_ops_write,
+ __FB_DEFAULT_DEFERRED_OPS_RDWR(ufx_ops),
.fb_setcolreg = ufx_ops_setcolreg,
- .fb_fillrect = ufx_ops_fillrect,
- .fb_copyarea = ufx_ops_copyarea,
- .fb_imageblit = ufx_ops_imageblit,
+ __FB_DEFAULT_DEFERRED_OPS_DRAW(ufx_ops),
.fb_mmap = ufx_ops_mmap,
.fb_ioctl = ufx_ops_ioctl,
.fb_open = ufx_ops_open,
diff --git a/drivers/video/fbdev/tcx.c b/drivers/video/fbdev/tcx.c
index 7fb8179a8f41..fe7b7bc77eda 100644
--- a/drivers/video/fbdev/tcx.c
+++ b/drivers/video/fbdev/tcx.c
@@ -32,28 +32,21 @@
static int tcx_setcolreg(unsigned, unsigned, unsigned, unsigned,
unsigned, struct fb_info *);
static int tcx_blank(int, struct fb_info *);
-
-static int tcx_mmap(struct fb_info *, struct vm_area_struct *);
-static int tcx_ioctl(struct fb_info *, unsigned int, unsigned long);
static int tcx_pan_display(struct fb_var_screeninfo *, struct fb_info *);
+static int tcx_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int tcx_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
+
/*
* Frame buffer operations
*/
static const struct fb_ops tcx_ops = {
.owner = THIS_MODULE,
+ FB_DEFAULT_SBUS_OPS(tcx),
.fb_setcolreg = tcx_setcolreg,
.fb_blank = tcx_blank,
.fb_pan_display = tcx_pan_display,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_mmap = tcx_mmap,
- .fb_ioctl = tcx_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sbusfb_compat_ioctl,
-#endif
};
/* THC definitions */
@@ -299,7 +292,7 @@ static struct sbus_mmap_map __tcx_mmap_map[TCX_MMAP_ENTRIES] = {
{ .size = 0 }
};
-static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int tcx_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct tcx_par *par = (struct tcx_par *)info->par;
@@ -308,8 +301,7 @@ static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
par->which_io, vma);
}
-static int tcx_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
+static int tcx_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct tcx_par *par = (struct tcx_par *) info->par;
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index b70762ead13c..2460ff4ac86b 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -716,68 +716,6 @@ static void dlfb_offload_damage(struct dlfb_data *dlfb, int x, int y, int width,
}
/*
- * Path triggered by usermode clients who write to filesystem
- * e.g. cat filename > /dev/fb1
- * Not used by X Windows or text-mode console. But useful for testing.
- * Slow because of extra copy and we must assume all pixels dirty.
- */
-static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- ssize_t result;
- struct dlfb_data *dlfb = info->par;
- u32 offset = (u32) *ppos;
-
- result = fb_sys_write(info, buf, count, ppos);
-
- if (result > 0) {
- int start = max((int)(offset / info->fix.line_length), 0);
- int lines = min((u32)((result / info->fix.line_length) + 1),
- (u32)info->var.yres);
-
- dlfb_handle_damage(dlfb, 0, start, info->var.xres,
- lines);
- }
-
- return result;
-}
-
-/* hardware has native COPY command (see libdlo), but not worth it for fbcon */
-static void dlfb_ops_copyarea(struct fb_info *info,
- const struct fb_copyarea *area)
-{
-
- struct dlfb_data *dlfb = info->par;
-
- sys_copyarea(info, area);
-
- dlfb_offload_damage(dlfb, area->dx, area->dy,
- area->width, area->height);
-}
-
-static void dlfb_ops_imageblit(struct fb_info *info,
- const struct fb_image *image)
-{
- struct dlfb_data *dlfb = info->par;
-
- sys_imageblit(info, image);
-
- dlfb_offload_damage(dlfb, image->dx, image->dy,
- image->width, image->height);
-}
-
-static void dlfb_ops_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect)
-{
- struct dlfb_data *dlfb = info->par;
-
- sys_fillrect(info, rect);
-
- dlfb_offload_damage(dlfb, rect->dx, rect->dy, rect->width,
- rect->height);
-}
-
-/*
* NOTE: fb_defio.c is holding info->fbdefio.mutex
* Touching ANY framebuffer memory that triggers a page fault
* in fb_defio will cause a deadlock, when it also tries to
@@ -1186,14 +1124,31 @@ static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
return 0;
}
+static void dlfb_ops_damage_range(struct fb_info *info, off_t off, size_t len)
+{
+ struct dlfb_data *dlfb = info->par;
+ int start = max((int)(off / info->fix.line_length), 0);
+ int lines = min((u32)((len / info->fix.line_length) + 1), (u32)info->var.yres);
+
+ dlfb_handle_damage(dlfb, 0, start, info->var.xres, lines);
+}
+
+static void dlfb_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height)
+{
+ struct dlfb_data *dlfb = info->par;
+
+ dlfb_offload_damage(dlfb, x, y, width, height);
+}
+
+FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(dlfb_ops,
+ dlfb_ops_damage_range,
+ dlfb_ops_damage_area)
+
static const struct fb_ops dlfb_ops = {
.owner = THIS_MODULE,
- .fb_read = fb_sys_read,
- .fb_write = dlfb_ops_write,
+ __FB_DEFAULT_DEFERRED_OPS_RDWR(dlfb_ops),
.fb_setcolreg = dlfb_ops_setcolreg,
- .fb_fillrect = dlfb_ops_fillrect,
- .fb_copyarea = dlfb_ops_copyarea,
- .fb_imageblit = dlfb_ops_imageblit,
+ __FB_DEFAULT_DEFERRED_OPS_DRAW(dlfb_ops),
.fb_mmap = dlfb_ops_mmap,
.fb_ioctl = dlfb_ops_ioctl,
.fb_open = dlfb_ops_open,